A script to check sensor last update

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*

//version 0.2
const NotReportingThreshold = 0.8; // 0.8
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

for (const device of Object.values(devices)) {
// Exclude Virtual Devices and apps:
if (device.driverUri.match('vdevice|nl.qluster-it.DeviceCapabilities|nl.fellownet.chronograph|net.i-dev.betterlogic|com.swttt.devicegroups|com.gruijter.callmebot|com.netscan' )) continue; 
  // Filter devices to check
  if (!device.name.match(/temperature/i)) continue; // Include by regex device name
  //if (device.name.match(/Flood|TVOC|Netatmo Rain|Motion|Flora|Rear gate Vibration Sensor|Vibration Sensor Attic Doors/i)) continue; // Exclude devices with given name
  if (!device.class.match(/sensor|button|remote|socket|lights/i)) continue; // Include device types

  // Any capability updated recently?
  let IsReporting = false;
  for (const capability of Object.values(device.capabilitiesObj)) {
    if (!capability.lastUpdated) continue; // Skip NULL values
    let timeSinceReport = Date.now() - new Date(capability.lastUpdated);
    if (timeSinceReport < thresholdInMillis) {
      IsReporting = true;
      break;
    }
  }

  // Add to list if not reported 
  if (!IsReporting) {
    let lastUpdated = null;
    for (const capability of Object.values(device.capabilitiesObj)) {
      if (capability.lastUpdated && (!lastUpdated || new Date(capability.lastUpdated) > new Date(lastUpdated))) {
        lastUpdated = capability.lastUpdated;
      }
    }
    DevicesNotReporting.push(device.name + ' (' + (lastUpdated ? new Date(lastUpdated).toLocaleString('en-GB', { timeZone: 'Europe/Paris', year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/[./]/g, '-') : "Unknown") + ')');
    console.log('NOK: ' + device.name + ' - ' + device.class + ' - Last updated: ' + (lastUpdated ? new Date(lastUpdated).toLocaleString('en-GB', { timeZone: 'Europe/Paris', year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/[./]/g, '-') : "Unknown"));

    // Increment the count
    notReportingCount++;
  } else {
    let lastUpdated = null;
    for (const capability of Object.values(device.capabilitiesObj)) {
      if (capability.lastUpdated && (!lastUpdated || new Date(capability.lastUpdated) > new Date(lastUpdated))) {
        lastUpdated = capability.lastUpdated;
      }
    }
    console.log('OK: ' + device.name + ' - ' + device.class + ' - Last updated: ' + (lastUpdated ? new Date(lastUpdated).toLocaleString('en-GB', { timeZone: 'Europe/Paris', year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/[./]/g, '-') : "Unknown"));
  }
}

// Convert notReportingCount to a number and update the variable - just leftover, shouldn't be required
notReportingCount = parseInt(notReportingCount, 10);

// Output for script AND card
await ([
  tag('InvalidatedDevices', DevicesNotReporting.join('\n')),
  tag('notReportingCount', notReportingCount) // Tag notReportingCount as a number
]);

// Return both values
return {
  notReportingCount: notReportingCount,
  DevicesNotReporting: DevicesNotReporting
};

2 Likes