[Homey Pro] overview script

Homey Pro overview script

Always wanted an overview of your current Homey?
Because you are in the process of migrating to another Homey Pro, or just for the fun of it.
Well that is what this very HomeyScript script is for.
Feel free to share your results in this thread, as I do like to see every ones Homey too! (no sensitive data is shown)

I’ve tried to make this overview script somewhat user friendly to use.
The only thing you need is an Homey Pro (any version, besides Homey (Cloud)) and the app HomeyScript.

When you have that app installed you can go to the Web GUI => Scripts and click on “New HomeyScript” on the bottom-left of the page.
A new script will get created and you can give it a name (not mandatory, just easier to find it back later on), “Homey Overview” is a good example :wink:
Then all you need to do is copy and paste the entire script below (it is pretty large, 556 lines) into the top field, and press the “Save” button.

Then to see the result all you have to do is press “Test”, and behold the results will show up below it (it can take a few seconds to retrieve all information from Homey Pro).
(Tip: you can increase the result’s view by dragging the “Output” line, up).

Changelog:

  • v1.15 (October 16, 2023):
    • Added: Insight entries (boolean (yes/no) & numbers)
  • v1.14 (September 19, 2023):
    • Added: Unavailable devices (and the reason when displayed)
Show older updates
  • v1.13 (September 18, 2023):
    • Added: Last seen date and time for ZigBee devices, Homey Pro (early 2023) only
  • v1.12 (June 28, 2023):
    • Added: Logic (variable) names and their ID, for each type
    • Added: Node ID to Z-Wave devices’ names list
  • v1.11 (May 10, 2023):
    • Fix (virtual) infrared device(s) not being counted for Homey Pro (early 2023) (API change)
  • v1.10 (May 8, 2023):
    • Added: count and overview of apps are in the Stable or Test channel, or installed from CLI (development)/Community Appstore
  • v1.9 (April 26, 2023):
    • Fix error for the now available getAppSettings() function (since 10.0.0-rc.80)
  • v1.8 (April 9, 2023):
    • Added: App <group>'s devices to the virtual devices count
  • v1.7 (April 6, 2023):
    • Added: Storage information (disabled by default for Homey Pro (2016-2019) as it is a very slow function)
    • Added: Number of alarm clocks
    • Homey Pro (early 2023) only:
      • Added: Throttled (Homey Pro (early 2023) will throttle when a bad power supply is used or the temperature is being too high)
      • Added: Under voltage (Homey Pro (early 2023) was delivered at first with a power supply that in many cases delivered too low of a voltage.)
    • Cleaned up the code a bit
  • v1.6 (April 3 2023):
    • Fix error with counting Router and End Devices for ZigBee devices (API change) on Homey Pro (early 2023)
  • v1.5 (March 14 2023):
    • Added error information for Homey Pro (early 2023) users as HomeyScript needs an update to support the getAppSettings() function
    • Fix when no HomeyScript tokens (again)
  • v1.4 (March 11 2023):
    • Added amount of HomeyScripts
  • v1.3 (March 11 2023):
    • Fix when no HomeyScript tokens
  • v1.2 (March 11 2023):
    • Added amount of: HomeyScript tokens, Better Logic Variables;
    • Added some error catching if anything fails, it will continue on;
  • v1.1 (March 11 2023):
    • Fixed the Z-Wave count.
      I used a bad way before, now it is more accurate and includes the different security levels;
    • Added Chronograph and Better Logic Library for Virtual Devices count;
  • v1 (March 10 2023):
    • Initial release;

Note:

The Z-Wave count for battery and router devices can be slightly wrong to your actual real life devices, as Homey doesn’t expose what a actual router or battery device is, there is a “battery” flag but that is false for FLiRS devices like “newer” thermostats (Eurotronic Spirit or Fibaro Thermostatic).
I’ve tried to fix it as accurate as possible by also looking if there are batteries specified for the device.
But also this isn’t the case for every device like the Aeotec Siren 6, which has a battery, but that is only for backup reasons and thus pretty much always connected to the mains.
This is just the best I could do without having to manual configure every device that should be excluded, which is too much work for just an Overview Script.

Count down and/or other apps
I won’t be adding the countdown apps, there are 4 different ones, and is getting a bit too much that way.
Other apps will most likely also not be added, or in the end the script will contain all apps.

Disclaimer:

If you encounter an issue, feel free to say so and I will try to fix it as soon as possible.

Please do keep the thread clean, any non related replies will get deleted!
If you have (general) questions about HomeyScript or the used Web API, then this is not the thread for that.

The Script v1.15:

