Accessing an item's previous state

To get access to the previous state of an triggering event in Jython, I know I must use:

event.oldItemState

However, there’s no oldItemState entry in an item’s dict, as the following example shows:

Item 'AT_Shutter_N' has dir = ['UID', '__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__', '__ensure_finalizer__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__subclasshook__', '__unicode__', 'acceptedCommandTypes', 'acceptedDataTypes', 'addGroupName', 'addGroupNames', 'addStateChangeListener', 'addTag', 'addTags', 'category', 'class', 'commandDescription', 'commandDescriptionService', 'dispose', 'equals', 'eventPublisher', 'getAcceptedCommandTypes', 'getAcceptedDataTypes', 'getCategory', 'getClass', 'getCommandDescription', 'getGroupNames', 'getLabel', 'getName', 'getState', 'getStateAs', 'getStateDescription', 'getTags', 'getType', 'getUID', 'groupNames', 'hasTag', 'hashCode', 'isAcceptedState', 'itemStateConverter', 'label', 'name', 'notify', 'notifyAll', 'removeAllTags', 'removeGroupName', 'removeStateChangeListener', 'removeTag', 'send', 'setCategory', 'setCommandDescriptionService', 'setEventPublisher', 'setItemStateConverter', 'setLabel', 'setState', 'setStateDescriptionService', 'setUnitProvider', 'state', 'stateDescription', 'stateDescriptionService', 'tags', 'toString', 'type', 'unitProvider', 'wait']

And when retrieving dir(item.state), then I can’t find it either:

The state of item 'AT_Shutter_N' has dir = ['HUNDRED', 'ZERO', '__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__', '__ensure_finalizer__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__subclasshook__', '__unicode__', 'as', 'byteValue', 'class', 'compareTo', 'doubleValue', 'equals', 'floatValue', 'format', 'getClass', 'hashCode', 'intValue', 'longValue', 'notify', 'notifyAll', 'shortValue', 'toBigDecimal', 'toFullString', 'toString', 'valueOf', 'wait']

Is there a way to get the previous (different) state from an item in JSR223 Jython, or is this not yet supported?

Take a look at the Event object attributes, specifically the Events. These are transient things, going for a ride on the event bus and they are not stored. You’d need to use Item persistence and previousState. Event persistence is an interesting concept though.

1 Like

That’s what I was searching for, and eventually I found it in the documentation: Actions - Persistence extensions

Going to give it a go.

EDIT: it works!

1 Like

Okay, I got that working right.

Now I’m struggling with the JSR223/Jython equivalent of previousCommand, as in:

	val String cmdReceived = receivedCommand.toString().toUpperCase()
	val String cmdPrevious = previousCommand.get(shutterName)

The first line is easy:

    cmdReceived = event.itemCommand.toString().upper()

But I can’t find any Jython equivalent of cmdPrevious in Rules DSL.

Commands are different in many ways. The biggest way it’s different is that a command is not always the same as an Item’s state. For example, if you have a Dimmer Item you can send it the command INCREASE. But a Dimmer Item cannot store INCREASE as a State (it’s be meaningless to do so).

Persistence only stores states, not commands. So there is nothing to store commands to persistence, and it doesn’t really make sense to. So there is no way to pull a previous command for another Item (i.e. not the Item that triggered the Rule.)

For the Item that triggered the Rule, the event (if I understand correctly) only has a previousState populated when Rules are triggered by a changed event. There has never been a concept of previousCommand in Rules DSL and at least when I started trying to document all this sort of stuff for NGRE there was no previousCommand on the event either. This is something that I suspect could be added, though it might not be easy. The reason we have previousState is because the previous state exists on the event that get’s put on the event bus (watch events.log and you will see “Item blah changed from ON to OFF” or the like. A command is just a command. There is no “Item received command ON, previous command was OFF”. So in order to support a previousCommand the core would need to be updated to keep track of that. And even that doesn’t really make much sense to me. A command is a momentary event, it’s not a state. I can’t think of a single case where one would want to do something different because of the previous command instead of because of the previous or current State.

Do you have a compelling use case for why you want this? In all the years I’ve been supporting OH this is the first time I’ve seen a request for previousCommand.

Short version of @rlkoshak - there is no previousCommand to have an equivalent to. :wink:

Oops. Silly me. I misread my own rules DSL code. I store the last command received in a hash list to overcome unreliable communication with my Z-Wave roller shutters.

I basically need to poll my Z-Wave shutters to confirm that they properly responded to the UP or DOWN command, and I intermittently poll them to check their state should they have been operated by means of a secondary controller. Both checks are implemented with timers (also stored in a hash list).

I need to know which was the previous command to avoid ending up in a deadlock.

I know this old but the documentation list oldItemState for an event and I am getting an error that this attribute does not exist. Is it not part of the event object?

It depends on the Trigger used. Which one are you using?

Code is below

    @rule ("gOccupancy State Command")
    @when ("Member of gOccupancyState received command")
    def gOccupancyStateReceivedCommand (event):

I don’t expect there to be a previous State available where the rule is triggered by command.

Ross is correct and this is documented in the Event Object Attributes. The ItemCommandEvent only gives you itemName and itemCommand. Since the command comes in before the state changes, you can read the state of the item before the command effects it, but this is not 100% reliable, especially on slow machines or in large rules. If you need it, it is best to grab the Item’s state first thing in the rule, but there’s probably a better way to do what you are trying to do.

Yup, this was a mistake. Should have been received update not command. This was for avoiding processing during startup with persistence on…