Updated script I posted above - added counter of non responding devices - eg, in case you would like to initiate some action based on number of not-responding devices - please note this is the version I’m using, so feel free to change relevant variables below the section // Filter devices to check
Changelog :
0.1 - update - converting notReportingCount to a number - if you used previous version of script, delete tag by await tag(‘notReportingCount’, null);*
0.2 - added filtering based on device app type - thanks @Peter_Kawa*
0.3 - update for new HomeyScript - compatible now only with HomeyScript v. 3.5.1 and later
0.3b - fixed for THEN card (returning TEXT value), primary use-better use is for AND card though
// Version 0.3b
// Script checks devices based on the last updated time against a threshold
// Focuses on temperature sensors and specified device classes
const NotReportingThreshold = 0.8; // 0.8 hours, which is 48 minutes
const thresholdInMillis = NotReportingThreshold * 3600000; // Convert hours to milliseconds
let DevicesNotReporting = [];
let devices = await Homey.devices.getDevices();
let notReportingCount = 0; // Variable to keep track of the count
// Function to format date as "dd-mm-yyyy, hh:mm:ss"
function formatDate(date) {
if (!date) return "Unknown"; // Return 'Unknown' if date is null or invalid
const day = date.getDate().toString().padStart(2, '0');
const month = (date.getMonth() + 1).toString().padStart(2, '0'); // Months are 0-indexed
const year = date.getFullYear().toString();
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
const seconds = date.getSeconds().toString().padStart(2, '0');
return `${day}-${month}-${year}, ${hours}:${minutes}:${seconds}`;
}
for (const device of Object.values(devices)) {
// Exclude Virtual Devices and specific apps
if (device.driverUri && device.driverUri.match('vdevice|nl.qluster-it.DeviceCapabilities|nl.fellownet.chronograph|net.i-dev.betterlogic|com.swttt.devicegroups|com.gruijter.callmebot|com.netscan')) continue;
// Include by regex device name, focusing on temperature-related devices
if (!device.name || !device.name.match(/temperature/i)) continue;
// Exclude devices based on specific name patterns (if necessary, uncomment and modify)
// if (device.name.match(/Flood|TVOC|Netatmo Rain|Motion|Flora|Rear gate Vibration Sensor|Vibration Sensor Attic Doors/i)) continue;
// Include devices based on device class
if (!device.class || !device.class.match(/sensor|button|remote|socket|lights/i)) continue;
let IsReporting = false;
let lastUpdated = null;
for (const capability of Object.values(device.capabilitiesObj)) {
if (!capability.lastUpdated) continue; // Skip capabilities without lastUpdated info
let timeSinceReport = Date.now() - new Date(capability.lastUpdated).getTime();
if (timeSinceReport < thresholdInMillis) {
IsReporting = true;
break;
}
// Track the most recent update
if (!lastUpdated || new Date(capability.lastUpdated) > new Date(lastUpdated)) {
lastUpdated = new Date(capability.lastUpdated);
}
}
if (!IsReporting) {
let deviceInfo = `${device.name} (${formatDate(lastUpdated)} - ${device.class}) (NOK)`;
DevicesNotReporting.push(deviceInfo);
console.log('NOK:', deviceInfo);
// Increment the count
notReportingCount++;
} else {
let deviceInfo = `${device.name} (${formatDate(lastUpdated)} - ${device.class}) (OK)`;
console.log('OK:', deviceInfo);
}
}
// Output for script AND card
await tag('InvalidatedDevices', DevicesNotReporting.join('\n'));
await tag('notReportingCount', notReportingCount);
// Define a return value
const myTag = `Not Reporting Count: ${notReportingCount}\nDevices Not Reporting:\n${DevicesNotReporting.join('\n')}`;
// Return the defined value
return myTag;