// Set any of these from `false;` to `true;` to see the corresponding Name(s) or Node ID('s) added to the list
const showStorage = false; // Show storage status (Very slow!, is enabled for Homey Pro (early 2023))
const showUpdateableApps = false; // Names of Apps that can be updated
const showDisabledApps = false; // Names of Apps that are disabled or crashed
const showStableApps = false; // Names of Stable channel Apps
const showTestApps = false; // Names of Test channel Apps
const showDevApps = false; // Names of Apps that are installed via CLI or Community Appstore
const showSDKv2Apps = false; // Names of Apps that are on SDKv2
const showSDKv3Apps = false; // Names of Apps that are on SDKv3
const showLogicBoolean = false; // Names and ID of boolean (yes/no) variables
const showLogicNumber = false; // Names and ID of number variables
const showLogicString = false; // Names and ID of string (text) variables
const showDisabledFlows = false; // Names of Flows that are disabled
const showBrokenFlows = false; // Names of Flows that are broken
const showDisabledAdvancedFlows = false; // Names of Advanced Flows that are disabled
const showBrokenAdvancedFlows = false; // Names of Advanced Flows that are broken
const showUnavailableDevices = false; // Names of devices that are marked unavailable
const showZwaveDevices = false; // Names and Node ID of all Z-Wave devices
const showZwaveRouterDevices = false; // Names and Node ID of Z-Wave router devices
const showZwaveUnsecureDevices = false; // Names and Node ID of unsecure Z-Wave devices
const showZwaveSecureS0Devices = false; // Names and Node ID of secure (S0) Z-Wave devices
const showZwaveSecureS2AuthenticatedDevices = false; // Names and Node ID of secure (S2 Authenticated) Z-Wave devices
const showZwaveSecureS2UnauthenticatedDevices = false; // Names and Node ID of secure (S2 Unauthenticated) Z-Wave devices
const showZwaveBatteryDevices = false; // Names and Node ID of Z-Wave battery devices
const showZwaveUnreachableNodes = false; // Node ID's of unreachable (flagged) devices
const showZwaveUnknownNodes = false; // Node ID's of unknown nodes
const showZigbeeNodes = false; // Names of all ZigBee devices
const showZigbeeRouter = false; // Names of ZigBee: router devices
const showZigbeeEndDevice = false; // Names of ZigBee: end device devices
const showZigbeeLastSeen = false; // Show additional: the last seen time and date (early 2023+ only)
const showVirtualDevices = false; // Names of all Virtual devices
const showIRDevices = false; // Names of all InfraRed devices

// ================= Don't edit anything below here =================

log('--------------- Homey Pro Overview v1.15 --------------');

await Homey.system.getSystemName()
  .then(result => log('Homey name:', result))
  .catch(() => log('Failed: Getting Homey name'));

let homeyPlatformVersion, homeyVersion, timezone;
await Homey.system.getInfo()
  .then(result => {
    log('Homey version:', homeyVersion = result.homeyVersion);
    log('Homey model:', result.homeyModelName, '(' + result.cpus.length + ' core(s))');
    homeyPlatformVersion = result.homeyPlatformVersion || 1;
    timezone = result.timezone;

    const d = Math.floor(result.uptime / 86400);
    const h = Math.floor((result.uptime % 86400) / 3600);
    const m = Math.floor((result.uptime % 3600) / 60);
    const s = Math.floor(result.uptime % 60);
    let uptimeHuman = '';
    if (d > 0) uptimeHuman += d + ' day' + (d > 1 ? 's, ' : ', ');
    uptimeHuman += h + ' hour' + (h > 1 ? 's, ' : ', ');
    uptimeHuman += m + ' minute' + (m > 1 ? 's, ' : ', ');
    uptimeHuman += s + ' second' + (s > 1 ? 's' : '');
    log('Uptime:', result.uptime, '(' + uptimeHuman + ')');

    if (homeyPlatformVersion === 2) {
      log('WiFi:', (result.wifiConnected) ? 'Connected' : 'Not connected');
      log('Ethernet:', (result.ethernetConnected) ? 'Connected' : 'Not connected');
      log('Throttled:', (result.videoCoreThrottleOccured) ? 'Yes' : 'No', '(Currently:', (result.videoCoreThrottleCurrently) ? 'Yes)' : 'No)');
      log('Under voltage:', (result.videoCoreUndervoltageOccured) ? 'Yes' : 'No', '(Currently:', (result.videoCoreUnderVoltageCurrently) ? 'Yes)' : 'No)');
    }
  })
  .catch(() => log('Failed: Getting Homey\'s statistics'));

await Homey.updates.getUpdates()
  .then(result => {
    if(result.length > 0) {
      log('Update available:', result[0].version);
    } else {
      log('Update available: No');
    }
  })
  .catch(() => log('Failed: Getting updates'));

if (showStorage || homeyPlatformVersion === 2) {
  await Homey.system.getStorageInfo()
    .then(result => {
      let sizeFree = result.free + 'B'
      if (result.free >= 1000000000) {
        sizeFree = (result.free / 1000000000).toFixed(2) + ' GB';
      } else if (result.free >= 1000000) {
        sizeFree = (result.free / 1000000).toFixed(2) + ' MB';
      }
      log('Storage:', (result.total / 1000000000).toFixed(2), 'GB (' + sizeFree + ' free)');
    })
    .catch(() => log('Failed: Getting storage information'));
}

