Keep 'when Item received update' rules from running during RestoreOnStartup

So I have a series of lock notification rules that run when our locks change state (locked by button, user passcode entered, etc.) that I use received update event triggers on. I also am using a RestoreOnUpdate in my persistance file to restore my system after a restart. The problem is when the lock variables get restored it triggers all of my rules and I get a ton of notifications which are annoying (primarily to my wife…)

I tried setting up a virtual switch that gets triggered by a timer during system startup and then check the switch status in my notification rules but that didn’t work. I’ve resorted to disabling the rules file when I do manual restarts but would prefer to not have to manually do that. Any other ideas would be appreciated.

What are you running on? I ask because on my machine I’ve never once had restoreOnStartup events trigger my rules, primarily because persistence and Items load so much before rules do.

Are you running OH 2 or 1.8? If 1.8 you can configure the file polling periods to leaf rules after items and persistence loads.

Can you make your rules trigger only on certain state changes?

Item MyLock changed from OFF to ON or
Item MyLock changed from ON to OFF

I’m running the latest snapshot of OH2. Unfortunately the state changes are variables so no way to filter using the ‘to’ parameter. Thanks for taking a stab at it though. Here’s my actual code just to see if you think of anything I’m not thinking of.

Item:

String Lock_GF_Living_Username "Front Door User Name [%s]" (Mios) {mios="unit:home,device:15/service/DoorLock1/sl_UserCode,in:REGEX(UserID=\".+\" UserName=\"(.*)\")"}

And my corresponding rule:

rule "Front Door Unlock User"
when
	Item Lock_GF_Living_Username received update
then
    Thread::sleep(500)
    if(SystemStarting != ON) {
		if (Switch_HomeMode.state == 2) Switch_HomeMode.sendCommand(1)
		var DateTime NowTime = new LocalTime()
		sendBroadcastNotification("Front door unlocked by " + Lock_GF_Living_Username.state + " at " + NowTime)
		sendMail(mailTo, "Front Door Unlocked at " + NowTime, "Door unlocked by " + Lock_GF_Living_Username.state)
	}
end

And here is where I tried to set the SystemStarting part (hence why I used the sleep to see if it would set first:

rule "System startup"
when
	System started
then
	SystemStarting.postUpdate(ON)
	tStartup = createTimer(now.plusMinutes(10)) [|
		SystemStarting.postUpdate(OFF)
		tStartup = null
	]
end

Well, if we can get an issue fixed that lets you use Strings in the where clause it would work.

Until then…

I’m not seeing the same behavior (i.e. restoreOnStartup does not trigger any of my rules) so I can’t really guess at a good solution. However, I too have faced an issue with too many notifications to my SO which is one of the reasons why I wrote this design pattern which shows you how to centralize your notification logic so you can do things like only send alerts to you and not your wife when your system is starting up.

It’s just a band aide but sometimes band aids can go a long way towards easing the pain.

Thanks. I’ve found your design patterns very helpful (been a few decades since I wrote code and never worked in an object oriented language).

You are in luck, the Rules langauge is not OO. :slight_smile: Just think of Rules as isolated chunks of logic that can execute in parallel.

True, I was referring more to Java and getting use to the syntax structure of needing things like ‘.state’ vs just calling out a variable…

Hi,
I’m having the same problem. All my rules that are triggered by a “Item xxx received update” are triggered when OpenHAB is (re)started. I guess it’s the RestoreOnStartup of my MapDB.

I tried to implement some of the suggested workarounds:

  • Use “changed from … to …” wherever possible (and meaningful). However, that does not work for string-items that can have many values.
  • For some rules, it is acceptable that they are triggered on start up.

A new rule I want to set up is to send a text-message (SMS) when something happens around the house that needs my attention.

The text message itself is a string obviously. So what I would do (I’m just quickly writing this in pseudo-code):
When
Item textmessagestring received update:
Then
If textmessagestring = null => do nothing;
Else => send the actual test message and set textmessagestring to null.
End

I think this avoids text messages being sent when restarting OpenHAB.

But I think a fundamentally better solution is that OpenHAB first does a “RestoreOnStartup” and then start up the rules-engine.

Did you try:

changed from NULL

You don’t need both the from and the to.

Is there a reason you are persisting and restoring this item? It might be easiest to simply not include this item in restoreOnStartup.

See my persistence design pattern for how to manage this using groups.

It used to work that way where restoreOnStartup​ happened before the rules engine started executing rules, but suspect that was caused by an accident of timing. On really fast machine or based on timing it may not always work out.

Another thing you can do is use an if(previousState != NULL) in the body of your rule and only send the message when the previous state isn’t NULL.

That is indeed a better way. I don’t need to check if my item = null. However, after processing I should still change the value of that item back to NULL.

I’ve read your post(s) with great detail. I currently have two persistence strategies:

  • In MAPDB I persist everything on change for RestoreOnStartup;
  • In InfluxDB I persist a selection of groups (everyminute) for graphs and stuff.

As far as I know, you can’t define a “persist everything except…” in your persistence strategy.
My current MAPDB persistence file is pretty simple:

Items {
		* : strategy = everyChange, restoreOnStartup
}

I could decide to not use the wildcard and mention all relevant groups more explicitly. But that implies I would need to update this .persist file more often.

1 Like

Yes, that is true. Otherwise, the rule won’t fire.

No, just define a restoreOnStartup group and add all Items that should be restored to that group. Then you never need to touch the .persist file again.

Will do. Thanks!

Hi,
I wanted to come back on this older topic.

I’m still in a situation where many rules get triggered because the restoreOnStartup is still doing it’s job when rules are initialized.

I do have many rules that have a trigger like:

when   
    Item  MyItem received update
then

These are typically string items.
A trigger like “Item MyItem received update from anything but NULL” would solve the problem. But that is not an option.

Sometimes (in 10% of the cases), my rules are even triggered before all my items are loaded. Then I get something like this in my log:

2017-11-19 22:22:26.696 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'some.rules'
2017-11-19 22:22:30.524 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Some rule': The name 'someItem' cannot be resolved to an item or type; line 286, column 8, length 35
2017-11-19 22:22:35.540 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'some.items'

Wouldn’t it make sense that OH has a more controlled process of doing certain things in a predefined sequence at start up?

  • Load all things & items;
  • Load persistence strategies and perform restoreOnStartup;
  • Load rules;
  • Load sitemaps;

Thanks,
Dries

It might make sense but it is a lot more challenging than you might think since all of these happen in separate threads at the same time and trying the schedule and synchronize them is not always so easy.

But I think there is an issue open to address this.

Hi Rich,
Thanks for your input. I can imagine it’s not that easy. And maybe the people contributing to the code have more pressing matters to look into.

I tried locating that issue that would address this. I couldn’t find it. Unless you can tell me the issue number, I’ll create a new one.

I don’t know it. I’m going off a foggy memory. Open one and if it is a duplicate it will be closed. Note this is an ESH issue so it needs to be on that repo.

1 Like

@rgerrans : From your other rule (where you do SystemStarting.postUpdate()) I presume “SystemStarting” is an Item (of type Switch), right?

If so, the following piece of code needs to be modified:

to this:

if(SystemStarting.state != ON) {

I hope this helps!

I thought it was an OH issue, so I was looking in the wrong place. Here it is:


Or this one:

I haven’t seen an update since May. I guess they have other priorities at the moment.

My approach on preventing the rules to run on system startup is to check previousState.
Something like this:

rule "whatever"
when
    Item myItem received update
then
    if(previousState != NULL){
        //do stuff
        myItem.sendCommand(NULL)
end
1 Like

That is inspired. Excellent tip!