OH3 MainUI-rule condition: only if all members are ON

Hi there!

i have the below rule and i want to execute the action only if all members from “g_homies” are ON. So i have written the DSL script condition:

g_homies.members.filter[ i | i.state == OFF].forEach[i | return false ]

but it doesent work. The function itself works fine in a separate script.
Here is the complete rule:

configuration: {}
  - id: "1"
      thingUID: astro:sun:local
      channelUID: astro:sun:local:civilDawn#event
    type: core.ChannelEventTrigger
  - id: "2"
      thingUID: astro:sun:local
      channelUID: astro:sun:local:daylight#event
    type: core.ChannelEventTrigger
  - id: "7"
      groupName: g_homies
      state: ON
    type: core.GroupStateChangeTrigger
  - inputs: {}
    id: "3"
      itemName: Lokale_Sonnenphase
      state: DAYLIGHT
      operator: =
    type: core.ItemStateCondition
  - inputs: {}
    id: "8"
      itemName: Gast_mode
      state: ON
      operator: "!="
    type: core.ItemStateCondition
  - inputs: {}
    id: "4"
    label: all members are online
      type: application/vnd.openhab.dsl.rule
      script: g_homies.members.filter[ i | i.state == OFF].forEach[i | return false ]
    type: script.ScriptCondition
  - inputs: {}
    id: "5"
      considerConditions: true
        - e5136251c7
    type: core.RunRuleAction

Get the Group to do the work, with aggregation function AND for ON.

As an aside, note that not-OFF is not the same as ON, since other states like UNDEF may be encountered.

1 Like

in my case it is not possible, because th group is already on if only one person is ON. but the rule should only execute the action if all users are ON

You can add a second non semantic groups with „all on equals on“ and add the members to it.

yes, i could, but it’s too confusing for me. can’t i do it somehow with the above rule?

You could also put all items in a „Count:OFF“ group via expert settings and create your rule to react on state less than number of items and greater than 0 and the second rule to trigger at state 0.

If you can’t or don’t want to use one of the Group aggregation functions then your only choice is to use a Script Condition and go through the members to see if they are all on, which appears to be what you are trying to do. But you can’t use a return statement like that in a Script Condition. It’s designed to take the what ever the last line of the script evaluates to as the return value. Therefore that last line needs to evaluate to a boolean.

g_homies.members.filter[ i | i.state != ON ].size == 0

That evaluates to false is one or more members are not ON and true if they are all ON.

thanks @all and @rlkoshak! that´s what i want :slight_smile:

@rlkoshak please can you tell me, how i find out which methods a function has?
i mean the “.size” or “.members” or “.allMembers” and so on …

Any time you touch on something from openHAB itself (Group, Item, Action, etc.) you are working with the core Java Objects even though your rule is written in some other language (in this case Rules DSL.

So looking at the openHAB Java Docs for Group Item: GroupItem (openHAB Core 3.3.0-SNAPSHOT API)

We see that getMembers() returns a Set<Item>. You can even click on that and it will take you to the doc for Set which shows all the methods available to you.

One place where it gets a little weird though is that Xtend, the base language for Rules DSL provides a bunch of wrappers around the core Java Collection Classes to make interacting with the Java Collections Stream API a little easier. Unfortunately that stuff really isn’t documented well by Xtend even which is why I wrote Design Pattern: Working with Groups in Rules.

Note: in some of the rules languages like JS Scripting and jRuby, a pure native abstraction layer is provided so that you never have to mess with the Java stuff directly. In these cases, if you look at the reference docs for the add-on and just generic references for the language you will get everything you need.