Rule which iterates through group(s) of similar items

I’m sure that was before the addition of the Member of trigger and triggeringItem.

With Member of and triggeringItem you no longer need persistence to figure out what Item triggered the Rule.

Yes, i use this rule for some time… It was before adding this…

Ok, now i understand.

The rule with the window contacts doesn´t seem to work properly.

I have the same rule or my lights, this is working without problems.

I have seen in the window contacts, that if i have some windows open, the datetime item changes all few minutes to the actual time, when nothing has changed.

I have a knx installation and my knx binary actor sends the value open/closes every few minutes.

Then i changed the rule from “received update” to received command", but then the rule stopped working at all.

My lights knx actor sends the status too, there it works and the old rule for my windows contacts was working too.

Do you know, where there could be the error?

Now i have 5 windows opened, and every few minutes, all 5 windows gets a new timestamp.

When i open a new window, then only this windows is updatet - this works. But the other 5 windows change a few minutes after this again.

Now i use the trigger “changed from CLOSED to OPEN” and now it seems to work better.

The binding probably postUpdates the Item periodically. That will trigger the Rule for every update whether something changed or not if you are using receivedUpdate.

Contacts cannot receive a command. That is one of the key distinctions between a Switch and a Contact.

Changed is a more appropriate trigger in this case.

What would be a good trigger for my temp sensors?

I use xiaomi mi temp/humidity wireless sensors and get sensor reports every 50 minutes (or shorter intervalls, when temp is changing a lot). I don´t know if the new values after a restart are from the persitence or from the xiaomi gateway?

With received update it worked with the old rule, but with the new way of writing this rule, on a openhab service restart, i get the actual timestamp on every item.

Is there a better way? My temp sensors report values and no on/off, so what to use here for a better experience?

‘changed’ seems sensible. You want to take action when temperature changes, not when it is steady, right?

Dealing with OH restart is often a challenge. You can choose whether to restore-on-startup as a first guess at a temperature, or to leave it as NULL (but you might have to make sure your rules can deal with NULL).
Either way, it all comes right at the next update where it will probably change.

EDIT - on re-reading, it’s the timestamp you are complaining about.
I’d use ‘change’ trigger and use ‘restore-on-startup’ for temperatures. If the real temperature does’t change, the timestamping rule shouldn’t trigger.

Ok, will try it.

But when the temp stays the same, i can´t see, if my temp-sensor is still alive… Maybe the battery is empty or something else…

So it is good to know, when i get a update and the timestamp is chanching, also when the temp is the same.

Expire binding is helpful here. Add an expiry of say 2 hours, where you expect hourly updates, with an action like command=NULL. You can even have a rule trigger on chnaged to NULL to ring bells and so on.

EDIT - mistake here, don’t command NULL but instead state=NULL to make an update happen. You’d still ring bells by looking for “changed to NULL”

1 Like

I see, in some cases, the old way of typing the rule was better…

But there are error/warnings when i use the old way. But i think it works also.

It all depends on what you are trying to do in the Rule. If you are using the persistence hack to figure out which Item triggered the Rule then you should absolutely be using the Member of Rule trigger. It requires fewer lines of code, works more reliably, and doesn’t slow down the running of your Rule with sleeps.

@rossko57’s suggestion to use the Expire binding to detect when a temperature sensor isn’t reporting (technically the NULL really just means that the Item doesn’t have a usable state) is a better approach for that.

For setting a DateTime Item when a Temperature Item updates I would code something like:

rule "take timestamp when temp sensor updates"
    Member of Thermometers received update
    if(previousState == NULL) return; // we don't want to overwrite the timestamp for restoreOnStartup
    postUpdate( + "_Lastupdate", now.toString)

if(previousState == NULL) doesn´t work for restore on startup.

All my datetime-items are with the now-time, when i make an openhab service restart.

