Discard outrageous sensor readings

Is there a relatively simple way to discard readings that are wrong? I’ve got a couple of dht22 sensors on two raspberry pis.

Occasionally they’ll post a 6 degree reading when it’s about 18 degrees in the room. It’s obviously an error. I’d there some sort of comparison rule I could put in place to discard changes >5 degree difference from the last reading?

If you create a second item for each sensor item, like

Number Temperature "Temperature [%.1f]" (groupA,groupB)
Number Temperature_from_sensor "Temperature from sensor [%.1f]" { ...your current binding... }

and then a rule like this:

import org.openhab.core.library.types.DecimalType // not needed in OH2

rule TemperatureFilter
when
  Item Temperature_from_sensor changed
then
  if ((Temperature.state instanceof DecimalType) && Math::abs((Temperature.state as DecimalType) - (Temperature_from_sensor.state as DecimalType)) > 5) {
    logWarn("dht22", "Discarding unbelievable sensor value " + Temperature_from_sensor.state)
  } else {
    Temperature.postUpdate(Temperature_from_sensor.state)
  }
end

The above intends (untested) to discard updates when a previous value is known and it differs from the new proposed value by more than 5 degrees. Otherwise, it forwards it on to the item you want to monitor.

I have items from a weather source that occasionally report wildly incorrect temperatures, which are then persisted and will pollute charts. If I add a rule like above, these bad values ought to be discarded.

Thanks I’ll look at putting that in.

So finally managed to put in it:

rule "TemperatureFilter_gf_cupboard1 filter rule"
when
        Item gf_cupboard1_temperature_sensor changed
then
  var Number difference
  if (gf_cupboard1_temperature.state != Uninitialized) {
        difference = Math::abs((gf_cupboard1_temperature.state as DecimalType).floatValue) - ((gf_cupboard1_temperature_sensor.state as DecimalType).floatValue)
        logWarn("gf_cupboard1_temperature", "sensor value difference = "+  difference)
        if (difference < 5)
        {
                logWarn("gf_cupboard1_temperature", "Posting update as difference < 5")
                gf_cupboard1_temperature.postUpdate(gf_cupboard1_temperature_sensor.state)
        }
        else
                logWarn("gf_cupboard1_temperature", "Discarding Difference as >  5")
  }
  else {
        logWarn("gf_cupboard1_temperature", "gf_cupboard1_temperature.state is null, posting  " + gf_cupboard1_temperature_sensor.state)
        gf_cupboard1_temperature.postUpdate(gf_cupboard1_temperature_sensor.state)
  }
end

Interestingly though I log the diffrence variable, and it still seems to post negatives. I thought that was the point of the Math::abs?

2016-08-03 22:33:58.850 [WARN ] [o.m.s.gf_cupboard1_temperature] - sensor value difference = -0.10000038
2016-08-03 22:33:58.860 [WARN ] [o.m.s.gf_cupboard1_temperature] - Posting update as difference < 5
2016-08-03 22:35:36.064 [WARN ] [o.m.s.gf_cupboard1_temperature] - sensor value difference = -0.10000038
2016-08-03 22:35:36.067 [WARN ] [o.m.s.gf_cupboard1_temperature] - Posting update as difference < 5

Looks like you are missing a closing parenthesis on the Math::abs line (or rather, premature closing paren).

ah yeah. Got that working now.

Do you know of a what of taking variable sensors and applying the same rules to it? or can I create a rule that takes a sensor and operate on the passed in variable?

Ahh finally proof:
2016-08-04 11:29:49.171 [WARN ] [m.script.br_master_temperature] - Discarding Difference as > 2: Sensor: 6.09999990463 Stored: 18.8999996185 Difference: 12.799999

1 Like

Thanks for the hints here.

I get an error with the following code:

  var Number difference
  if (tankDepthRawFiltered.state != Uninitialized) {
    difference = Math::abs(((tankDepthRawFiltered.state as DecimalType).floatValue) - ((tankDepthRaw.state as DecimalType).floatValue))
    logWarn("tankDepthRawFiltered", "sensor value difference = "+  difference)
    if (difference < 10)
    {
            logWarn("tankDepthRawFiltered", "Posting update as difference < 10")
            tankDepthRawFiltered.postUpdate(tankDepthRaw.state)
    }
    else
            logWarn("tankDepthRawFiltered", "Discarding Difference as > 10")
  }
  else {
    logWarn("tankDepthRawFiltered", "tankDepthRawFiltered.state is null, posting  " + tankDepthRaw.state)
    tankDepthRawFiltered.postUpdate(tankDepthRaw.state)
  }

The name ‘Uninitialized’ cannot be resolved to an item or type

Any suggestions?

I believe with openHAB 2.0 and above uninitialised became null.

1 Like

That fixed it…

:+1: