Success or failure of a sendCommand - jython rules

I have made significant progress in my transition from SmartThings to OH3. Can’t thank the community enough for creating and maintaining this system! I only have a few devices left to convert before I can toss the ST hub out :slight_smile:

In my system I have implemented support for OhmConnect’s OhmHour in which they ask customers to shutdown devices to save electricity during certain times (they pay a small amount of money for your efforts) … anyway, in my rules I have files for each room and each one contains a rule for “OhmTime” where I can take actions to turn off the room devices that I want.

So when the OhmTime switch changes to ON, a rule in each room runs and turns OFF various devices.

The problem: Sometimes, the Item gets the command but doesn’t actually change. ie. I perform a sendCommand to an Item (say a TV Power), but the TV does not shut off. In the logs I see that the item command is received and it is “predicted to change” etc. But it doesn’t actually change.

Obviously many things could be going wrong and I’m not looking for specific help debugging this.

My question: I was considering putting in confirmations that an Item reached the state that I had requested. I am concerned this will create blocking code and likely slow the system down. Alternatively, maybe a small sleep() would solve this, although that’s more of a hack.

Another idea I had was to dynamically build the list of devices and commands that I want to send, then have a function that iterates through the final list until each of the devices is confirmed to have changed to the desired state.

Is there a better approach (i.e. simpler) to confirm that an Item has reached its desired state?

Show the logs for this.

When looking at these events though make sure you understand what is going on. There is a feature that is turned on by default for Items called “Autoupdate”. That’s the thing that is making those predictions. With Autoupdate turned on the Item’s state will usually go through something like this.

  1. command received
  2. autoupdate predicts the new Item state the command will result in
  3. autoupdate updates the Item to this new state (you won’t see that in event.logs)
  4. after the device changes to the new state, the binding will update the Item with the new state

Both step 3 and 4 results in an update to the Item.

Here is what happens when autoupdate is turned off.

  1. command received
  2. after the device changes to the new state, the binding will update the Item with the new state

Obviously it could be quite some time between 1 and 2 in this case and if there was an error, 2 may never occur meaning your Item never changes state in response to the command.

This is important to address your specific problem.

Sort of. You can block until the Item changes state (assuming autoupdate is OFF so you know from the binding that the Item actually changed state and it’s not just autoupdate predicting it) and that will block that one rule but it won’t slow the system down over all. Subsequent commands after that block will be delayed and that rule won’t be allowed to trigger again until it exits but that’s it. That may not matter.

To avoid the blocking you can put the checking and recommanding into a Timer which won’t block things but becomes a tiny bit more complicated.

But in both cases you need to make sure to account for the case where the device never changes state because of some error. There has to be a maximum amount of time to wait.

1 Like
createTimer(now.plusSeconds(5)) [ |
    if(SomeItem.state != "active") {
       // take some action
       // maybe a retry and reschedule
     } ]

You’ll probably want to disable autoupdate on some Items to see true status.

1 Like

Thanks @rossko57 and @rlkoshak … so a few follow ups …

  1. Regardless of whether Autoupdate is on or off, because of an error, the device may not actually change states. Given that, I would need to add some sort of check (i can do this no problem).

  2. In the UI, for the Auto Update metadata, it has “Force auto-update” with a Dash, I assume this means it is not definitively set … when I click on it, I can turn it off, or click to turn it on. But you say all items have this Autoupdate ON by default, correct? (even though it shows as a Dash) …

  3. So, basically what I am getting from both of you is that the Item (and its binding ) should normally eventually change to the correct state, unless an error occurred (which could be for various reasons) … so when I absolutely need to know the Binding has actually changed states, Autoupdate should be ON and I will need to check for errors.

Do I have this right? If so, perhaps I should have a low level function that handles cases where the device must change to the correct state and handles delays and retries etc… obviously it may still fail and so that would be a fatal error (logged etc) … is this something everyone does for cases where a device change needs to be confirmed?

Really it has three states. “Default” or “not set” is distinct from both disabled and forced. Default is effectively enabled in most cases. If you wish to disable, you must disable (each Item).

For fuller autoupdate understanding

1 Like
  1. Correct, you’d need some sort of check if the binding doesn’t report back the new state, or the device failed to change state. Note that there is a special REFRESH command you can send to an Item that will cause some bindings to poll the device for its current state. But if autoupdate is on you may be happily unaware that the device never turned off. Autoupdate predicted the device would turn off and it updated the Item with that prediction. If there was an error the binding may never come back and update the Item to show that the device didn’t in fact turn off.
    So again, as we’ve both recommended, you should probably turn off autoupdate.

  2. Sort of. Some binding can provide their own suggestion for how autoupdate behaves. You can override that which is what I think the force option is.

  3. It really depends on the technology and the binding. For example, 433MHz technologies typically don’t report back anything ever. Un-linked Items won’t ever update in response to a command with autoupdate turned off. But if the technology supports it, or you have some other way to determine the state of the device, that should eventually report back the new state of the device. How long that takes depends on the technology involved and settings.
    And you have it backwards. If you do not want the Item to update until the device has actually changed in response to the command, turn OFF autoupdate.

