[SOLVED] Reducing the impact of turning off MANY lights? How to optimise

Is there some documentation on this because I dont understand.

I assume I need an && for SwitchItem and DimmerItem. Not sure where you’re getting the not from, do you mean

SwitchItem && DimmerItem && !GroupItem?

No, I mean given you get three possible types and you want two of them; an alternative way to express the logic is that you want to test the target is NOT of the other type. Not-instanceOf.

...filter[Lights | Lights !instanceof GroupItem && Lights.state==ON]...

I think the next obstacle you will run into is that Dimmer types states are numeric, not ON. You could overcome that by casting to OnOffType, a kind of conversion.

Ah!

If I look at the Items for Switch/Dimmer, both of them are part of gAllLights, so if I ignore the Dimmer type also and just match the SwitchItem, that should turn it off (irrespective of if its a dimmer or switch)

But, that should mean my rule as it is should work!

Uh, I think you have lost sight of your objective - only sending commands to lights that are actually ON, not to all members of a Group.

Just to be clear, if you send a command to a Group it will regenerate that same command to every member, regardless of state or type. You cannot control that in any way, apart from not doing it to begin with.

Correct, so, why does instanceof SwitchItem not work?

Objective: Send an OFF command to every item of the group that is a Switch with the state ON. Without flooding off commands to stuff that’s not on

To me, the below does that? but clearly doesnt.

rule "Turn off all Lights"
when
        Item Proxy_gAllLights received command OFF
then
          gAllLights?.allMembers.filter[Lights | instanceof SwitchItem && Lights.state==ON].forEach[ LightsON |
               LightsON.sendCommand(OFF)
               logInfo("alloff","Item {} is set to OFF from {}",LightsON.name,LightsON.state)
          ]
end

Right. So you’re saying no matter what I do, the event log would be flooded with OFF commands irrespective of the filter?

Because it is incomplete. What is an instance of SwitchItem?
Once again, in this situation, the complete statement is
Lights instanceOf SwitchItem

But as discussed that won’t work because it will ignore Dimmer types as well as Group types it finds among the “top” group’s members.

No, this what the filtering is about. In the first version of the rule, we used the filter only to find things that are ON.
But as you have some things that are Groups that can also be ON, we have to miss those out as well.
And now there are Dimmers, which aren’t ON but 55% in their basic state.

It might be more comprehensible writing it out longhand, and doesn’t take much more processing.

gAllLights?.allMembers.forEach[ someItem |
      if (someItem instanceOf SwitchItem && someItem.state == ON) {
         someItem.sendCommand(OFF)
      } else if (someItem instanceOf DimmerItem && someItem.state > 0) {
         someItem.sendCommand(OFF)
      } //else if any other type we do nothing
]
1 Like

Now that makes far more sense to me!!!

So:


rule "Turn off all Lights"
when
        Item Proxy_gAllLights received command OFF
then
        gAllLights?.allMembers.forEach[ AllLights |
      if (AllLights instanceOf SwitchItem && AllLights.state == ON) {
         AllLights.sendCommand(OFF)
      } else if (AllDimmers instanceOf DimmerItem && AllDimmers.state > 0) {
         AllDimmers.sendCommand(OFF)
      } //else if any other type we do nothing
]
end

My point before was that a Light and a Dimmer is the same device, just a different type, ie if you turn off the Switch item, it turns off the Dimmer item. So technically, only the first if is needed right?

I don’t know what that means. Your devices are each represented by pairs of Items of different types?

Sure, see my example:

/*ZWave Dimmer 2 Movie Stair Lights*/
Switch Movie_Stairs_Sw1     "Movie Stair Lights"                             (gFamilyLights,gLivingLights)             { channel="zwave:device:6dad8bea:node171:switch_dimmer1" }
Dimmer Movie_Stairs_Dimmer1 "Movie Stair Lights"                             (gLivingDimmers)                          { channel="zwave:device:6dad8bea:node171:switch_dimmer1", alexa="PowerController.powerState,BrightnessController.brightness" }
Number Movie_Stairs_Num1    "Movie Stair - Current Consumption [%.1f W]"     (gAllLightsUsage,gEnergyRealTime)         { channel="zwave:device:6dad8bea:node171:meter_watts1" }
Number Movie_Stairs_Num2    "Movie Stair - Usage [%.1f kW]"                  (gPowerUsage)                             { channel="zwave:device:6dad8bea:node171:meter_kwh1" }

Well, you have full control over what the rule does, and the membership of the groups it acts on, it’s time to make what you want.

1 Like

Why defining two items for the same channel? This is crap! You can use the Dimmer Item as a switch, too.

I can’t see any command from the rule to any group in the logs, so the rule can’t do the wrong commands here.

If you want to use a Dimmer state as OnOffType, you could do it like this:

rule "Turn off all Lights"
when
    Item proxyAllLights received command OFF
then
    gAllLights?.allMembers.filter[Lights | !(Lights instanceof GroupItem) && Lights.getStateAs(OnOffType) == ON ].forEach[ LightsON |
        LightsON.sendCommand(OFF)
    ]
end

Please take note of the different boolean not - there is no “not instanceof” but only an “instanceof”, so you have to negate the term instead (this is why I use brackets)

1 Like

Group command concern arises from that.

Yes, but not from the script… :wink:

[clipse.smarthome.model.script.alloff]

I had to because in my habpanel code, it dynamically populates the lights from a group, and the item.type I could only get working as a Switch

as per this:

<div class="widget" ng-if="item.type=='Switch' && itemValue(item.name)=='ON'" ng-click="sendCmd(item.name, 'OFF')">

I have a mix of switches and dimmers, so for this to work I’d need to have

 item.type=='Switch' && item.type=='Dimmer' && itemValue=(item.name=='ON'

" but i couldnt get it to function :frowning:

No, you need a different version:

 (Lights instanceof SwitchItem || Lights instanceof  DimmerItem) && Lights.state == ON

An Item can’t be Switch and Dimmer the same time :wink:

1 Like

Sorry, I mean in my HabPanel code (not the rule code you’re speaking of). The rule works, I just need to try and remove the duplicate switch items for each dimmer device but display both in my habpanel code (as not every light is a dimmer)

Ah, sorry, didn’t get this point. I don’t use HABpanel (yet), so unfortunatley I can’t help here.

No trouble! Looks like I spoke too soon.

I went ahead and removed the nested groups , by adding my switches & dimmer items into ‘gAllLights’ for simplicity

The rule however still sends commands of OFF to all lights :frowning:


rule "Turn off all lights"
when
        Item gAllLights received command OFF
then
        gAllLights?.allMembers.forEach[ AllLights |
      if (AllLights instanceof SwitchItem && AllLights.state == ON) {
         AllLights.sendCommand(OFF)
      } else if (AllLights instanceof DimmerItem && AllLights.state > 0) {
         AllLights.sendCommand(OFF)
      } //else if any other type we do nothing
]
end

Yes because you send the command to the group, openHAB will cascade the command to members.
OpenHAB does that REGARDLESS there is a rule for that trigger or not.

Understood, so the proxy solution is the only option for the rule trigger

rule "Turn off all lights"
when
        Item Proxy_gAllLights received command OFF
then
        gAllLights?.allMembers.forEach[ AllLights |
      if (AllLights instanceof SwitchItem && AllLights.state == ON) {
         AllLights.sendCommand(OFF)
      } else if (AllLights instanceof DimmerItem && AllLights.state > 0) {
         AllLights.sendCommand(OFF)
      } //else if any other type we do nothing
]
end