I have had some challenges with devices being “dead” as in not reporting updates or actually being dead. Primairly the problem has been related to zigbee devices which is reporting temperature which again is used as input to advanced flows to control temperature. It ends up being quite elaborate and I am wondering if there is some better way to do this. Process consist of a homey flow which triggers scripts where the output from the script is then used to determine if action should be taken to check the device ( meaning restart etc manually).
// Get all Zigbee devices and convert to array
const zigbeeDevicesArray = Object.values(await Homey.devices.getDevices());
// Filter Zigbee devices based on the 'measure_temperature' capability and a specific driver ID
const zigbeeFilteredDevices = zigbeeDevicesArray.filter(device =>
device.capabilitiesObj &&
device.capabilitiesObj.measure_temperature &&
device.driverId === 'homey:app:com.xiaomi-mi:weather' // Filtering to include only Xiaomi Mi weather devices
);
// Map Zigbee devices to include name and last update information from all relevant capabilities
const zigbeeDeviceInfoArray = zigbeeFilteredDevices.map(device => {
const temperatureCapability = device.capabilitiesObj.measure_temperature;
const humidityCapability = device.capabilitiesObj.measure_humidity;
const pressureCapability = device.capabilitiesObj.measure_pressure;
const tempUpdated = new Date(temperatureCapability.lastUpdated);
const humidityUpdated = humidityCapability ? new Date(humidityCapability.lastUpdated) : tempUpdated;
const pressureUpdated = pressureCapability ? new Date(pressureCapability.lastUpdated) : tempUpdated;
const mostRecentUpdate = new Date(Math.max(tempUpdated, humidityUpdated, pressureUpdated));
const formattedMostRecentDate = new Intl.DateTimeFormat('en-GB', {
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
timeZone: 'Europe/Oslo',
timeZoneName: 'short'
}).format(mostRecentUpdate);
return {
name: device.name,
lastUpdated: formattedMostRecentDate,
lastUpdatedRaw: mostRecentUpdate
};
});
// Find the Zigbee device with the oldest temperature update
const oldestZigbeeDevice = zigbeeDeviceInfoArray.reduce((oldest, device) => {
return (!oldest || device.lastUpdatedRaw < oldest.lastUpdatedRaw) ? device : oldest;
}, null);
// Actions based on the found oldest device
if (oldestZigbeeDevice) {
// Calculate the number of hours since the last update of the oldest device
const currentTime = new Date();
const zigbeeDevice_hoursSinceUpdate = Math.round(
(currentTime - oldestZigbeeDevice.lastUpdatedRaw) / (1000 * 60 * 60)
);
// Set tags for Homey flow, ensuring they are descriptive and protocol-specific
await tag('zigbee_oldestDeviceName', oldestZigbeeDevice.name);
await tag('zigbee_oldestReadingDate', oldestZigbeeDevice.lastUpdated);
await tag('zigbee_hoursSinceLastUpdate', zigbeeDevice_hoursSinceUpdate);
// Return values for testing and further use in flows or debugging
return {
zigbee_oldestDeviceName: oldestZigbeeDevice.name,
zigbee_oldestReadingDate: oldestZigbeeDevice.lastUpdated,
zigbee_hoursSinceLastUpdate: zigbeeDevice_hoursSinceUpdate
};
} else {
log('No Zigbee devices found with temperature measurement capabilities from Xiaomi Mi weather.');
return 'No Zigbee devices found';
}