Average sensor value for rules

HI everyone.

I’m trying to find the best way to keep the average value from a temperature sensor. Since it will be controlling an electrical heating panel and currently it returns consistent data, but sometimes it has hiccups

For instance if I defined a 19ºC threshold, if temperature is above that value, I turn off the heating, otherwise it remains on. The problem is that sometimes I get a series of values like this: 18, 18, 18.2, 23 (turns the heating panel off), 18.2 (turns the heating panel on), 18.2, etc…

The ON/OFF cycle could last 2 seconds because the trigger of the rule is based on “Item xxx received update”.

One of the solutions I thought about, was using an average of the last 5 readings. Will that work? How can I implement it?

Thanks!

As an first idea it should work with persistance. You should persit all values and then within the rule which switches the heating you should access the persistance data. It should be something like

item.averageSince(AbstractInstant) - Gets the average value of the state of a given item since a certain point in time.

and with this valu you could check your hysteresis

Thomas

Thanks Thomas.

Where can I read more about persistence on OH2? The simplest method, the better since I only need it for this particular scenario.

J

I am not sure if there is much about it for OH2, but ist is similar to OH1. Für your scenario i would suggest rrd4j, because it sort of compresses older data that ist not important for you. I assume you will need an average of 10 minutes or solething like that.

Here ist the lwiki link: https://github.com/openhab/openhab/wiki/Persistence

Thomas

I was just reading that document and came out with this for the rrd4j.persist file:

Strategies {
    default = everyUpdate
}

Items {
    office_temp : strategy = everyUpdate
}

office_temp is the item which data I want to persist.

This rule:

rule "Average Office Temp"
	when
    	// Every 1 min
   		Time cron "0 0/1 * * * ?"
	then
		logInfo("OfficeRules", office_temp.averageSince(now.minusMinutes(5)))
	end

Generates this exception:

Error during the execution of rule Average Office Temp
java.lang.IllegalStateException: Could not invoke method: org.eclipse.smarthome.model.script.actions.LogAction.logInfo(java.lang.String,java.lang.String,java.lang.Object[]) on instance: null
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:1102)[140:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:1060)[140:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1046)[140:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:991)[140:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
        at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:114)[124:org.eclipse.smarthome.model.script:0.8.0.b5]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901)[140:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864)[140:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223)[140:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203)[140:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:446)[140:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227)[140:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203)[140:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:189)[140:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
        at org.eclipse.smarthome.model.script.runtime.internal.engine.ScriptImpl.execute(ScriptImpl.java:77)[125:org.eclipse.smarthome.model.script.runtime:0.8.0.b5]
        at org.eclipse.smarthome.model.rule.runtime.internal.engine.ExecuteRuleJob.execute(ExecuteRuleJob.java:60)[123:org.eclipse.smarthome.model.rule.runtime:0.8.0.b5]
        at org.quartz.core.JobRunShell.run(JobRunShell.java:202)[103:org.eclipse.smarthome.core.scheduler:0.8.0.b5]
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)[103:org.eclipse.smarthome.core.scheduler:0.8.0.b5]
Caused by: java.lang.IllegalArgumentException: java.lang.ClassCastException@11a2857
        at sun.reflect.GeneratedMethodAccessor40.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_65]
        at java.lang.reflect.Method.invoke(Method.java:497)[:1.8.0_65]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:1085)[140:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
        ... 16 more

:frowning:

I think your cron statement is not right. Try Time cron “0 * * * * ?” to schedule it every minute. and how often are the values are updated?

Thomas

No, the error is not cron related.
I guess you forgot to include the persistence classes
Not sure if OH2 is different from OH1 here, in OH1 you would need to use
import org.openhab.core.persistence.* at the top of the rules file.

2 Likes

Just my two cents:
logInfo is for Strings, so please try

logInfo("OfficeRules", "Office Temp: {}", office_temp.averageSince(now.minusMinutes(5)).toString)
2 Likes

Correct

You are right, thanks :slight_smile:

Now, when the rules run, I get the following error:

Error during the execution of rule 'Office Panel': Script interpreter couldn't be obtain

This is a different rule that was already in the file and was working. I started getting this error message when I added the average temperature :confused:

Thank you @Udo_Hartmann! That did the trick

I would suggest simply ignoring unreasonable values. Decide by how much the temperature could possibly change in your time period and if the number you receive is outside that range, delete it.

Even if you take an average, you should delete numbers that fall outside a sensible temperature range. When I was setting my system up a got a temperature reading of 4000, which would have messed up any average readings.

Also, instead of setting one temperature for on and off, I suggest building in a hysteresis loop, so that, for instance, the heating turns off at 19.5, but turns on at 18.5, to avoid switching too frequently.

Hi Graham.

Is not that simple since those unreasonable values are close to what could be considered a reasonable one. Thus, using average will work.

This is very interesting. Do you have an example or documentation I can read?

I am working on this same issue and think it would be nice if there was a persistence function to return a trimmed mean.