log('\r\n------------------ Main ---------------------');

await Homey.users.getUsers()
  .then(result => {
    let owner = 0, manager = 0, user = 0, guest = 0;

    Object.keys(result).forEach(function(key) {
      const role = result[key].role;
      if (role === 'owner') owner++;
      if (role === 'manager') manager++;
      if (role === 'user') user++;
      if (role === 'guest') guest++;
    });

    log(Object.keys(result).length, 'Users', '('  + owner + ' Owner, ' + manager + ' Manager, ' + user + ' User, ' + guest + ' Guest)');
  })
  .catch(() => log('Failed: Getting users'));

await Homey.apps.getApps()
  .then(result => {
    let sdkv2Apps = [], sdkv3Apps = [], updateableApps = [], disabledApps = [], stableApps = [], testApps = [], devApps = [];

    Object.keys(result).forEach(function(key) {
      if (result[key].updateAvailable) updateableApps.push(result[key].name);
      if (result[key].sdk === 2) sdkv2Apps.push(result[key].name);
      if (
        result[key].sdk === 3
        || homeyPlatformVersion === 2
      ) {
        sdkv3Apps.push(result[key].name);
      }
      if (!result[key].ready) disabledApps.push(result[key].name);
      if (result[key].origin === 'devkit_install') devApps.push(result[key].name);
      else if (result[key].channel === 'stable' || result[key].channel === 'live') stableApps.push(result[key].name);
      if (result[key].channel === 'beta' || result[key].channel === 'test') testApps.push(result[key].name);
    });

    log(Object.keys(result).length, 'Apps', '(' + stableApps.length + ' Stable, ' + testApps.length + ' Test, ' + devApps.length + ' Development/Community Appstore, ' + sdkv2Apps.length + ' SDKv2, '  + sdkv3Apps.length + ' SDKv3, '  + updateableApps.length + ' Updateable, ' + disabledApps.length + ' Disabled/Crashed)');
    if (showStableApps) {
      log('---------------------------------------------')
      log('App(s) in the Stable channel:');
      log(stableApps.join('\r\n'));
      log('---------------------------------------------')
    }

    if (showTestApps) {
      log('---------------------------------------------')
      log('App(s) in the Test channel:');
      log(testApps.join('\r\n'));
      log('---------------------------------------------')
    }

    if (showDevApps) {
      log('---------------------------------------------')
      log('App(s) that are installed via CLI or Community Appstore:');
      log(devApps.join('\r\n'));
      log('---------------------------------------------')
    }

    if (showSDKv2Apps) {
      log('---------------------------------------------')
      log('SDKv2 app(s):');
      log(sdkv2Apps.join('\r\n'));
      log('---------------------------------------------')
    }

    if (showSDKv3Apps) {
      log('---------------------------------------------')
      log('SDKv3 app(s):');
      log(sdkv3Apps.join('\r\n'));
      log('---------------------------------------------')
    }

    if (showUpdateableApps) {
      log('---------------------------------------------')
      log('Updateable app(s):');
      log(updateableApps.join('\r\n'));
      log('---------------------------------------------')
    }

    if (showDisabledApps) {
      log('---------------------------------------------')
      log('Disabled app(s):');
      log(disabledApps.join('\r\n'));
      log('---------------------------------------------')
    }
  })
  .catch(() => log('Failed: Getting apps'));

await Homey.zones.getZones()
  .then(result => log(Object.keys(result).length, 'Zones'))
  .catch(() => log('Failed: Getting zones'));

await Homey.notifications.getNotifications()
  .then(result => log(Object.keys(result).length || 0, 'Notifications (Timeline)'))
  .catch(() => log('Failed: Getting notifications'));

await Homey.insights.getLogs()
  .then(result => {
    let boolean = 0, number = 0;

    Object.keys(result).forEach(function(key) {
      if (result[key].type === 'number') number++;
      if (result[key].type === 'boolean') boolean++;
    });

    log(result.length, 'Insight entries', '(' + boolean + ' Boolean (Yes/No), ' + number + ' Number)');
  })
  .catch(() => log('Failed: Getting Insights'));

await Homey.logic.getVariables()
  .then(result => {
    let boolean = [], number = [], string = [];
  
    Object.keys(result).forEach(function(key) {
      if (result[key].type === 'boolean') boolean.push(result[key].name + ' (ID: ' + result[key].id + ')');
      if (result[key].type === 'number') number.push(result[key].name + ' (ID: ' + result[key].id + ')');
      if (result[key].type === 'string') string.push(result[key].name + ' (ID: ' + result[key].id + ')');
    });

    log(Object.keys(result).length, 'Logic Variables', '(' + boolean.length + ' Boolean (Yes/No), ' + number.length + ' Number, ' + string.length + ' String (Text))');
    
    if (showLogicBoolean) {
      log('---------------------------------------------')
      log('Boolean (yes/no) variable(s):');
      log(boolean.join('\r\n'));
      log('---------------------------------------------')
    }
    
    if (showLogicNumber) {
      log('---------------------------------------------')
      log('Number variable(s):');
      log(number.join('\r\n'));
      log('---------------------------------------------')
    }
    
    if (showLogicString) {
      log('---------------------------------------------')
      log('String (text) variable(s):');
      log(string.join('\r\n'));
      log('---------------------------------------------')
    }

  })
  .catch(() => log('Failed: Getting variables'));

