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

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!

Actually, the last sendCommand should not send NULL.
Instead one should use “” (emtpy string) or 0 or some other value depending on the item type.
NULL should be only on system startup :smile:

Not necessarily. For example, I use the expire binding to set Items back to NULL when the sensor has not reported in a long time. This tells me that the sensor is not functional and therefore whatever it is sensing is in an unknown state and I write my rules accordingly.

You are right one would not want to sendCommand NULL but it is perfectly reasonable to postUpdate(NULL) or let Expire do it for you.

I also implemented the “previousState != NULL” trick to prevent rules from triggering with RestoreOnStartup but the use of the implicit variable previousState is generating an error:

Rule 'Scene CMD_mCR_command': An error occurred during the script execution: index=0, size=0

Below is the rule:

rule "Scene CMD_mCR_command"
when
    Item CMD_mCR_command received update 15 //triple-click
then
    if(previousState != NULL){
        DW_mCR_portail.sendCommand(50)//TOGGLE
    }
end

When replacing by CMD_mCR_command.previousState().state it works but this is not what I need.
Any idea?

previousState only exists when a Rule is triggered by a changed trigger.

There is no way I know of to determine if an Item’s previous state was NULL with any other Rule trigger.

Thank you! I should read the doc with more concentration :roll_eyes:

I applied a workaround with a global boolean variable that is set to true when the rule is first triggered at startup (due to RestoreOnStartup behavior).

var my_item_initialized = new Boolean(false)

rule "Rule that must not be triggered during RestoreOnStartup"
when
	Item MyItem_WithRestoreOnStartup received update
then
	if(my_item_initialized){
		//code that must be executed only after RestoreOnStartup is completed
	}
	else{
		my_item_initialized = true
	}
end