[Solved] Issue with matchEntities() in Expression using groups key for Dynamic Group
-
Following the docs:
In expressions; dynamic groups can be referred to in the groups key of the matchEntities() function, or by passing the group's canonical ID to getEntity(). The former is probably preferable, as it's much easier to read and understand what is going on.
Example in docs:each e in matchEntities({group:'groups>low_battery_entities'}): e.name each id in getEntity('groups>low_battery_entities').attributes.sys_group.members: getEntity( id ).name
I set up a Dynamic group:
- id: groups name: Dynamic Group Controller enable: true implementation: DynamicGroupController config: groups: "EzloDevicesNotResponding2": name: Ezlo Devices Not Responding select: - include_controller: ezlo - include_capability: x_ezlo_device filter_expression: entity.attributes.x_ezlo_device.reachable != true
But when I try the Expression I get a compilation error
Log:
[latest-22004]2022-01-09T12:24:35.420Z <Engine:NOTICE> [Engine]Engine#1 expression testing has changed; recomputing dependencies [latest-22004]2022-01-09T12:24:35.421Z <Engine:ERR> [Engine]Engine#1: error evaluating expression testing: [ReferenceError]ReferenceError: Invalid reference to member name of ezlo>device_61baf610129e0725bd9f80f3 [latest-22004]2022-01-09T12:24:35.422Z <Engine:ERR> [Engine]Engine#1: expression: each e in matchEntities({group:'groups>EzloDevicesNotResponding2'}): e.name [latest-22004]2022-01-09T12:24:35.422Z <Engine:5:Engine.js:960> [Engine]Engine#1: path testing->testing [latest-22004]2022-01-09T12:24:35.422Z <Engine:CRIT> ReferenceError: Invalid reference to member name of ezlo>device_61baf610129e0725bd9f80f3 ReferenceError: Invalid reference to member name of ezlo>device_61baf610129e0725bd9f80f3 at _run (/home/homebridge/reactor/common/lexp.js:1411:31) at _run (/home/homebridge/reactor/common/lexp.js:1514:41) at /home/homebridge/reactor/common/lexp.js:1246:29 at Array.forEach (<anonymous>) at _run (/home/homebridge/reactor/common/lexp.js:1245:28) at run (/home/homebridge/reactor/common/lexp.js:1609:22) at Object.evaluate (/home/homebridge/reactor/common/lexp.js:1645:20) at Engine._eval_expr (/home/homebridge/reactor/server/lib/Engine.js:958:280) at Engine.notify (/home/homebridge/reactor/server/lib/Engine.js:644:142) at /home/homebridge/reactor/server/lib/MessageBus.js:106:223 [latest-22004]2022-01-09T12:24:35.424Z <Engine:5:Engine.js:1000> [Engine]Engine#1 set global testing; value=(object)(null)
When not referring to
e.name
It's an array with three memberslatest-22004-6d6c6b7 bare metal installation.
What I'm I doing wrong?
-
matchEntities()
returns a list (array) of canonical IDs, not entity objects. You need:each id in matchEntities({group:'groups>low_battery_entities'}): getEntity( id ).name
-
This is the example in the docs. I'm not seeing any issue here:
sensors = matchEntities( { controller: 'vera', capability: [ 'binary_sensor', 'value_sensor' ] } ) low_battery = each e in sensors: getEntity( e ).attributes.battery_power?.level < 0.5 ? e : null
sensors
is handled as an array of canonical IDs by the second expression. Is there another place in the docs you are referring to that I'm not thinking of? -
OK. I was looking at the Expressions docs.
Edit: changes will make their way into the next release, along with strong messaging that dynamic groups should be used in preference to
matchEntities()
for group filtering (you can still use it to get the group members, but let DynamicGroupController do the hard work). DGC is much more efficient (and flexible) in its filtering, by design. -
Confusing. The only way to get the name (currently) is through
getEntity()
. Thedo...done
statement doesn't enter into it; it's just a language construction that may or may not be needed in the expression as written. I think you're thinking ofeach...in
, which is how you iterate over an array, so yes, if you have an array of entity IDs, you'll needeach...in
andgetEntity()
together to make a list of them. -
Sorry for assuming you remember every post you ever made
I was referring to this excellent advice
I guess it’s not necessary when I only do one getEntity for the name. -
Ah, yes... if you need to reuse the fetched entity several times, it's definitely better to use a
do...done
block as the loop body and keep the result ofgetEntity()
in a local variable, so you're only doing that fetch one time. You can then use the local variable as many times as needed... a cache of sorts. I'm with you...