I was going to suggest this. You should create a library function to handle this.

You also need to exit the block or timer too.

This really isn’t something people need to deal with most of the time, again depending on the technology. If the command didn’t work the first time there is no reason to expect it will work if sent again. Or there are other ways to determine if there will be a problem prior to sending the command such as checking the status of the Thing.

So this is really kind of rare edge case than something everyone has to deal with.

Home Automation general case: if the lights don’t work, there’s nothing I can do about in software. ‘Someone’ will complain loudly, so I don’t even need to detect or alert.

Making sure a frost heater comes on in the greenhouse overnight is the rarer case requiring special action (that will vary greatly depending on your setup)

1 Like

Yes sorry realized that after I wrote it… thanks for clarifying.

Good answer. I suspect something else may be going on, or I simply have flaky cheap zigbee power devices (possible since I am also cheap :slight_smile: ) …

Given that in typical, and even normal circumstances, a sendCommand will result in a change to the actual device (which is what I would expect from a mature technology like OH (seriously) )

So now, looking at the log I see for this particular device (BackDen_Television) the three log entries:

2021-08-30 18:55:00.343 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'BackDen_Television' received command OFF
2021-08-30 18:55:00.666 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'BackDen_Television' predicted to become OFF
2021-08-30 18:55:00.798 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BackDen_Television' changed from ON to OFF

I deleted (…) many dozens of other entries for other devices (i.e. a lot of other zigbee device activity going on)

But this shows as you explained the Item going through the three different phases: Command, Predicted, Changed)

I would need to turn on other zigbee debug to perhaps see why the device didn’t actually change.

Im thinking to write a test routine to continuously turn on and off the suspect device and look for cases where it didn’t actually change states… the question is, how do I know that? The binding may say that it changed states but still didn’t actually change (i.e. it’s flaky) … I dont think I’ve seen how to query the status of a Thing or a Channel from jsr223 … is that possible?

Definitely try sending the REFRESH command. I think Zigbee is one of the bindings that supports it. I know Zwave definitely is and since they have the same author, assuming Zigbee supports polling, I’d expect both support it.

That can be a way to force the binding to poll the device linked to that Item with it’s current state.

But just to be clear, that change is caused by autoupdate, not the binding. You don’t really know whether the device actually turned off. Autoupdate is updating the Item because it’s supposed to go OFF. But who knows what the device has actually done?

You won’t see that “predicted” entry in the logs when autoupdate is disabled and the Item won’t change to OFF until after the device actually reports that it’s turned off.

Are you sure? Or is it autoupdate that updated the Item? I’ve not seen any evidence that you’ve ever run with autoupdate disabled. Until you do that you don’t know what the binding is actually doing.

What I would do ion the library function is (after turning off autoupdate on the Item of course):

  1. sendCommand to the Item
  2. enter a busy wait while loop that loops until the Item changes or we’ve waited too long
    a. send a REFRESH command to the Item
    b. sleep an appropriate amount of time
  3. if the Item changed return, if not log an error and return

The amount of time to wait over all and the amount of time to wait in the loop you’ll have to determine. Each refresh command will hit your zigbee network so sending lots of REFRESH command real fast may cause more problems than it solves.

But in general I’ve found and have seen reported that Zigbee devices in general, even the cheap ones, tend to be pretty reliable. Maybe you don’t have a good mesh network and one or two more Zigbee devices is the true solution to your problems. It’s most likely that the command message is getting lost.

Another problem might be you are sending the commands too fast. I know that’s a problem with Hue so suspect it’s a generic Zigbee problem too. Adding a delay between commands to Zigbee devices might be the solution. See Design Pattern: Gate Keeper. There is a Python implementation linked to there that would only need to replace Joda DateTime with ZonedDateTime to make it usable in OH 3.

If it’s possible it’s possible from Jython. But in this case it’s a core capability available in all languages.

