Script get all battery of modules

Hello, I’ve adopted a script from a user, but when I run it on Homey 2023, I encounter this error message. Can someone provide the fix?

// battery-report
let array = [];

const devices = await Homey.devices.getDevices({ filter: {capabilities: 'measure_battery'} });
_.forEach(devices, device => {
array.push( device.name  + ':  \n' + device.capabilitiesObj?.measure_battery.value + '%' );
});

//oldest date on top sort array = ["time_stamp device", "time_stamp device", "time_stamp device" ]
const array_sorted = array.slice().sort(function(time_stamp, device) { 
 const firsttime_stamp = time_stamp.split(" ")[0];
 const secondtime_stamp = device.split(" ")[0];
 if(firsttime_stamp < secondtime_stamp) return -1;
 if(firsttime_stamp > secondtime_stamp) return 1;
 return 0;
});

return("Battery levels:\n" + array_sorted.join('\n') + "\n");

This one should work better

// Sensor.onBattery_Check.js 
// to check sensors connection by comparing last update times
let array = [];

const devices = await Homey.devices.getDevices({ filter: {class: 'sensor', capabilities: 'measure_battery'} });
_.forEach(devices, device => {
array.push( device.capabilitiesObj?.measure_battery.lastUpdated?.substring(0,10) + " / [" + device.name + "]" );
});

//oldest date on top sort array = ["time_stamp device", "time_stamp device", "time_stamp device" ]
const array_sorted = array.slice().sort(function(time_stamp, device) { 
 const firsttime_stamp = time_stamp.split(" ")[0];
 const secondtime_stamp = device.split(" ")[0];
 if(firsttime_stamp < secondtime_stamp) return -1;
 if(firsttime_stamp > secondtime_stamp) return 1;
 return 0;
});

console.log("Sensors battery alert:\n" + array_sorted.join('\n'));

Homey.flow.runFlowCardAction({
        uri: 'homey:manager:notifications',
        id: 'create_notification',
        args: {
          text: "Sensors battery alert:\n" + array_sorted.join('\n')
        },
      });
return(true);

.

And in this example you can find an alternative version of the script which measures any preferred device, including a filtering option (open the post to view all of it):

Thank you, I will try.

Sorry, but with your corrected code, I still have an error

When I change the last line


return true;

to this


return "Sensors battery alert:\n" + array_sorted.join('\n');

the HS flow card finishes like it should
I cannot reproduce the error you show.

Do you happen to own a Pro 2023? I run the script on a Pro 2019…

Did you check the other script I referred to earlier:

Great, you’ve found the issue, but the script doesn’t return any results. It seems like something is missing in the code to display the list. Do you know why? Yes, I’m using Homey 2023, and I’ve also encountered this issue with Pushover, which throws an error but still works. For your information, the developer is asking if someone could review his code to make it compatible with Homey 2023, as he no longer has the time to address it. So, if you’re interested, send him a message.

OK. You seem to focus on this script. Curious why don’t you try the, way better, alternative script I pointed out twice?

Yes, I even installed it, but your script only brings back the modules where no action has been taken for XX minutes. What I want, in relation to the script I’m showing you, is the ability to display all the batteries with their percentages next to them, just like what’s available on the iOS application

Owww, my bad, coffee shortage most probably :stuck_out_tongue: Somehow I thought it was the ‘device last-updated’ script…
I now I get your plans.
No clue what changed, I now only got 2 devices (both robovacs, it’s just scary) from 30-ish battery using devices. At the time of publishing the flow + script, it showed all battery levels :thinking:

.
The array_sort part wasn’t needed by the way,

// battery-report
let array = [];

const devices = await Homey.devices.getDevices({ filter: {capabilities: 'measure_battery'} });
_.forEach(devices, device => {
array.push( device.name  + ':  \n' + device.capabilitiesObj?.measure_battery?.value + '%' );
});

return "Battery levels:\n" + array.slice('\n') + "\n" ;

t’s okay, I’ve rewritten the code to make it work. Now it displays the battery levels for each module from the lowest to the highest. :smiley:

const devicesObject = await Homey.devices.getDevices({ filter: { class: 'sensor' } });
const devices = Object.values(devicesObject);

const batteryLevels = [];

for (const device of devices) {
  const batteryCapability = device.capabilitiesObj.measure_battery;
  if (batteryCapability) {
    const batteryLevel = batteryCapability.value;
    const deviceName = device.name;
    batteryLevels.push({ name: deviceName, battery: batteryLevel });
  }
}

batteryLevels.sort((a, b) => a.battery - b.battery);

const batteryInfoText = batteryLevels.map((device) => `${device.name}: ${device.battery}%`).join('\n');

console.log('Niveaux de batterie:\n' + batteryInfoText);

return 'Niveaux de batterie:\n' + batteryInfoText;

1 Like

Nice!
It only doesn’t return any device @ my Pro 2019 :hugs:
No errors.

That’s a real shame! :pensive: It works great on the 2023 version. Well, we either need to migrate to the new box or modify the code to make it work on the 2019 version.

Try this version and let me know if it works on your 2019 box. Unfortunately, I can’t test it as I have the 2023 version.

const devicesObject = await Homey.devices.getDevices({ filter: { class: 'sensor' } });
const deviceKeys = Object.keys(devicesObject);
const batteryLevels = [];

for (const deviceKey of deviceKeys) {
  const device = devicesObject[deviceKey];
  const batteryCapability = device.capabilitiesObj.measure_battery;
  if (batteryCapability) {
    const batteryLevel = batteryCapability.value;
    const deviceName = device.name;
    batteryLevels.push({ name: deviceName, battery: batteryLevel });
  }
}

batteryLevels.sort((a, b) => a.battery - b.battery);

const batteryInfoText = batteryLevels.map((device) => `${device.name}: ${device.battery}%`).join('\n');

console.log('Niveaux de batterie:\n' + batteryInfoText);

return 'Niveaux de batterie:\n' + batteryInfoText;

I tested this on my Homey Early 2016 and can confirm it works.
Thank you for the efforts! :blush:

Thanks for your efforts!
It still returns zero:

Niveaux de batterie:

———————————————————
✅ Script Success
↩️ Returned: "Niveaux de batterie:\n"

.

Now when I add this after line 3:

log ("deviceKeys: ", deviceKeys);

it shows the ID’s of 70 devices, but i have around 30 battery powered sensors.

For me it works as well, but it’s a bit odd it doesn’t return any battery value :thinking:
Can you elaborate on “it works”? Thanks in advance.

Hi Peter,

Here’s my output with a little script change for language purposes:

You need a HP2016 for this :rofl: , that works fine for me too, same result as @Sebby5

I don’t see how a Pro 2019 is different from a 2016 model, Jan! :joy::rofl::joy:
A script doesn’t care about more RAM and an additional CPU core, right?

1 Like