Javascript to fast?


I have a rule which is triggered by a received command on an item and then it triggers a javascript script. Within the javascript I pull the same item as which received the command, but the state is sometimes the previous state. If I add a small sleep of just 10ms it always has the triggered/new state. Are those two components, the trigger and the pulling of the state async?

configuration: {}
  - id: "1"
      itemName: object_master_switch_action
    type: core.ItemCommandTrigger
conditions: []
  - inputs: {}
    id: "3"
      type: application/javascript;version=ECMAScript-2021
      script: |-
        var action = items.getItem("object_master_switch_action");
        console.log('Received command', action.state);
    type: script.ScriptAction

EDIT: And here’s the proof, without the sleep:

2023-11-14 11:04:04.929 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'object_master_switch_action' received command 0
2023-11-14 11:04:04.929 [INFO ] [nhab.automation.script.ui.d4fe83c7ae] - Received command. 1
2023-11-14 11:04:04.930 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'object_master_switch_action' changed from 1 to 0

You can see the javascript console.log() is triggered before the eventbus is changed from 1 to 0.

Kind regards,

That’s by design, as item change and rules running independent.
Use the implicit variables, that are available for this case, instead

1 Like

Yes and I want to elaborate a little on @Matze0211’s answer.

A command never changes the state of an Item. Sometimes the command doesn’t even look anything like the state of the Item (e.g. sending INCREASE as a command to a Dimmer Item).

The state of an Item only changes through an update.

By default there is a service called “autoupdate” which when it gets a command predicts what the new state of the Item will be after processing the command and update the Item based on that prediction (you can see this happening in events.log. Autoupdate can be turned off through Item metadata. When autoupdate is off, a command will not result in the Item changing state. It will require the binding (assuming it’s linked) or some rule to change the state of the Item with an update.

For devices that report back the state of the device after processing a command, it’s often best to disable autoupdate. Then the Item will only reflect the true state of the device, not what autoupdated predicted the state should be.

In addition, there is nothing preventing the state of the Item that triggered the rule from changing while the rule is running regardless of whether the rule was triggered with a command, update, or changed.

For these reasons you should never rely on the state of the Item that triggered the rule inside the rule (with some exceptions of course). Instead you should rely on the event Object.

console.log('Received command', event.receivedCommand);

I never realized this. I just assumed that because a rule is triggered by a state change this new state is already available to items.getItem();

I will change my scripts to start using the event object and/or the implicit variables.

1 Like

It is. But you triggered on received command, not Item changed.

But even then there is no guaranteed that it hasn’t changed again since then.

Just to iterate over them:

Trigger What happened
received command Item has not changed state yet, the command has gone out to the binding.
changed Item has actually changed
updated Item’s state has been updated but it has not necessarily changed state

So a command can result in an additional update and change, but not necessarily. A change is always corollated with an update.

Ah I see, now I get it. Thanks again!