Correct way to respond to Item change in rules DSL when the .items file is saved

I was trying to clean up my rules and noticed when I re-save the .items files it will trigger rules that are of the form.

when
Item SavedItem changed

Happens with or without persistence and when the item is connected to a binding. The value itself is not changing though, e.g. 0 is still 0.
I went searching around but didn’t see any preferred patterns for handling Item changes and not getting them to trigger accidentally when its item file is re-saved… Was wondering if there is a pattern to handle this.

I’m just going to use

    if (previousState == NULL) return;

every place I have a Item changed…, unless there is a better solution.

No. Or yes: don’t change .items. If you (have to) do often, you should revisit your concepts.
It’s not required in normal operations. So there’s also no need to handle this in rules.

Well. What you are lacking is an overall programming concept.
The underlying problem cannot be handled locally in a rule.

A good concept is to
a) test for the state of any item.state before you use it
If it’s wrong, log this information and appropriately proceed in your rule (that might mean “return” but you could for example also work with a constant default value or action).
and
b) properly initialize all items on system startup.
It’s good practice to write an “initialization” rule that validates all items (i.e. that they are not NULL and in range of reasonable values) and if they’re not ok, initializes them to a default value.
This rule you can run on system startup or whenever things have gone wrong or when there is a need to reset the great state machine.
You may also divide that into multiple smaller initialization rules so you can re-initialize parts or in stages and a single run does not affect everything.

But note that will still trigger other rules looking for a change, and you would still need

or similar to ignore that start-up change.
It’s a perfectly reasonable way to do it.

Err, well. It’s fine to do that (note it’s what I also suggested as a) ) but it ain’t sufficient hence I would not call it “perfectly reasonable”.
You also need b) else you will be having problems with your application logic.

But you don’t need to initialise something like a sensor reading with fake data, if you are happy to wait until good readings come along. You would need to deal with “not available yet” condition, that’s fine. There isn’t a blanket answer, each case on its requirements.

“Perfectly reasonable” is a trigger word to me that I dislike in this context. It’s ok but far from perfect.
As I said myself it’s good practice, no hard requirement.
Sure it’s more work for a start and for simplemost applications you can get away without it, but it pays off quickly so the earlier you start the better. And there are many more best practices in programming, but this is probably the wrong place to discuss.

Thanks for the advise. Yes in my case a lot of states come from MQTT, so I can wait for them to repopulate. After several years I never really bothered to handle the changes when the item file is resaved because it auto-resolves itself when MQTT publishes the new values. I (sort of) expect the state to be undefined during startup and I do have a rule to handle that, it just seems unfortunate that they get cleared (upon closer inspection) when the item file is re-saved, even when nothing in the item file changes. Probably I knew that a long time ago and forgot about it… I suppose with people moving to the UI for defining these things it’s not an issue, but I’ve been using OH for several years so I have reasons and habit to keep editing the items files. Thanks again for the comments.

1 Like