Odd behaviour of switch item state in rule triggered by received command

Hi all,
I have made a ‘dummy’ switch, which I use to control christmas lights via a python script. Unfortunately, there seems to be a delay in when the switch state is executed and when the rule for the command is executed that I’m trying to figure it out. I have several other similar switches, and hadn’t noticed this behaviour before, but I don’t think I often reference the command in the body of the rule without it having been specified in the rule header.

My rule triggers on any received command, and then the rule checks the state of the switch. If ON, then it sends the command "ON’ via the python script, and otherwise it sends the command OFF.

My rule is below. Item twinklyTree is a switch.

rule "Twinkly Christmas Tree Power State"
when 
  Item twinklyTree received command
then
  if (twinklyTree.state == ON) {
    executeCommandLine("python3 twinkly.py 192.168.0.209 on")  // turn the christmas tree on
  }
  else {
    executeCommandLine("python3 twinkly.py 192.168.0.209 off")  // turn the christmas tree off
  }
end

The problem is that when I use twinklyTree.sendCommand(ON), sometimes the rule sends the command ON, and sometimes OFF (alternates).

Attempt#1, Tree lights are currently off, sending twinklyTree.sendCommand(ON)


2020-12-18 08:25:54.741 [INFO ] [.smarthome.model.script.lights.rules] - Scene 4x Up

2020-12-18 08:25:54.766 [ome.event.ItemCommandEvent] - Item 'twinklyTree' received command ON

==> /var/log/openhab2/openhab.log <==

2020-12-18 08:25:54.776 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'python3 twinkly.py 192.168.0.209 off'

Lights did NOT come on, as can be expected from the above python line actually sent.

Attempt#2, Tree lights still off, sending twinklyTree.sendCommand(ON), again.

2020-12-18 08:26:03.172 [INFO ] [.smarthome.model.script.lights.rules] - Scene 4x Up

2020-12-18 08:26:03.196 [ome.event.ItemCommandEvent] - Item 'twinklyTree' received command ON

==> /var/log/openhab2/openhab.log <==

2020-12-18 08:26:03.205 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'python3 twinkly.py 192.168.0.209 on'

I’m guessing that when used within the rule, twinklyTree.state is referring to the value of twinklyTree BEFORE the command has been fully processed and the state changed to the new value. Is there a way of reliably referencing the new value, without having to make two separate rules (ie, item twinklyTree received command ON and … received command OFF)?
Is there something else at play here?

For what it’s worth, the same behaviour happens when trying to turn the lights off. I had never noticed this before as I had been using a simple pushbutton to toggle the lights, and it would reliably change the state every time it was pressed (and the kids pressed it a lot). Only now am I able to see that my routine AM and PM rules aren’t being followed, prompting me to look into this further.

Thanks in advance for the anticipated rule lesson (I’m aware there is a new rule system with openhab3, but given that everything else is working and my system is somewhat complex with lots of scripted rules, I don’t have the energy to pull the plug and make the switch yet)

Ben

Openhab 2.5 on Openhabian on a RPi 4.

Thanks @rlkoshak. The corrected rule is:

rule "Twinkly Christmas Tree Power State"
when 
  Item twinklyTree received command
then
  if (receivedCommand == ON) {
    executeCommandLine("python3 twinkly.py 192.168.0.209 on")  // turn the christmas tree on
  }
  else {
    executeCommandLine("python3 twinkly.py 192.168.0.209 off")  // turn the christmas tree off
  }
end

A command is not a state. When an Item receives a command a whole bunch of stuff happens in parallel:

  • Bindings linked to the Item are informed of the command and sends the command out to the device
  • If autoupdate=true (the default setting), the autoupdate feature attempts to predict what state the Item will become in response to the command and update the Item to that state.
  • If autoupdate=false, the binding will wait for confirmation back from the device that it became the new state in response to the command and update the Item as appropriate.
  • Rules that are triggered by received command are triggered

Notice, there’s a bunch of stuff that has to happen before the Item changes state in response to the command. In the mean time, even before the Item changed state, the rule was triggered and run. In the few milliseconds between the rule starting to run and if(twinklyTree.state == ON) executes it is highly unlikely that the Item has changes state to ON in response to the ON command.

That’s why the receivedCommand implicit variable exists. https://www.openhab.org/docs/configuration/rules-dsl.html#implicit-variables-inside-the-execution-block You can’t rely on the state of the Item yet in that rule because you don’t know how long it will take for the Item’s state to update, but you can see what the command that triggered the rule was.

if(receivedCommand == ON) {

This is an important concept to understand. There are many commands that don’t correspond to a state. For example, INCREASE/DECREASE on a Dimmer Item.

If you need the Item to reach it’s new state before running the rule, use a changed or received update trigger instead.

The above applies to OH 3 rules too.

4 Likes