Can the DeviceID field have multiple entries?

HA Core v0.115.3
NR v. 1.1.3
WebSocket integration Palette v 0.25.1

I’m using the Poll State Node to monitor battery condition of a device, and it works just fine.
But I have many (extremely many) devices with batteries, and I’d like to monitor them all.
Instead of adding lot of nodes and maintain each one individually (which will lead to chaos), I’d like to add multiple devices to the DeviceID field in just a single node.
Is that possible?

I see that the State Change Node allows DeviceID’s to be entered alternatively as a substring or a regular expression, but that option is absent in the Poll State Node.

Any suggestion is highly welcome.
(or how do I add this as a feature request?)

You can use get entities node to find all entities with battery level attribute <=100. the problem is attributes are not consistent I see. some uses battery_level and some user battery to report it. so you may need more than 1 node but definitely less than polling state for each entity.

image

@serkank, thank you for that tip. I haven’t tried the “Get Entities” node yet, so I’ll try that. I have also noticed the inconsistency inthe attribute names, but isn’t that something I can change in HA myself (rename these attributes to make them consistant) ?

1 Like

I think the attribute names are coming from the integrations, customization couldn’t change the name itself. or better said: i don’t know a way to do it.

Perhaps not a good solution but you could add them all in an array and loop through them in a function node.
That way the entities and attributes can be manually added and there is less headache.
But probably more finger ache for typing it all :wink:

@serkank, Sorry to bother you with my stupid questions, but how do I “trigger” the “Get Entities” node so that something is produced on its output? This node has an input, but what to connect there?
I need a way to initiate a steady stream of payloads that I can work with (or at least at regular intervals). I can’t just sit back and wait for a state to change in HA (which can take days or weeks).

Inject node?
It can be triggered manually or set to trigger at intervals

1 Like

Yes, I tried using the inject node, but the resulting output was an array with one (1) object, and the same object every time I triggered it. I could not successfully determine why that particular object turned up, perhaps because it was the first one found ?
I had expected an array of (n) objects = the total number of objects matching the selected attribute.
In the loooong list of attributes presented during setup of the node, I found only two with the word “battery” in it ;

attribute.Battery_level
attribute.battery_level

As can be seen, the difference between them is only the capital character ‘B’
By selecting “the other” attribute, the same object was selected again, but with a different payload.

Beats me…

are you using 2 separate get entities node for each attribute? The condition in get entities is “AND”.

No, I use only a single “Get Entities” node. Here is my very simple setup so far:

