I am developing a Homey app (status : Test)
that receives real-time sensor data (temperature, humidity, occupancy)
from an our backend
We have switched from polling to using Homey Cloud Webhooks,
where our AWS Lambda POSTs data to:
https://webhooks.athom.com/webhook/{WEBHOOK_ID}?homey={HOMEY_ID}
The Homey app then receives the data and updates device capabilities accordingly.
I have a few questions to confirm we are on the right track:
Does Test status affect the functionality of Cloud Webhooks?
Should the webhook listener be registered at App level (app.js)
or Device level (device.js)?
Are there any rate limits or payload size limits we should
be aware of?
Thank you for your time and assistance.
No, cloud webhooks are available for all apps (even apps that aren’t published to the app store).
I would recommend to place it in app.js, as it only has to receive/register once in case of multiple devices.
As far as I know there are no rate limits, but you can contact Athom to be sure.
Thanks for support, following code, i was using, it was work on local development environment but not work for TEST status, would you pls let me know why ?
app.js
async onInit() {
//this.log('MyApp has been initialized');
const homeyId = await this.homey.cloud.getHomeyId();
this.log('Homey ID:', homeyId);
const myWebhook = await this.homey.cloud.createWebhook(
Homey.env.WEBHOOK_ID,
Homey.env.WEBHOOK_SECRET,
{}
);
myWebhook.on('message', async ({ body }) => {
this.log('Webhook received:', body);
const drivers = this.homey.drivers.getDrivers();
for (const driver of Object.values(drivers)) {
for (const device of driver.getDevices()) {
await device.onWebhookData(body).catch(this.error);
}
}
});
this.log(`Webhook URL: https://webhooks.athom.com/webhook/${Homey.env.WEBHOOK_ID}?homey=${homeyId}`);
}
});
this.log(`Webhook URL: https://webhooks.athom.com/webhook/${Homey.env.WEBHOOK_ID}?homey=${homeyId}`);
}
};
device.js
async onWebhookData(data) {
const { air_temperature, humidity, person_cnt, is_lower_alert, is_higher_alert } = data;
await this.setCapabilityValue('measure_temperature', air_temperature).catch(this.error);
await this.setCapabilityValue('measure_humidity', humidity).catch(this.error);
await this.setCapabilityValue('people_count_capability', person_cnt).catch(this.error);
// Flow triggers
if (is_lower_alert) {
await this.homey.flow.getTriggerCard('room-may-feel-too-cool')
.trigger().catch(this.error);
} else if (is_higher_alert) {
await this.homey.flow.getTriggerCard('room-may-feel-too-warm')
.trigger().catch(this.error);
}
}
You have this part in the code 2 times, you need to remove this part at the end of the code.
Tendertec_Developmen:
await
Also, you don’t need to use await on getTriggerCard
Yeah, It is copy and paste error only
'use strict';
const Homey = require('homey');
module.exports = class MyApp extends Homey.App {
/**
* onInit is called when the app is initialized.
*/
async onInit() {
//this.log('MyApp has been initialized');
const homeyId = await this.homey.cloud.getHomeyId();
this.log('Homey ID:', homeyId);
const myWebhook = await this.homey.cloud.createWebhook(
Homey.env.WEBHOOK_ID,
Homey.env.WEBHOOK_SECRET,
{}
);
myWebhook.on('message', async ({ body }) => {
this.log('Webhook received:', body);
const drivers = this.homey.drivers.getDrivers();
for (const driver of Object.values(drivers)) {
for (const device of driver.getDevices()) {
await device.onWebhookData(body).catch(this.error);
}
}
});
this.log(`Webhook URL: https://webhooks.athom.com/webhook/${Homey.env.WEBHOOK_ID}?homey=${homeyId}`);
}
};
Does it work when you remove await from getTriggerCard?
Also, are there any error messages in the logs?
Thanks for support,.
I cannot see any log on TEST environment, or how can see the cloud log ?
When I using homey app run, and see the local log, it everything is work fine
You can check that by creating a diagnostics report. In the Homey mobile app, go to More->Apps->[your app]->Settings (top right corner)->Create diagnostics report. You then receive an email with the log.
OK. thanks for your information and let me take a look,
I also remove the code of getTriggerCard, also not work without any log
That’s strange, it appears that your app isn’t running at all. Did you receive any notifications in the Timeline about app crashes?
There are no issues with the code itself since it works in development mode.
Thanks for support
finally I checked , i was received data from endpoint
I have another question is I was post like this
await fetch('https://webhooks.athom.com/webhook/69f467cd39b65f563ab3071f?homey={HOMEY_ID}', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(
{
"air_temperature": 18.5,
"humidity": 60,
"person_cnt": 2,
"is_lower_alert": false,
"is_higher_alert": false
}
),
});
And I was received
{
“humidity”: { “N”: “60” },
“air_temperature”: { “N”: “18.5” },
“is_higher_alert”: { “BOOL”: true },
“person_cnt”: { “N”: “2” },
“is_lower_alert”: { “BOOL”: false }
}
it is any hint i can receive just normal ?
{
"air_temperature": 18.5,
"humidity": 60,
"person_cnt": 2,
"is_lower_alert": false,
"is_higher_alert": false
}
I only use webhooks with query parameters (no body) so I don’t know if that is possible.
Also,
Tendertec_Developmen:
?homey=
You should remove the Homey CloudID from your reply, since anyone can use it to access your Homey remotely (and push webhooks to it).
Tendertec_Developmen:
And I was received
Doesn’t make sense, the Athom backend should pass the JSON as-is (and it does so for my test app).
Request body (using POST):
{
"bool": false,
"num": 123,
"str": "this is a string"
}
And in on("message"):
body: { str: 'this is a string', num: 123, bool: false }
yes. I also find it is not a main issues.
this is my code how to pass value from app.js to device.js
const drivers = this.homey.drivers.getDrivers();
await this.remoteLog('info', 'drivers count', { count: Object.keys(drivers).length });
for (const driver of Object.values(drivers)) {
const devices = driver.getDevices();
await this.remoteLog('info', 'driver devices count', {
driverId: driver.id,
deviceCount: devices.length
});
... and pass data to device
}
From the log,
I can see on my Local environment
drivers count = 1
driver devices count = 1
BUT when I doing same thing at TEST environment
drivers count = 1
driver devices count = 0
that why cannot showing my data on UI
I’m not sure if devices created by a local version of your app are assigned to a test version of your app (installed from the app store).
yes, I also tried as following step:
Remove device and uninstall the local app
2. Install App from test version, and add the device
It also not work in this case.