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?
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
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.
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
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.
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.