await Homey.flow.getFlows()
  .then(result => {
    let disabledFlows = [], brokenFlows = [];
    Object.keys(result).forEach(function(key) {
      if (!result[key].enabled) disabledFlows.push(result[key].name);
      if (result[key].broken) brokenFlows.push(result[key].name);
    });

    log(Object.keys(result).length, 'Flows', '('  + brokenFlows.length + ' Broken, ' + disabledFlows.length + ' Disabled)');
    
    if (showBrokenFlows) {
      log('---------------------------------------------')
      log('Broken flow name(s):');
      log(brokenFlows.join('\r\n'));
      log('---------------------------------------------')
    }

    if (showDisabledFlows) {
      log('---------------------------------------------')
      log('Disabled flow name(s):');
      log(disabledFlows.join('\r\n'));
      log('---------------------------------------------')
    }
  })
  .catch(() => log('Failed: Getting flows'));

await Homey.flow.getAdvancedFlows()
  .then(result => {
    let disabledFlows = [], brokenFlows = [];
    Object.keys(result).forEach(function(key) {
      if (!result[key].enabled) disabledFlows.push(result[key].name);
      if (result[key].broken) brokenFlows.push(result[key].name);
    });

    log(Object.keys(result).length, 'Advanced flows', '('  + brokenFlows.length + ' Broken, ' + disabledFlows.length + ' Disabled)');
    
    if (showBrokenAdvancedFlows) {
      log('---------------------------------------------')
      log('Broken advanced flow name(s):');
      log(brokenFlows.join('\r\n'));
      log('---------------------------------------------')
    }

    if (showDisabledAdvancedFlows) {
      log('---------------------------------------------')
      log('Disabled advanced flow name(s):');
      log(disabledFlows.join('\r\n'));
      log('---------------------------------------------')
    }
  })
  .catch(() => log('Failed: Getting advanced flows'));
  
await Homey.alarms.getAlarms()
  .then(result => {
    let enabled = 0;
    Object.keys(result).forEach(function(key) {
      if (result[key].enabled) enabled++;
    })

    log(Object.keys(result).length, 'Alarms', '(' + enabled + ' Enabled)')
  })
  .catch(() => log('Failed: Getting alarms'));

await Homey.apps.getAppSettings({id: 'com.athom.homeyscript'})
  .then(result => {
    log(Object.keys(result.scripts).length, 'HomeyScript scripts', '(' + ((result.tokens) ? Object.keys(result.tokens).length : 0) + ' Token/Tag)');
  })
  .catch(() => {
    if (homeyPlatformVersion === 2 && homeyVersion.localeCompare("10.0.0-rc.80", undefined, {numeric: true, preversion: ["rc"]}) < 0) {
      log('Failed: Getting HomeyScript, Homey Pro (early 2023): getting information from apps is currently unavailable.');
    }
    else {
      log('Failed: Getting HomeyScript');
    }
  });

await Homey.apps.getAppSettings({id: 'net.i-dev.betterlogic'})
  .then(result => {
    let boolean = 0, number = 0, string = 0;
    Object.keys(result.variables).forEach(function(key) {
      if (result.variables[key].type === 'boolean') boolean++;
      if (result.variables[key].type === 'number') number++;
      if (result.variables[key].type === 'string') string++;
    });

    log(Object.keys(result.variables).length, 'Better Logic Variables', '(' + boolean + ' Boolean (Yes/No), ' + number + ' Number, ' + string + ' String)');
  })
  .catch(() => {
    if (homeyPlatformVersion === 2 && homeyVersion.localeCompare("10.0.0-rc.80", undefined, {numeric: true, preversion: ["rc"]}) < 0) {
      log('Failed: Getting Better logic, Homey Pro (early 2023): getting information from apps is currently unavailable.');
    }
  });

log('\r\n----------------- Devices -------------------');
let allDevices = 0, other = 0, zwaveDevices = [], zwaveNodes = [], zwaveRouterDevices = [], zwaveBatteryDevices = [], zwaveSxDevices = [], zwaveS0Devices = [], zwaveS2AuthDevices = [], zwaveS2UnauthDevices = [], unavailableDevices = [];