Thanks Rich.

  1. Is it possible to query the Channel specifically?
  2. Is there a REFRESH Command (I see xxitem.sendCommand(REFRESH) … but I need (for now) a sendCommand(“Item”,REFRESH) can I do that? (in these cases I only have the Items string name)

Looking further in the log (only a second later) I see this back to back sequence (ie no gaps):

2021-08-30 18:56:16.069 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'BackDen_Television' received command ON
2021-08-30 18:56:16.073 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'BackDen_Television' predicted to become OFF
2021-08-30 18:56:16.376 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'zigbee:device:ZigBee_Bridge:00124b001cd6a9c6' changed from OFFLINE to ONLINE
2021-08-30 18:56:16.379 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BackDen_Television' changed from OFF to ON
2021-08-30 18:56:18.210 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'BackDen_Television' received command OFF
2021-08-30 18:56:18.214 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'BackDen_Television' predicted to become OFF
2021-08-30 18:56:18.221 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BackDen_Television' changed from ON to OFF

The Thing in question indeed is the “00124b001cd6a9c6” Thing… so this explains some of this … i.e. the Thing was OFFLINE then became ONLINE while the commands are being sent. Frankly, I don’t know why the 2nd “Item 'BackDen_Television' received command ON” was received, (I dont think I explicitly sent it) … so combining what I showed earlier and this set , the log is:

2021-08-30 18:55:00.343 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'BackDen_Television' received command OFF
2021-08-30 18:55:00.666 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'BackDen_Television' predicted to become OFF
2021-08-30 18:55:00.798 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BackDen_Television' changed from ON to OFF
2021-08-30 18:56:16.069 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'BackDen_Television' received command ON
2021-08-30 18:56:16.073 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'BackDen_Television' predicted to become OFF
2021-08-30 18:56:16.376 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'zigbee:device:ZigBee_Bridge:00124b001cd6a9c6' changed from OFFLINE to ONLINE
2021-08-30 18:56:16.379 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BackDen_Television' changed from OFF to ON
2021-08-30 18:56:18.210 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'BackDen_Television' received command OFF
2021-08-30 18:56:18.214 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'BackDen_Television' predicted to become OFF
2021-08-30 18:56:18.221 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BackDen_Television' changed from ON to OFF

Was there some sort of retry going on at a lower level because the Thing was OFFLINE? Also, it’s weird that at 18:56:16.069 … the log shows ON Received, but then immediately shows “predicted to become OFF” why OFF and not ON? … anyway, I know that the log entries may not line up with actual real time.

Not expecting you to dive into my logs … I need to set up a better test case. This event only happened once and only noticed it because the TV didn’t suddenly turn off :slight_smile: as I expected.

BTW, I have over 35 zigbee devices so dont think the mesh is an issue :slight_smile: but … there could easily be a lot of chatter causing missing zigbee commands … slowing down the rate of sendCommands might be the first thing to try.

What exactly does it mean to query a Channel? The Thing represents the device, not the Channel. Either the device is online or it’s not. You won’t have one Channel online and another one offline on the same Thing.

And remember that the online status of a Thing means that the communications channel between OH and the device is online, not necessarily that the device itself is online. Though some technologies, Zigbee among them, are good at detecting and updating a Thing when a device goes offline.

Yes, same as you can send and ON command to a Switch using "ON".

In Python and JavaScript the only way to send commands is using events.sendCommand(String, String).

When the device came back online the binding polled it for its current state and the binding commanded the Item with the new state instead of just updating it. There isn’t really a good standard for when a binding should update compared to command Items. It appears that Zigbee chose, at least for this device, to command the Item when it appears that the device turned on through some other way than through OH.

From the binding’s perspective, the device turned on outside of OH so it processed that change as a command.

Possibly. You’ll need debug logs from the binding to be sure. I believe Zigbee is one of the bindings that implements it’s own autoupdate and I can definitely see it updating the Item to OFF if the Thing is OFFLINE.

1 Like

I thought I could get the value that the Switch Channel is set to, but now that I think about it, the Item is updated from the Things Switch Channel so its not necessary (i.e. the Item state represents the Channel state (or will in some small amount of time)

Oh! I had just read through the discussion on why its better to use Item.sendCommand(state) for type checking … oh well.

Very helpful to understand this, thank you!

Now I’m thinking the first thing to do is to check the status of the Thing before commanding it … this raises a separate issue about various OFFLINE zigbee devices, which I’ll post in another thread.

Furthermore, the Channel doesn’t actually have a state. It’s just a conduit to the Item. As you surmise, it’s the Item that maintains the state. The Channel is kind of like a wire. The Link is kind of like a plug.

That’s only for Rules DSL. I wish it were for the other languages too but the way they do the magic in Rules DSL to allow that to happen doesn’t exist in Python.

1 Like

Comment, looking at timestamps; this is really quite sluggish performance (example posts showing 20mS from command to change are quite genuine).
That may be because there was a lot of other stuff going at the time.

Zigbee can be a bit special about autoupdate - in some circumstances it applies the rarely-used binding veto. But if you’re seeing ‘predicted’ for a given device, all well and good. Mentioning because not all your Zigbee devices may behave alike here.

But this part is not Zigbee specific; send a command to an Item with a broken channel (i.e. Thing offline) and autoupdate gets vetoed by the framework, “this command cannot work”. So autoupdate predicts “same state as before”.

I’m not very convinced about that, not supposed to happen. Some other rule or UI effect I reckon.

I’m not sure for sure what is going on either. Debug logs from the binding would be required to know for sure if it’s involved.

Well, I am going to be playing with the other OFFLINE devices so I’m sure there will be useful info :slight_smile: Thanks to you both for your responses, very helpful in building my understanding!

If you’ve got Zigbee Things popping on and offline unexpectedly, there are fundamental problems. This is not routine. It’ll be making knock-on overheads as well.

yes could be … I’ve started a thread on this topic (which I see you’ve commented in) …

What do you mean by this?

1 Like

When a Thing comes online, there is initialization code churning about, which won’t be tuned for efficiency. It’s not a routine event.