I use OH 3.3 file based configuration and rules.
Sometimes it happens that some sensor reading is false/unavailable and that causes unexpected results in calculations. E.g. the daily water consumption spikes to 40000 litres because the sensor was offline for some days. That looks awful in a chart.
I know I could build some workaround in a rule, but doing that for thousands of items is a nightmare.
Is possible to limit the possible numeric range directly in the items definition, e.g.
well yes, but if you’ve got thousands of Items generating false values it might be worth reviewing exactly why.
I don’t know what that means.
For numeric Item states updated from a channel, you could apply a profile with SCALE transformation, although I think that will not do what you want.
A JS transformation can be used to select pass-through or block.
@rossko57 Well, usually things go wrong when a sensor fails and values expire. I definitely look into this whenever it happens but as it happens rarely, I still sometimes encounter failures after years of flawless operation.
Defining limits for Items would add an additional layer of safety and would make everything more robust.
I looked into SCALE, it is not exactly what I want. It filter values coming from a channel but not those assigned to an item by a rule.
What I would like is an item defined as
Item MyNumber {min=0, max=100}
And that Item can never ever have any other values (maybe undef or so) If a rule updates it with the value 200, that value is intercepted and limited to 100.
Indeed, but umm, if it is your rule that is assigning incorrect values, it would seem smart to make your rule smarter so as not to do that.
Rules are allowed to postUpdate state UNDEF
What you want does not exist (yet).
This is exactly the sort of thing the expire functionality was created for.
If updates stop arriving at an Item, it can set the state to some chosen value, like 0 or UNDEF
It does depend on the technology involved (binding) if updates stop arriving or not.
There is also a rule template in the marketplace that can be used to detect and alert when Item expire. I have a bunch of sensors that report on a pretty regular basis. So I set an expire on those Items to update the Items to UNDEF when there is no report. I use Open Reminder [3.3.0;3.4.9) to detect when that happens, wait a little bit in case it’s only momentary (i.e. debounce) and then call another rule where redial action can take place (in my case I generate an alert notification).
For my sensors I use the following config values for the rule:
That will alert me except between 22:00 and 08:00 when a sensor goes offline and call sensor_offline_alert every 8 hours until the sensor goes back online. Notice there’s no code. That’s the beauty of rule templates, it’s just config, not coding.
I could set a different initial timeout (i.e. debounce period) on an Item by Item basis with rem_time metadata but I just use the default five minutes for this rule.
The sensor_offline_alert rule looks like this:
configuration: {}
triggers: []
conditions:
- inputs: {}
id: "2"
configuration:
type: application/javascript;version=ECMAScript-2021
script: >
var { itemRegistry } = require('@runtime');
//console.log('Received an alert on ' + alertItem);
var equipment = actions.Semantics.getEquipment(itemRegistry.getItem(alertItem)); // requires the Java Item, not JS Item
var statusItem = items.getItem(equipment.name + '_Status');
//console.log('received an offline alert for equipment ' + equipment.name + ' and status Item ' + statusItem.name);
// Just went offline
statusItem.state == 'ON';
type: script.ScriptCondition
actions:
- inputs: {}
id: "1"
configuration:
type: application/javascript;version=ECMAScript-2021
script: >-
var { itemRegistry } = require('@runtime');
var {alerting} = require('rlk_personal');
var logger = log('Sensor Offline');
var equipment = actions.Semantics.getEquipment(itemRegistry.getItem(alertItem)); // requires the Java Item, not JS Item
var statusItem = items.getItem(equipment.name + '_Status').postUpdate('OFF');
alerting.sendAlert(equipment.label + ' has stopped reporting and is likely offline');
type: script.ScriptAction
Notice that this rule uses the semantic model to ensure that only one alert per equipment is generated.
I’ve another pair of rules to alert me when it goes back online.
Beyond that the already mentioned JS Transformation could be used to limit the values to a range as you describe for values that come from Channels. For the values coming from your rules, well like @rossko57 said, don’t do that. Add something to your rule to prevent that. You have full control over the rule.
@rlkoshak , @rossko57
Thank you both for the elaborate answer and the time you put into this. I really appreciate this.
Unfortunately, I don’t quite recognize the syntax of the rule you propose as I am using DSL rules only. I did some digging and was able to create a workaround for now that hopefully adds stability and log entries for debugging. It does check the state of an item for null and if it is within bounds.
val check = [ GenericItem s, Double min_ , Double max_ |
var Double retval=min_
var Double min_t = min_
var Double max_t = max_
if (min_>max_) {
logInfo("check", "WARNING "+ s.name+" limits faulty. min > max. Swapping them now.")
min_t = max_
max_t = min_
}
if (s.state !== null) {
retval = (s.state as Number).doubleValue()
} else {
logInfo("check", "WARNING "+ s.name+" is null. Changed to min value.")
}
if (retval < min_t) {retval = min_t }
if (retval > max_t) {retval = max_t }
return (retval)
]
and the rule for testing:
rule CheckMinMaxTest
when
Time cron "0 0/1 * * * ?" // every 1 minutes
then
var rangedLimited = check.apply(Vito_Aussentemperatur24h, 0.0, 3.0)
logInfo("checktest","original "+ Vito_Aussentemperatur24h.state+" changed to "+ rangedLimited)
end
Seems to do the trick. Now would you happen to know if I can put that into a library or header file and import/include it for all my other rules ?
Note that this is never, ever, true.
If an Item object exists, it has a non-null state.
That state’s value might be NULL, but NULL is a value and is not null.
.state can also be UNDEF
That’s a UI rule using JS Scripting. But you could use any language you desire.
If you were to:
add an expire to the sensor Item so they go to UNDEF when not updated for too long
add all those Items to a Group
write your rule to alert (see below)
install and instantiate a rule using the Open Reminder rule template
The only code you’d have tow write is as follows:
rule "Alert when sensor is offline"
when
then
sendBroadcastNotification("Item " + alertItem + " is offline!");
end
Or how ever you generate alerts. Detecting that the sensor went offline, and setting timer management and such is all handled by the rule template. All you need to mess with is sending the actual alert.
That’s what my reply is saying. It addresses reporting “when a sensor fails and values expire” with minimal coding on your part.