[{"id":"63bcc99e.14ff48","type":"ha-get-entities","z":"7b5044f.7cabdbc","server":"15c5ca8b.7ac0c5","name":"","rules":[{"property":"attributes.battery_level","logic":"lt","value":"100","valueType":"num"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":410,"y":260,"wires":[["659f1ca3.fb39f4"]]},{"id":"659f1ca3.fb39f4","type":"debug","z":"7b5044f.7cabdbc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":630,"y":260,"wires":[]},{"id":"ac8a273d.607838","type":"inject","z":"7b5044f.7cabdbc","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":240,"y":260,"wires":[["63bcc99e.14ff48"]]},{"id":"15c5ca8b.7ac0c5","type":"server","z":"","name":"Home Assistant","legacy":false,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]

This is the output in the debug panel:

10/1/2020, 12:36:33 AMnode: 6abc2c8c.c4e014
msg.payload : array[1]
array[1]
0: object
entity_id: "device_tracker.iphone_se"
state: "home"
attributes: object
last_changed: "2020-09-30T17:50:43.619867+00:00"
last_updated: "2020-09-30T17:50:43.619867+00:00"
context: object
id: "763beedb034511eb8cb63d5ed06c3dd9"
parent_id: null
user_id: null
timeSinceChangedMs: 17149412

I have no idea why the device tracker for my wife’s iPhone is returned.

the limitation of the get entity node, effectively you can select only one attribute, because if you add more than one condition, all conditions has to be true in order to find all entities with battery level. You can use multiple nodes, one node for each battery related attribute and as @Hellis81 said, merge them with a join node. I come up with something like this but at this stage I am not sure this is less convoluted then what you started with :confused:

[{"id":"9069d6c7.4ef798","type":"ha-get-entities","z":"110b2c7b.9890f4","server":"e447d17a.16a64","name":"","rules":[{"property":"attributes.battery","logic":"lte","value":"100","valueType":"num"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":470,"y":40,"wires":[["5d0b09ab.3a5ac8"]]},{"id":"bc834f66.86fe6","type":"inject","z":"110b2c7b.9890f4","name":"","props":[{"p":"payload.Email","v":"Serkan","vt":"str"},{"p":"payload.Passwd","v":"F%6rt815","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":250,"y":100,"wires":[["9069d6c7.4ef798","664d9c5.1693964","d0d1cb11.4c82f8"]]},{"id":"7fbc374b.696678","type":"debug","z":"110b2c7b.9890f4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"data","targetType":"msg","statusVal":"","statusType":"auto","x":1020,"y":80,"wires":[]},{"id":"664d9c5.1693964","type":"ha-get-entities","z":"110b2c7b.9890f4","server":"e447d17a.16a64","name":"","rules":[{"property":"attributes.Battery Level","logic":"lte","value":"100","valueType":"num"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":470,"y":100,"wires":[["119ec94e.e72e37"]]},{"id":"d0d1cb11.4c82f8","type":"ha-get-entities","z":"110b2c7b.9890f4","server":"e447d17a.16a64","name":"","rules":[{"property":"attributes.battery_level","logic":"lte","value":"100","valueType":"num"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":470,"y":140,"wires":[["3b99c169.cdffce"]]},{"id":"5d0b09ab.3a5ac8","type":"split","z":"110b2c7b.9890f4","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":630,"y":40,"wires":[["dbf649cf.f4ac58"]]},{"id":"dbf649cf.f4ac58","type":"change","z":"110b2c7b.9890f4","name":"","rules":[{"t":"set","p":"data","pt":"msg","to":"{payload.entity_id: payload.attributes.battery}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":40,"wires":[["7fbc374b.696678"]]},{"id":"119ec94e.e72e37","type":"split","z":"110b2c7b.9890f4","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":630,"y":100,"wires":[["963daf17.f3b32"]]},{"id":"963daf17.f3b32","type":"change","z":"110b2c7b.9890f4","name":"","rules":[{"t":"set","p":"data","pt":"msg","to":"{payload.entity_id: payload.attributes.[\"Battery Level\"]}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":100,"wires":[["7fbc374b.696678"]]},{"id":"3b99c169.cdffce","type":"split","z":"110b2c7b.9890f4","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":630,"y":140,"wires":[["555c80f0.760f5"]]},{"id":"555c80f0.760f5","type":"change","z":"110b2c7b.9890f4","name":"","rules":[{"t":"set","p":"data","pt":"msg","to":"{payload.entity_id: payload.attributes.battery_level}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":140,"wires":[["7fbc374b.696678"]]},{"id":"e447d17a.16a64","type":"server","z":"","name":"Home Assistant","legacy":false,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":false,"cacheJson":true}]

above produces 13 messages for me.

That wasn’t what I meant.
I meant you have one function node with something like:

msg.arr = [sensor.something.attributes.battery, sensor.somethingElse.attributes.batterylevel, sensor.andAnother.attributes.battery_level];

If the array is not set when the message gets there.
Then you array pop to get one value at the time and feed that to next node that gets the state.
The message loops back to the function node again and the array is one item shorter.
You pop again and feed in to the loop until the array is empty.

So essentially the sequence is in one line but with a loop back to get another item from the array.

You can change the comparison type to JSONata and use something like

$entity().attributes.battery_level < 50 or $entity().attributes.batterylevel < 50 or $entity().attributes.someotherproperty < 50
2 Likes

@Kermit, I tried your suggestion, but it din’t get me any further. This is my small test flow:

[{"id":"1ab4d156.c6965f","type":"ha-get-entities","z":"3abd6ec5.999042","server":"15c5ca8b.7ac0c5","name":"","rules":[{"property":"","logic":"jsonata","value":"$entity().attributes.battery_level < 100","valueType":"jsonata"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":390,"y":260,"wires":[["8271d95d.d0a6a8"]]},{"id":"8271d95d.d0a6a8","type":"debug","z":"3abd6ec5.999042","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":610,"y":260,"wires":[]},{"id":"829f8c6d.829ad","type":"inject","z":"3abd6ec5.999042","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":220,"y":260,"wires":[["1ab4d156.c6965f"]]},{"id":"15c5ca8b.7ac0c5","type":"server","z":"","name":"Home Assistant","legacy":false,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]

The result after manual trigger , is;

10/1/2020, 6:05:20 PMnode: 8271d95d.d0a6a8
msg.payload : array[1]
  array[1]
  0: object
     entity_id: "device_tracker.iphone_se"
     state: "home"
     attributes: object
        source_type: "gps"
        battery_level: 60
        latitude: 59.92833706650565
        longitude: 10.710182539863737
        gps_accuracy: 65
        altitude: 60.89334487915039
        vertical_accuracy: 10
        friendly_name: "iPhone-SE"
     last_changed: "2020-09-30T17:50:43.619867+00:00"
     last_updated: "2020-09-30T17:50:43.619867+00:00"
     context: object
        id: "763beedb034511eb8cb63d5ed06c3dd9"
        parent_id: null
        user_id: null
     timeSinceChangedMs: 80075195

Adding a second property to the JSONata changes nothing - as if only the first one is parsed.

The autocompleted list of all properties currently set on all loaded HA entities, there’s only four properties with match on the word “battery”:

attributes.Battery Level
attributes.Battery State
attributes.battery_health
attributes.battery_level

Again, why my wife’s iPhone shows up as the only hit, is a mystery to me.
If I use the other property attributes.Battery Level, I have to add double quotes to avoid an error message, because of the white space ;

$entity().attributes."Battery Level" < 100

Then the output is:

10/1/2020, 6:22:03 PMnode: 8271d95d.d0a6a8
msg.payload : array[1]
array[1]
0: object
  entity_id: "sensor.ewa_sin_iphone_battery_state"
  state: "Not Charging"
  attributes: object
    Battery Level: 55
    Low Power Mode: false
    friendly_name: "Ewa sin iPhone Battery State"
    icon: "mdi:battery-50"
    device_class: "battery"
  last_changed: "2020-09-30T17:50:43.504224+00:00"
  last_updated: "2020-09-30T17:50:43.504224+00:00"
  context: object
    id: "762a49f3034511eba52fa739efc02cf5"
    parent_id: null
    user_id: null
  timeSinceChangedMs: 81077659

Again, it’s only the property of the iPhone that is matched. All my other battery powered devices remains in the dark… :sleepy: