OH3: Getting TriggeringItemName and PreviousState of Thing changed

I just have found out the my migration rules from OH2 to OH3 don’t work correctly anymore regarding detecting which Thing changed and what the previousState was. I have tried all solutions I have found but it seems like they all just work on Items.
Anyone a clue how to get those informations?

rule "test" when
	Thing "homematic:HG-HM-LC-Dim1T-FM:11442233:OEQ7654321" changed or
	Thing "homematic:HG-HM-LC-Bl1PBU-FM:11442233:OEQ1234567" changed
then
	logInfo("test", "Trigger Thing is:"+??????????)
	logInfo("test", "Trigger Thing previous State is:"+??????????)
end

These all are not working:

rule "test" when
	Thing "homematic:HG-HM-LC-Dim1T-FM:11442233:OEQ7654321" changed or
	Thing "homematic:HG-HM-LC-Bl1PBU-FM:11442233:OEQ1234567" changed
then
	logInfo("test", "Trigger Thing is:"+triggeringItemName)  //Not working
	logInfo("test", "Trigger Thing previous State is:"+previousState) //Not working
	//And therefore this all is not working:
	var list = ScriptServiceUtil.getItemRegistry.getItems(triggeringItemName)
	var triggering_item = list.get(0);
	logInfo("test", "Trigger Thing is:" + triggering_item.label) //no working
	logInfo("test", "Trigger Thing is:" + triggering_item.previousState) //no working
end

Triggering Item name has never worked with Things. Nor has state or previous state, Things not having states.
Maybe if we see your old rule we can see what you used to get?

1 Like

Indeed, I did not used triggeringItem on OH2. But previousState worked garantued.

previousState would be also enough, if getting the Thing name would not be possible at all.

Is there a way to get previousState at least

But Things don’t have a state, so whatever you were looking at in OH2 was not what you think. That’s why I asked to see what you really used to get, so we could replicate whatever it is.

I think the bus ThingStatusInfoChangedEvent has the previous status info as well as the new one, so it should be theoretically possible.
I don’t think there are any methods available in DSL rules to get at that, though you should have better luck in some other rule language.

An alternative is to use the Log Reader binding to pull the text of ThingStatusInfoChangedEvent logs for analysis.

We’ve probably got to the point where if you explain what you’re trying to do instead of the nuts and bolts, there might be better approaches.

But it worked absolutely sure:


rule
	"regelOfflineGarage"
when
	Thing "homematic:HG-HM-LC-Sw4-WM:11442233:OEQ0274516" changed to ONLINE
then
	logInfo("offline.rules", "regelOfflineGarage: Thing geht ONLINE. Status davor: "+ previousState )
	if ( previousState.toString == "INITIALIZING" ) logInfo("offline.rules", "regelOfflineGarage: Abbruch wegen Status INITIALIZING davor." )
	else if ( counterfunction.apply( OfflineCounterGarage )) {
		Garage_1_State.sendCommand( OFF )
		Garage_2_State.sendCommand( OFF )
		Garage_3_State.sendCommand( OFF )
		st_garage_faehrt_auf.sendCommand( OFF )
		st_garage_faehrt_ab.sendCommand( OFF )
		Garage_1_OnTimeAutomatic.sendCommand( 1.1 )
		Garage_2_OnTimeAutomatic.sendCommand( 1.1 )
		Garage_3_OnTimeAutomatic.sendCommand( 1.1 )
	}
end

I’ll take your word for it.
I just looked up OH2 “implicit variable” docs, because I believed previousState did what it said and returned the state of the triggering Item. It would then follow that if there is no Item in the trigger, there is no previousState (just like no triggeringItem name).

But the official words are more ambiguous -

  • previousState - will be implicitly available in every rule that has at least one status change event trigger.

If that is supposed to include Thing status changes, then you’ve found a deficiency in DSL and should log a Github bug for it. I’m guessing newState has similar limitation.

I would not expect any rapid interest in that, which leaves you with the “how do I” puzzle.

As already said, you can use Log Reader binding to find log entries for the events that interest you.

What do you get these days in DSL with

val x = getThingStatusInfo("homematic:HG-HM-LC-Sw4-WM:11442233:OEQ0274516")
logInfo("test", "x {}", x)

at best I’d expect only new status as a string, it’s the event that you want to examine not the Thing.

EDIT
but looking at what your rule does, do you really care what “old status” was?
When the Thing changes to ONLINE, then it was not ONLINE before. Is that all you need to know to do the garage initialise stuff?

1 Like

