Item values and logical ranges at updates

Presently I’m having difficulties with getting reliable information from my heating controller. I’m also having similar issues with some onewire-attached sensors.
In detail it’s mostly on temperature sensors, which suddenly drop in values or even return completely illogical values (like -999). Presently I have some trouble with my rules, which rely on temperature change over some time period - if for some reason it drops to 0, the rule is triggered but the “real” temperature is still over the threshold…

so, my Question:
Is there are built-in logic for items, which prevent an item change, that I’m perhaps not aware of? The workaround is very special and complex and would involve to add another item per sensor, which gets updated via a dedicated rule per item - within the rule I would then do some logic and only update the item, if the change is within some boundaries. This would be the worst case, because it would involve having duplicates of items (at least that ones I use for other rules).

my wish
What I’d like to have is some kind of configuration on item-level which prevents an item update, if the new value is completely out of logic (e.g. an temperatue change of more than let’s say 3-5K per interval). If the change is “denied”, it also shouldn’t persisted at all.

isn’t this what transform scripts are for?

I know transformation for the presentation layer, meaning you can add transformation within the item-label. This would be too late for the item update.

Is there some kind of transformation for the item value? I know some bindings, which allow transformation within the binding-section. As far as I know, I can’t use binding transformation for onewire and for mqtt-eventbus, these are the main ways how those items get updated in my environment.

but perhaps I’m completely off and just don’t know how to use transform scripts? :confused:

Good point, I was forgetting that not all bindings support transform of incoming updates. If the bindings you are using have that limitation, you’d probably need to ask for that enhancement. Sounds like a non-trivial job though.

OH2 MQTT supports transforms, but how that relates to the eventbus stuff I do not know. MQTT expert needed.

Onewire binding would certainly benefit from an update to standard OH transform methods, as it is typically used with sensors. I wonder if anyone is working on “OW for OH2”?

I think there could be a pitfall with a transform method; knowing what the previous value was, if you seek to eliminate large swings in value. (Eliminating extreme values is easier and would cover most cases)

Working around all this for now using a shadow virtual Item is probably the best way to go here. If you can group your raw sensors by similar behaviour and needing similar ‘transforms’, you can use a group-triggered rule to do the work and figure out which shadow Item to update.
Example, setup Items Room1Temp_raw for the data, Room1Temp for the laundered version. A rule can easily derive the name of the laundered Item from the raw Item name when triggered.
Put Room1Temp_raw in a group gRawsensors , trigger the rule from an update.
New features in 2.3 make this easier

Depends on the binding. I wish ALL bindings supported transforms. Most of the lower level generic bindings support transforms on the Item state (e.g. MQTT, HTTP, Exec, …).

OneWire appears to not support transforms but you could use a transform on the event bus but subscribing to the topic directly on your Item rather than relying on the event bus to update the Item. This will require your Item to have a different name than the remote one but then you can apply a JS transform to test the range of the new state and if it doesn’t make sense return NULL (I think that will work).

This is indeed a limitation. If you need the previous value you will need to use a Rule and proxy Items.

Also look at Design Pattern: Associated Items

There is no such mechanism. The standard approach is to use proxy Items and Rules.

Could you not use previousState to do the job?

My idea is in the rule which will be triggered, check if previousState and state are in expected range.
If not just post the previousState to the item. This will execute the rule dependent of the trigger once with received command, thrice if it is `changed´. But it is easy and does not need to be adapted and also does not need proxy items.

It also keeps the error in your persistence, so you could do a check for errors etc. Maybe find out when or why they happen.

Example code, not tested.

    if( abs(triggeringItem.state - triggeringItem.previousState) > 10 ) {
        triggeringItem.postUpdate(triggeringItem.previousState)
    }

if there’s no built-in procedure, I see two posibilities:

  1. somehow route everything via MQTT (binding, not eventbus) and then attach a JavaScript transformation (is there persistence / previousState available?)
  2. use the proxy item approach and update the real item via rule (where previousState is available)

I guess, I’ll go with 2. - despite making it much more complex…

No. You only have access to the raw MQTT message to transform.

Here is an idea that I don’t know if it will work but might be worth trying.

There is a persist method on the Item that lets you persist the current state of an Item. What if:

  1. You don’t list the Item in the .persist file

  2. Write a Rule that triggers when the Item changes.

  3. In the Rule check to see if the new state makes sense. Except for the very first time this Rule runs you should have access to all the persistence methods. If you use changed as the Rule trigger, you will have access to the previousState implicit variable.

  4. If the new state passes muster call MyItem.persist. If not call MyItem.postUpdate(previousState)

  5. If the new state makes sense, do whatever other stuff you need to do for the valid change.

If I’m correct, even if the table space doesn’t exist for MyItem, the call to .persist will create it and save the state. This lets you take control over when the values get persisted and doesn’t require a proxy Item.

If you need to emulate a periodic change like every minute, add a Time cron trigger to this same Rule and it should work just fine.

Edit: there might be an edge case here if you get two bad values in a row, I’m not sure though.

2 Likes

Don’t think so as you update the state with a valid one from previousState, if the values don’t come in too fast.

it very similar to my suggestion. but requires more overhead.

So something like this could also do the job, or not?

if( abs(triggeringItem.state - previousState) > 10 ) {
        triggeringItem.postUpdate(previousState)
    }
2 Likes

The big thing is Thomas wants to keep the bad value from being saved to persistence. If all you do is send out a new postUpdate the old wrong value will be saved to persistence.

My idea is basically yours only it tries to solve the persistence problem by only saving values that have been adjudicated by the Rule to persistence using the .persist method on the Item and not having the Item automatically persisted through the .persist file.

3 Likes

Thanks guys, I’ll give it a try this weekend and come back. I’d better had it solved in the source in the first place, but my heating controller suddenly puts out false values since Monday - and I don’t have any idea why and don’t have access to it. worked for 2years flawless …

Thank you for pointing that out. I think I skipped the last line of his post. Where he states no persistence.

I also thought that maybe keeping the values might give a hint why it gives out bad readings. By comparing e.g. sensor voltage etc. when they appear.

1 Like

If such a change of behaviour occurred at a specific, I would ask myself what happened at that time to my system?
Do you do any updates back then?

Yes, thing is I not only automate tasks via value changes (e.g. shading or allowing the gas heater to jump in, when solar isn’t enough…) but also like to graph the values and it’s a total mess, if those unrealistic values show up…

There was no change in oh2 at that time, neither in the script that takes out the serial rs232 connection to my heating controller. The hexbyte results are different since Monday 18:42. not only do they have two or sometimes even three complements more, but sometimes the ACKnowledged values are either -999 or 0 or 21. Most of the times I can just forget -999, but in temperature 0 or 21 (2.1 in that case) is a feasible result. I use python serial for querying the rs232 periodically.

I suspect either a damage in the controller (it was quite hot and sunny the last weeks here - heat from solar?) or some raspbian update (which didn’t happen according to logs) or some inexplicable issues with the serial cable… All of which worked for more than 2 years without problems)