Now i also get an error for this:

	"resource": "/w:/rules/temperatur_anzeigen.rules",
	"owner": "_generated_diagnostic_collection_name_#0",
	"code": "org.eclipse.xtext.xbase.validation.IssueCodes.invalid_number_of_arguments",
	"severity": 8,
	"message": "Invalid number of arguments. The method previousState(Item) is not applicable without arguments",
	"startLineNumber": 181,
	"startColumn": 5,
	"endLineNumber": 181,
	"endColumn": 18

What is the right way to write this?

Here is my modified rule which is giving the error:

rule "Xiaomi Temp-Sensoren State Changed"
    Member of gXiaomiTemp received update
    if(SystemStarting.state != OFF) return;
    if(triggeringItem.previousState != NULL) {
    		postUpdate( + "_Lastupdate", now.toString)

I look in the forum and found this:


***** (without the ending .state it works too)

Seems to work now…

But is previousState only working with persistence? And if i have more than one, how can i specify which persistence should be used?

There’s an error in my previous suggestion of using expire with command=NULL. I believe you cannot command NULL, so it would need to be state=NULL to have the Item update instead. General idea is fine.

WARNING There are two previousState

previousState on its own is an implicit variable. It’s something the rule makes available to you If, and only if, the rule was triggered by some Item changing state - then it will contain the previous Item.state
It won’t work with ‘received command’ rule trigger for example. It won’t work with any other Item except the one that triggered the rule this time.

someItem.previousState() is a method on that particular Item that you can call in any rule on any Item.
But it is based on persistence - it goes and looks in your database for the last value. So it only works if persistence is set up correctly on that Item.
This previousState doesn’t return a simple item.state though - it returns a type of thing called a ‘Historic Item’. The .state is in there, along with a timestamp and so on.
So to get just the .state you need to say so

Ok, so i think, the first previousState wouzld be the better choice for me?

But i get this error, look at my previous post.

What is the correct way to use just previousState without persistence?

Look my rule, this is not working, error see above…

rule "Xiaomi Temp-Sensoren State Changed"
    Member of gXiaomiTemp received update
    if(SystemStarting.state != OFF) return;
    if(previousState != NULL) {
    	    postUpdate( + "_last_connection", now.toString) 

That’s a different rule to your previous post. You get the identical error?

Yes, same error.

And now i get this error in the openhab.log for every change of the temp-sensors.

2018-08-30 13:48:15.559 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Xiaomi Temp-Sensoren State Changed': An error occurred during the script execution: index=0, size=0

Beginning to feel like you have two rules named the same, perhaps its a caching issue.

No, only one rule.

When i change to triggeringItem.previousState().state the error is gone immediately. When changing back to just previousState, error is here again.

And i didn´t get new time data. I looked to the wrong items…
error --> no time update
no error --> time update working

Can you clarify which error(s) come and go? You said you had two.

What version of OH are yo running here?

I´m on OH 2.4 snapshot # 1341 - latest version from today.

No, only this error occurs, when i use previousState.

The error is from vscode:

Invalid number of arguments. The method previousState(Item) is not applicable without arguments

The other error was only in the openhab.log, but now it is gone, i think we can forget this. The first error is still there.

When i use the persistence-previousstate, checking for NULL will never help me, because persistence is never NULL.

Only previousstate (without persistence) will make sense, because this could be NULL, when restoreatstartup is not finished yet.

As @rossko57 indicated, previousState only works with a changed trigger. You can’t use received update and previousState in the same Rule. I wasn’t paying attention to that when I wrote Rule on post 30.

So you need to change the trigger to changed or if you use received update need to remove that first line. I’m not entirely certain what that means during startup. It might be the case where you have to work around the timestamps that get generated when OH first starts up.

I don’t use timestamps in my system for this sort of thing. I don’t really care when the last time the sensor reported in OH. I can look in the events.log for that if I have to. So I use NULL to indicate that the sensor doesn’t have a valid state, and generate alerts when one of the sensors go to NULL. With this I don’t need the timestamp so I’ve never had to deal with this problem.