I have just checked the javadocs and there is nothing I can find. PreviousState is really just related to Items. Ok, there are different ways to achieve what I need but thank you very much nevertheless!

I’ve added triggeringThing, previousStatus and newStatus in this pull request which should be included in the next milestone and release.

You’ll then be able to do the following

rule "test" when
	Thing "mqtt:topic:thing1" changed or
	Thing "mqtt:topic:thing2" changed
then
	logInfo("triggeringThing", "Trigger Thing is: " + triggeringThing) // mqtt:topic:thing1
	logInfo("triggeringThing", "Trigger Thing previous Status is:" + previousStatus) //ONLINE
	logInfo("triggeringThing", "Trigger Thing new Status is:" + newStatus) //OFFLINE
	val changedThingStatus = getThingStatusInfo(triggeringThing)
	logInfo("triggeringThing", thingStatusInfo.getStatus.toString) // OFFLINE
	logInfo("triggeringThing", thingStatusInfo.getStatusDetail.toString) // COMMUNICATION_ERROR
	logInfo("triggeringThing", thingStatusInfo.getDescription) // Authentication Failed
end
3 Likes

From experience, I would expect much future flailing with prevousStatus - is it sensible to name it more explicitly previousThingStatus?
Likewise newStatus of course.

This is amazing! Thank you so much. Any date/roadmap for the next milestone release?

as usual end of this month

1 Like

thanks for the suggestion - I agree, I’ve put in a follow up pull request and see where it goes.

1 Like

I have openHAB 3.3.0 Release Build and it is not working as expected.

e.g.
Thing ‘homematic:HG-HM-CC-RT-DN:11442233:ABC9876543’ changed from ONLINE to OFFLINE (COMMUNICATION_ERROR)
gets follwing results (See comments):

logInfo("triggeringThing", "Trigger Thing is: " + triggeringThing) // homematic:HG-HM-CC-RT-DN:11442233:ABC9876543
logInfo("triggeringThing", "Trigger Thing previous Status is:" + previousStatus) //Syntax error
logInfo("triggeringThing", "Trigger Thing new Status is:" + newStatus) //Syntax error
val thingStatusInfo = getThingStatusInfo(triggeringThing)
logInfo("triggeringThing", thingStatusInfo.getStatus.toString) // OFFLINE
logInfo("triggeringThing", thingStatusInfo.getStatusDetail.toString) // COMMUNICATION_ERROR
logInfo("triggeringThing", thingStatusInfo.getDescription) // null

e.g.
Thing ‘homematic:HG-HM-CC-RT-DN:11442233:ABC9876543’ changed from OFFLINE (COMMUNICATION_ERROR) to ONLINE
gets follwing results (See comments):

logInfo("triggeringThing", "Trigger Thing is: " + triggeringThing) // homematic:HG-HM-CC-RT-DN:11442233:ABC9876543
logInfo("triggeringThing", "Trigger Thing previous Status is:" + previousStatus) //Syntax error
logInfo("triggeringThing", "Trigger Thing new Status is:" + newStatus) //Syntax error
val thingStatusInfo = getThingStatusInfo(triggeringThing)
logInfo("triggeringThing", thingStatusInfo.getStatus.toString) // ONLINE
logInfo("triggeringThing", thingStatusInfo.getStatusDetail.toString) // NONE
logInfo("triggeringThing", thingStatusInfo.getDescription) // null

Any help to get the previous state of a Thing?

Reading this thread about naming …

and then there’s the documentation

  • previousThingStatus - implicitly available in every rule that has a thing-based trigger.
  • newThingStatus - implicitly available in every rule that has a thing-based trigger.
1 Like

That was it. So here is the solution:

e.g.
Thing ‘homematic:HG-HM-CC-RT-DN:11442233:ABC9876543’ changed from ONLINE to OFFLINE (COMMUNICATION_ERROR)
gets follwing results (See comments):

logInfo("triggeringThing", "Trigger Thing is: " + triggeringThing) // homematic:HG-HM-CC-RT-DN:11442233:ABC9876543
logInfo("triggeringThing", "Trigger Thing previous Status is:" + previousThingStatus) //ONLINE
logInfo("triggeringThing", "Trigger Thing new Status is:" + newThingStatus) //OFFLINE 
val thingStatusInfo = getThingStatusInfo(triggeringThing)
logInfo("triggeringThing", thingStatusInfo.getStatus.toString) // OFFLINE 
logInfo("triggeringThing", thingStatusInfo.getStatusDetail.toString) // COMMUNICATION_ERROR
logInfo("triggeringThing", thingStatusInfo.getDescription) // null
1 Like