[SOLVED] OpenHAB3 / Turn off all lights / How to use the semantic model to (easily) turn off all the lights?

Hi,

I am new to OpenHAB and started to work with version 3.

I struggle with a few things and unfortunately I am a bit confused on which instructions still work for OH3 and which don’t. I’ll post separate questions for each of my problems.

This question is about Semantic Model Usage.

Problem / Goal:

The documentation mentions that with the semantic model it should now easily be possible to “turn off all the lights” in whatever location.

Unfortunately, I could not find out how this can be achieved exactly.

What I would expect:
Have a button “Turn Off All Lights” or something similar with which I could simply trigger that all items of semantic type “light” are turned off.

Posts I read so far:


Platform information:

  • OS: ArchLinux
  • openHAB version: 3.0.0-2

I’m only just making my way in OH3 myself, but this is all about groups.

If you structure the lighting into groups you can configure OH to turn off all members within a group when you turn off the group itself.

In terms of the button, there are multiple ways to do this, through sitemaps, the new UI (I haven’t got that far yet) or through Alexa or similar notifications.

I have two sets of lights in my office, down lights and wall lights. Both are members of the group “Office Lights”. When I tell OH (usually through Alexa) to turn on/off the office lights, both sets will turn on or off.

Thanks

Hi @diddie17,

thank you for your answer.

The thing is that I don’t want to introduce additional groups. I’d rather just use the semantic information which is already there.
For example OH already knows what items are lights and those are properly shown e.g. under Home >> Equipment >> Lights.

I just want to re-use that information and work with it.

I did some further digging.
In the demo environment I found a rule which seem to work with light equipment. Unfortunately, it is not working for me either. :pensive: Not sure why though.

    configuration:
      type: application/vnd.openhab.dsl.rule
      script: |
        Lights?.members.forEach(light|
        	postUpdate(light, OFF)
        )

What happens if you try with sendCommand(light, OFF) instead?

Yes, I already tried that as well. Sorry, forgot to mention that.

It generally doesn’t seem to work.
I introduced a new dummy switch item all_lights_off and once the state toggles to ON it should trigger the rule.
In order to check if anything happens at all I tried to update the all_lights_off state to OFF again but that also doesn’t work.

triggers:
  - id: "0"
    configuration:
      itemName: all_lights_off
      state: ON
    type: core.ItemStateUpdateTrigger
conditions: []
actions:
  - inputs: {}
    id: script
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: |
        postUpdate(all_lights_off, OFF)
        Lights?.members.forEach(light|
        	//postUpdate(light, OFF)
            sendCommand(light, OFF)
        )
    type: script.ScriptAction

edit:
It works if I remove the lights thingy.

triggers:
  - id: "0"
    configuration:
      itemName: all_lights_off
      state: ON
    type: core.ItemStateUpdateTrigger
conditions: []
actions:
  - inputs: {}
    id: script
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: |
        postUpdate(all_lights_off, OFF)
    type: script.ScriptAction

I assume that the

        Lights?.members.forEach(light|
            postUpdate(light, OFF)
        )

simply doesn’t work for whatever reason.

I am afraid you are right. :pensive:

In the demo there is indeed a group which is called Lights


… and then you can probably work with <group-name>?.members.forEach loops.

This is very sad. I had hoped that I could just use the semantic information which is already there.

You shouldn’t need to work through the group members, the power of the groups means that you can just turn on or off the group with a command like -

events.postUpdate("Lights", "OFF");

Having groups mans that you can have an “OfficeLights” group inside a “DownstairsLights” group inside an “AllLights” group and choose which one of those you turn on or off, just by turning on or off the group. No need to work through the members.

You can of course still turn off each of the individual lights by sending a command directly to it.

You can get a view of how I think the developers envisioned the model working through this tutorial - Semantic Model

I think the point is that these groups would be in addition to those that you would have in your Semantic Model, because these groups themselves wouldn’t usually live within the Semantic Model.

So extra groups have to be created over and above the ones in the Semantic Model to control all the lights, which is what the OP is trying to avoid.

Maybe this is useful?

Basically, you can grab all Items with a specific tag…

1 Like

Yes, indeed!
This was very helpful. :+1:

I now ended up with the following ECMA rule:

triggers: []
conditions: []
actions:
  - inputs: {}
    id: "1"
    configuration:
      type: application/javascript
      script: |
        var items = itemRegistry.getItemsByTag("Light");
        for (var i in items) {
          var light = items[i];
         
          var state = light.getState();
          if (light.type == "Color") {
            // We need to remap HSB value to ON / OFF
            state = state.brightness > 0 ? "ON" : "OFF";
          }

          if (state == "ON") {
            events.sendCommand(light.getName(), OFF);
          }
        }
    type: script.ScriptAction

Unfortunately, I couldn’t figure out yet how to translate this into a DSL rule.

An alternative approach could be to run a rule which automatically assigns all the items to the corresponding dummy groups and stick with the additional groups.

# 'gRoot' is representing the root group which contains all items


# Iterate over all items of the root group including those of sub groups
gRoot?.allMembers.forEach[item |    

  # Verify whether item is tagged as light                                     
  if (item.tags.contains("Light")) {
    # Add to "lights" group
    gLights.addMember(item)
  }
]

That way one could still work with gLigths.sendCommand(OFF) / gLigths.sendCommand(ON) .

I tried to run your ECMA rule but hit an error,


2021-05-26 05:44:43.827 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'b0b9f4f087' failed: <eval>:4:10 Expected ; but found :
  - inputs: {}
          ^ in <eval> at line number 4 at column number 10

Any idea what is wrong?