await Homey.devices.getDevices()
  .then(result => {
    let virtualNames = [], irNames = [];

    Object.keys(result).forEach(function(key) {
      const device = result[key];

      if (
        device.hasOwnProperty('available')
        && device.available === false
      ) {
        unavailableDevices.push(device.name + ' (' + device.unavailableMessage + ')');
      }

      if (device.driverUri === 'homey:manager:vdevice') {
        if (device.driverId === 'infraredbasic' || device.driverId.includes('virtualdriverinfrared')) {
          irNames.push(device.name);
        }
        else {
          virtualNames.push(device.name);
        }
      }
      else if (
        device.driverUri === 'homey:app:com.arjankranenburg.virtual'
        || device.driverUri === 'homey:app:nl.qluster-it.DeviceCapabilities'
        || device.driverUri === 'homey:app:nl.fellownet.chronograph'
        || device.driverUri === 'homey:app:net.i-dev.betterlogic'
        || device.driverUri === 'homey:app:com.swttt.devicegroups'
      ) {
        virtualNames.push(device.name);
      }
      else if (device.flags.includes('zwaveRoot')) {
        zwaveDevices.push(device.name + ' (Node ID: ' + device.settings.zw_node_id + ')');
        zwaveNodes.push(Number(device.settings.zw_node_id));
        
        if (
          device.settings.zw_battery === '✓'
          || device.energyObj.batteries
        ) {
          zwaveBatteryDevices.push(device.name + ' (Node ID: ' + device.settings.zw_node_id + ')');
        }
        else {
          zwaveRouterDevices.push(device.name + ' (Node ID: ' + device.settings.zw_node_id + ')');
        }

        switch(device.settings.zw_secure) {
          case '⨯':
            zwaveSxDevices.push(device.name + ' (Node ID: ' + device.settings.zw_node_id + ')');
            break;
          case '✓':
          case 'S0':
            zwaveS0Devices.push(device.name + ' (Node ID: ' + device.settings.zw_node_id + ')');
            break;
          case 'S2 (Unauthenticated)':
          case 'Unauthenticated':
            zwaveS2UnauthDevices.push(device.name + ' (Node ID: ' + device.settings.zw_node_id + ')');
            break;
          case 'S2 (Authenticated)':
          case 'Authenticated':
            zwaveS2AuthDevices.push(device.name + ' (Node ID: ' + device.settings.zw_node_id + ')');
            break;
        }
      }
      else if (
        !device.flags.includes('zwave')
        && !device.flags.includes('zigbee')
      ) {
        other++;
      }
    });

    allDevices += virtualNames.length + irNames.length + zwaveDevices.length + other;

    log(unavailableDevices.length, 'Unavailable devices')
    if (showUnavailableDevices) {
      log('---------------------------------------------')
      log('Unavailable device(s):');
      log(unavailableDevices.sort((a, b) => a - b).join('\r\n'));
      log('---------------------------------------------')
    }

    log(virtualNames.length, 'Virtual devices');
    if (showVirtualDevices) {
      log('---------------------------------------------')
      log('Virtual device(s):');
      log(virtualNames.sort((a, b) => a - b).join('\r\n'));
      log('---------------------------------------------')
    }

    log(irNames.length, 'Infrared (database) devices');
    if (showIRDevices) {
      log('---------------------------------------------')
      log('Infrared (database) device(s):');
      log(irNames.sort((a, b) => a - b).join('\r\n'));
      log('---------------------------------------------')
    }
  })
  .catch(() => log('Failed: Getting devices'));

await Homey.zwave.getState()
  .then(result => {
    const unknownNodes = result.zw_state.nodes
      .filter((el) => !zwaveNodes.includes(el))
      .sort((a, b) => a - b)
      .slice(1);
    
    log(zwaveDevices.length, 'Z-Wave devices', '(' + zwaveSxDevices.length + ' Unsecure, ' + zwaveS0Devices.length + ' Secure (S0), ' + zwaveS2AuthDevices.length + ' Secure (S2 Authenticated), ' + zwaveS2UnauthDevices.length + ' Secure (S2 Unauthenticated), ' + zwaveRouterDevices.length + ' Router, ' + zwaveBatteryDevices.length + ' Battery, ' + result.zw_state.noAckNodes.length + ' Unreachable, ' + unknownNodes.length + ' Unknown)')

    if (showZwaveDevices) {
      log('---------------------------------------------')
      log('Z-Wave device(s):');
      log(zwaveDevices.join('\r\n'));
      log('---------------------------------------------')
    }

    if (showZwaveRouterDevices) {
      log('---------------------------------------------')
      log('Z-Wave router device(s):');
      log(zwaveRouterDevices.sort((a, b) => a - b).join('\r\n'));
      log('---------------------------------------------')
    }

    if (showZwaveUnsecureDevices) {
      log('---------------------------------------------')
      log('Z-Wave unsecure device(s):');
      log(zwaveSxDevices.sort((a, b) => a - b).join('\r\n'));
      log('---------------------------------------------')
    }

    if (showZwaveSecureS0Devices) {
      log('---------------------------------------------')
      log('Z-Wave secure (S0) device(s):');
      log(zwaveS0Devices.sort((a, b) => a - b).join('\r\n'));
      log('---------------------------------------------')
    }

    if (showZwaveSecureS2AuthenticatedDevices) {
      log('---------------------------------------------')
      log('Z-Wave secure (S2) authenticated device(s):');
      log(zwaveS2AuthDevices.sort((a, b) => a - b).join('\r\n'));
      log('---------------------------------------------')
    }

    if (showZwaveSecureS2UnauthenticatedDevices) {
      log('---------------------------------------------')
      log('Z-Wave secure (S2) Unauthenticated device(s):');
      log(zwaveS2Unauth.sort((a, b) => a - b).join('\r\n'));
      log('---------------------------------------------')
    }

    if (showZwaveBatteryDevices) {
      log('---------------------------------------------')
      log('Z-Wave battery device(s):');
      log(zwaveBatteryDevices.sort((a, b) => a - b).join('\r\n'));
      log('---------------------------------------------')
    }

    if (showZwaveUnreachableNodes) {
      log('---------------------------------------------')
      log('Unreachable node(s):');
      log('Node ID:', result.zw_state.noAckNodes.sort((a, b) => a - b).join('\r\nNode ID: '));
      log('---------------------------------------------')
    }

    if (showZwaveUnknownNodes) {
      log('---------------------------------------------')
      log('Unknown node(s):');
      log('Node ID:', unknownNodes.join('\r\nNode ID: '));
      log('---------------------------------------------')
    }
  })
  .catch(() => log('Failed: Getting Z-Wave state'));

await Homey.zigBee.getState()
  .then(result => {
    let zigbeeDevices = [], routerDevices = [], endDevices = [];

    Object.keys(result.nodes).forEach(function(key) {
      device = result.nodes[key];
      let deviceName = device.name;
      if (showZigbeeLastSeen && device.hasOwnProperty('lastSeen')) {
        const lastSeen = new Date(device.lastSeen).toLocaleString('en-GB', {timeZone: timezone, month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit'});
        deviceName += ' (last seen: ' + lastSeen + ')';
      }
      zigbeeDevices.push(deviceName);

      if (device.type.toLowerCase() === 'router') routerDevices.push(deviceName);
      if (device.type.toLowerCase() === 'enddevice') endDevices.push(deviceName);
    });
    
    log(zigbeeDevices.length, 'Zigbee devices', '(' + routerDevices.length + ' Router, ' + endDevices.length + ' End device)');

    if (showZigbeeNodes) {
      log('---------------------------------------------')
      log('ZigBee device(s):');
      log(zigbeeDevices.join('\r\n'));
      log('---------------------------------------------')
    }

    if (showZigbeeRouter) {
      log('---------------------------------------------')
      log('ZigBee router(s):');
      log(routerDevices.sort((a, b) => a - b).join('\r\n'));
      log('---------------------------------------------')
    }

    if (showZigbeeEndDevice) {
      log('---------------------------------------------')
      log('ZigBee end device(s):');
      log(endDevices.sort((a, b) => a - b).join('\r\n'));
      log('---------------------------------------------')
    }

    allDevices += zigbeeDevices.length;
  })
  .catch(() => log('Failed: Getting ZigBee state'));

log(other, 'Other devices');
log(allDevices, 'Total devices')

return 'Overview finished';
19 Likes

My Result with v1.14 after migration from Homey Pro (early 2019) to Homey Pro (early 2023): (Don’t have better logic installed so it will not be shown)

--------------- Homey Pro Overview v1.15 --------------
Homey name: Aurora
Homey version: 10.0.9-rc.1
Homey model: Homey Pro (Early 2023) (4 core(s))
Uptime: 484074.39 (5 days, 14 hours, 27 minutes, 54 seconds)
WiFi: Connected
Ethernet: Not connected
Throttled: No (Currently: No)
Under voltage: No (Currently: No)
Update available: No
Storage: 2.66 GB (1.06 GB free)

------------------ Main ---------------------
1 Users (1 Owner, 0 Manager, 0 User, 0 Guest)
41 Apps (34 Stable, 5 Test, 2 Development/Community Appstore, 0 SDKv2, 41 SDKv3, 0 Updateable, 0 Disabled/Crashed)
40 Zones
1 Notifications (Timeline)
1358 Insight entries (705 Boolean (Yes/No), 653 Number)
55 Logic Variables (0 Boolean (Yes/No), 48 Number, 7 String (Text))
3 Flows (0 Broken, 0 Disabled)
170 Advanced flows (0 Broken, 0 Disabled)
6 Alarms (2 Enabled)
19 HomeyScript scripts (0 Token/Tag)

----------------- Devices -------------------
0 Unavailable devices
38 Virtual devices
0 Infrared (database) devices
63 Z-Wave devices (63 Unsecure, 0 Secure (S0), 0 Secure (S2 Authenticated), 0 Secure (S2 Unauthenticated), 32 Router, 31 Battery, 1 Unreachable, 1 Unknown)
63 Zigbee devices (47 Router, 16 End device)
66 Other devices
230 Total devices

———————————————————
:white_check_mark: Script Success
:leftwards_arrow_with_hook: Returned: “Overview finished”

1 Like

Nice and useful overview, thanks!

--------------- Homey Pro Overview --------------

Homey name: Homey

Homey version: 8.1.3

Homey model: Homey Pro (Early 2019) (2 core(s))

Uptime: 904206 (10 days, 11 hours, 10 minutes, 6 seconds)

Update available: None

------------------ Main ---------------------

3 Users (1 owner, 1 user(s), 1 guest(s))

30 Apps (6 SDKv2, 24 SDKv3, 6 updateable, 0 disabled/crashed)

17 Zones

1145 Notifications

26 Variables (17 boolean (yes/no), 0 number, 9 string)

5 Flows (0 broken, 0 disabled)

67 Advanced flows (0 broken, 5 disabled)

----------------- Devices -------------------

28 Z-Wave nodes (17 router, 2 battery, 1 unreachable)

16 Zigbee nodes (16 router, 0 end device)

17 Virtual devices

0 Infrared (database) devices

32 Other devices

93 Total devices

———————————————————
:white_check_mark: Script Success

:leftwards_arrow_with_hook: Returned: “Overview finished”

1 Like

--------------- Homey Pro Overview --------------

Homey name: Homey Pro van Gerner 26
Homey version: 8.1.3
Homey model: Homey Pro (Early 2019) (2 core(s))
Uptime: 289579 (3 days, 8 hours, 26 minutes, 19 seconds)
Update available: None

------------------ Main ---------------------

2 Users (1 owner, 1 manager(s), 0 user(s), 0 guest(s))
37 Apps (2 SDKv2, 35 SDKv3, 0 updateable, 0 disabled/crashed)
18 Zones
162 Notifications
27 Variables (2 boolean (yes/no), 21 number, 4 string)
69 Flows (0 broken, 8 disabled)
42 Advanced flows (0 broken, 5 disabled)
Failed: Getting HomeyScript Tokens

----------------- Devices -------------------

1 Virtual devices
0 Infrared (database) devices
51 Other devices
11 Z-Wave nodes (5 Unsecure, 0 Secure (S0), 2 Secure (S2 Authenticated), 4 Secure (S2 Unauthenticated), 6 router, 5 battery, 0 unreachable, 1 Unknown node(s))
42 Zigbee nodes (23 router, 19 end device)
105 Total devices

———————————————————
:white_check_mark: Script Success
:leftwards_arrow_with_hook: Returned: “Overview finished”

1 Like

Ok how do you have that many notifications they should be capped at 100 :joy:

They are capped at 1 month I think, latest one is Feb 10 19:13…

No they are capped at 100 when did you last reboot Homey? Around Feb 10?

Nice!!! Thanks!

Q: About variables, I assume Better Logic and HomeyScript variables aren’t included?
A: Now they are :wink:


UPDATED v1.10

--------------- Homey Pro Overview v1.10 --------------
Homey name: 1.HomeyPro Peter
Homey version: 8.1.3
Homey model: Homey Pro (Early 2019) (2 core(s))
Uptime: 2787865 (32 days, 6 hours, 24 minutes, 25 seconds)
Update available: No
Storage: 1.64 GB (652.07 MB free)

------------------ Main ---------------------
3 Users (1 Owner, 1 Manager, 0 User, 1 Guest)
48 Apps (18 Stable, 24 Test, 6 Development/Community Appstore, 4 SDKv2, 44 SDKv3, 1 Updateable, 12 Disabled/Crashed)
---------------------------------------------
App(s) that are installed via CLI or Community Appstore:
Cast a text to Google and Sonos
Broadlinkred
WebOS Plus
< Timeline Manager² >
Homey Community Store
tadoZones
---------------------------------------------
SDKv2 app(s):
Marantz
PaperTrails Log
Broadlinkred
ESP Easy
---------------------------------------------
51 Zones
160 Notifications (Timeline)
283 Logic Variables (40 Boolean (Yes/No), 157 Number, 86 String)
456 Flows (16 Broken, 61 Disabled)
---------------------------------------------
58 Advanced flows (13 Broken, 11 Disabled)
---------------------------------------------
3 Alarms (0 Enabled)
169 HomeyScript scripts (302 Token/Tag)
5 Better Logic Variables (1 Boolean (Yes/No), 1 Number, 3 String)

----------------- Devices -------------------
107 Virtual devices
0 Infrared (database) devices
---------------------------------------------
0 Z-Wave devices (0 Unsecure, 0 Secure (S0), 0 Secure (S2 Authenticated), 0 Secure (S2 Unauthenticated), 0 Router, 0 Battery, 0 Unreachable, 0 Unknown)
0 Zigbee devices (0 Router, 0 End device)
163 Other devices
270 Total devices

———————————————————
✅ Script Success
↩️ Returned: "Overview finished"

I had 700+ flow notifications once :stuck_out_tongue:

Ah, I didn’t even think of these, but those aren’t currently included indeed, not sure how easy it would be to include this.

A didn’t even see this one :joy: that should be an easy fix (edit: fixed)

1 Like

No, 10 days ago

--------------- Homey Pro Overview --------------

Homey name: Home

Homey version: 8.1.3

Homey model: Homey Pro (Early 2019) (2 core(s))

Uptime: 529 (8 minutes, 49 seconds)

Update available: None

------------------ Main ---------------------

5 Users (1 owner, 0 manager(s), 1 user(s), 3 guest(s))

38 Apps (3 SDKv2, 35 SDKv3, 1 updateable, 0 disabled/crashed)

26 Zones

31 Notifications

7 Variables (3 boolean (yes/no), 3 number, 1 string)

101 Flows (1 broken, 19 disabled)

11 Advanced flows (0 broken, 1 disabled)

----------------- Devices -------------------

16 Z-Wave nodes (8 router, 0 battery, 3 unreachable)

0 Zigbee nodes (0 router, 0 end device)

6 Virtual devices

0 Infrared (database) devices

131 Other devices

153 Total devices

——————————————————— ✅ Script Success

↩️ Returned: "Overview finished"

--------------- Homey Pro Overview v1.4 --------------

Homey name: Homey Pro
Homey version: 8.1.3
Homey model: Homey Pro (Early 2019) (2 core(s))
Uptime: 597031 (6 days, 21 hours, 50 minutes, 31 seconds)
Update available: None

------------------ Main ---------------------
2 Users (1 owner, 0 manager(s), 1 user(s), 0 guest(s))


SDKv2 apps:
ABUS
NEO Coolcam
HTTP request flow cards
Homey Community Store


Updateable apps:


Disabled apps:
HTTP request flow cards
UnZ-Cure
MQTT Hub
MQTT Client


45 Apps (4 SDKv2, 41 SDKv3, 0 updateable, 4 disabled/crashed)
25 Zones
11 Notifications
149 Variables (54 boolean (yes/no), 90 number, 5 string)
266 Flows (6 broken, 114 disabled)
97 Advanced flows (0 broken, 20 disabled)
29 HomeyScript scripts (2 tokens)

----------------- Devices -------------------

20 Virtual devices
0 Infrared (database) devices
49 Other devices
78 Z-Wave nodes (72 Unsecure, 1 Secure (S0), 3 Secure (S2 Authenticated), 2 Secure (S2 Unauthenticated), 39 router, 39 battery, 1 unreachable, 0 Unknown node(s))
37 Zigbee nodes (19 router, 18 end device)
184 Total devices

———————————————————
:white_check_mark: Script Success
:leftwards_arrow_with_hook: Returned: “Overview finished”

Updated 12.03.23 with script v1.4

Lots of people have more Z-wave Node IDs then the router + battery devices (they should sum up to the same value) would indicate, and I’m curious why.

Anyone that has this willing to do some more “research”?
Please PM me or contact me on slack (caseda).

You’re right. I haven’t noticed it at all so far. I have counted and I come to 78 (without Homey). I will contact you on Slack.

-------------- Homey Pro Overview --------------

Homey name: Homey

Homey version: 8.1.3

Homey model: Homey (Early 2018) (1 core(s))

Uptime: 40939 (11 hours, 22 minutes, 19 seconds)

Update available: None

------------------ Main ---------------------

2 Users (1 owner, 0 manager(s), 1 user(s), 0 guest(s))

27 Apps (6 SDKv2, 21 SDKv3, 5 updateable, 0 disabled/crashed)

17 Zones

11 Notifications

1 Variables (1 boolean (yes/no), 0 number, 0 string)

129 Flows (1 broken, 12 disabled)

7 Advanced flows (0 broken, 4 disabled)

----------------- Devices -------------------

1 Z-Wave nodes (0 router, 0 battery, 0 unreachable)

5 Zigbee nodes (1 router, 4 end device)

15 Virtual devices

1 Infrared (database) devices

44 Other devices

66 Total devices

——————————————————— :white_check_mark: Script Success

:leftwards_arrow_with_hook: Returned: “Overview finished”

Nice to see. But I wonder; how to find the apps that are updatable?

in the top of the script there are several options you can turn on to show the names added to the overview, for updateable apps change this line:

const showUpdateableApps = false; // Names of Apps that can be updated

to

const showUpdateableApps = true; // Names of Apps that can be updated

And it will add the names to the overview of the apps that can be updated when you run (test) the script.

1 Like

Interesting enough my sum of router+battery+unreachable is way less than the total amount…

yeah, i’ve probably overlooked something with the code when i wrote that part long time ago… backtracing it all right now :sweat_smile:

(Deleted devices?)