Thermostat rule with persistence/averaging not working

Hello all, new to arduino, new to openhab, new to all of this. I’ve managed to make a decent amount of progress so far in automating the opening/closing of registers in rooms in my house for a home-made zoning setup.
I’m using Adafruit ESP8266 Huzzah boards at the registers with an analog temperature sensor and a servo for the opening/closing of the register. The ESPs run espeasy and properly send and receive via mqtt/http.

My issue is the temperature sensor readings bounce around a decent bit so I want to average the temperature readings and base the vent opening/closing via the averaged temperate. The problem is nothing seems to be happening when I use the average. If I base the actions solely on temperature changes it all works great, except my vents open and close quite a lot. Following is my rule (I lifted most of this rule from somewhere else, it is not my own).

rule "Master heating"
when
    Item VT_Heating_Mode_Masterbd changed or
    Item VT_Heating_Setpoint_Masterbd changed or
    Item Master_Temperature changed
then
    // 0="Off", 1="On", 2="Auto"
    if (VT_Heating_Mode_Masterbd.state == 0) {
        FF_Masterbd_Heater.sendCommand(OFF)
    } else if (VT_Heating_Mode_Masterbd.state == 1) {
        FF_Masterbd_Heater.sendCommand(ON)
    } else if (VT_Heating_Mode_Masterbd.state == 2) {
            var Number setpointM = VT_Heating_Setpoint_Masterbd.state as DecimalType
            var Number turnOnTempM = setpointM - 0.5
            var Number turnOffTempM = setpointM + 0.5
            var Number tempM = Master_Temperature.averageSince(now.minusMinutes(2)) //persistence
            //var Number tempM = Master_Temperature.state as DecimalType //non-persistence
            if (tempM <= turnOnTempM) {
                FF_Masterbd_Heater.sendCommand(ON)
    } else if (tempM >= turnOffTempM) {
                FF_Masterbd_Heater.sendCommand(OFF)
            }
       else {
            FF_Masterbd_Heater.sendCommand(OFF)
        	}
        
    }
end

As far as I can tell persistence is working
http://i.imgur.com/WdWSFzQ.png

the ESP is set to send readings every 10 seconds (events.log)

2017-03-02 07:59:06.523 [ItemStateChangedEvent     ] - Master_Temperature changed from 68.86 to 64.83
2017-03-02 07:59:06.555 [ItemCommandEvent          ] - Item 'FF_Masterbd_Heater' received command ON
2017-03-02 07:59:16.534 [ItemStateChangedEvent     ] - Master_Temperature changed from 64.83 to 68.29
2017-03-02 07:59:16.567 [ItemCommandEvent          ] - Item 'FF_Masterbd_Heater' received command ON
2017-03-02 07:59:26.544 [ItemStateChangedEvent     ] - Master_Temperature changed from 68.29 to 68.58

rrd4j.persist

Strategies {
        // for rrd charts, we need a cron strategy
        everyMinute : "0 * * * * ?"
        everyTenSec : "*/10 * * * * ?"

        default = everyMinute
}

Items {
        //DemoSwitch,NoOfLights,Window_GF_Toilet,Heating* : strategy = everyChange, everyMinute, restoreOnStartup

        // let's only store temperature values in rrd
        //Temperature*,Weather_Chart* : strategy = everyChange, everyMinute, restoreOnStartup
        Master_Temperature, Nursery_Temperature : strategy = everyUpdate, everyTenSec, restoreOnStartup

what else can i look at or where have i gone wrong?

rrd4j is only working reliable (or at all) with strategy everyMinute (hit the search button in this forum and you will find a lot of similar answers regarding rrd4j)

all right, so, backing down to every minute instead.
in the meantime i stop openhab2 and take a fresh look at the log

when i start openhab and then turn the stat to auto mode i receive this immediately in the log
2017-03-02 14:23:48.097 [ERROR] [.script.engine.ScriptExecutionThread] - Rule ‘Nursery heating’: org.eclipse.smarthome.core.library.types.DecimalType

what might this be?

There should be some more lines following that error message.
Maybe a typo or you are using an item in a rule which is not defined properly.
Please post some more lines …

stopping openhab2 and starting fresh, here are the lines immediately before that error. this error pops up when i change the virtual thermostat from off to auto or from on to auto. if i only use on or off it doesn’t complain. only when switching to auto does it throw the error

2017-03-03 17:24:15.634 [INFO ] [g.discovery.internal.PersistentInbox] - Added new thing 'hue:0210:001788264196:16' to inbox.
2017-03-03 17:24:15.643 [INFO ] [g.discovery.internal.PersistentInbox] - Added new thing 'hue:0210:001788264196:17' to inbox.
2017-03-03 17:24:16.834 [INFO ] [ui.habmin.internal.servlet.HABminApp] - Started HABmin servlet at /habmin
2017-03-03 17:24:51.372 [ERROR] [.script.engine.ScriptExecutionThread] - Rule 'Master heating': org.eclipse.smarthome.core.library.types.DecimalType
2017-03-03 17:24:57.825 [ERROR] [.script.engine.ScriptExecutionThread] - Rule 'Master heating': org.eclipse.smarthome.core.library.types.DecimalType

Sorry, I’m not a “rules guy” and can’t help much.
I copied your code into the Eclipse SmartHome Designer and got no obvious errors.
When I do math in my rules I do an import at the top of the rules file:
import org.java.math.*
But I’m not sure if that is always needed.

Good luck.

Some hints:
A
In order to debug your rules I’d use some logInfo lines in order to show the actual values/states from variables and items.
Example:

logInfo(“MyRuleName”, “Actual state of MyItem: {}”, MyItem)

You can monitor those log-entries on karaf while OH is running!
(just use “ssh IP_of_your_device_with_OH@localhost -p 8101”, password is “habopen”)

B
Looking at your chart doesn’t really help, I do guess you are interested in the changes of temperature in relation to the changes by the rule. Looking at a timeframe of 24 houres doesn’t help, use something like or 2 Houres and the picture will show more detail.

through logging i think it’s actually working. not sure what the error is in reference to but it does seem to be working. i’ve also made some additional changes to that the vents arent actuating so often.
I’ve switched to mysql for persistence and am updating the temperature every 10 seconds. Then every 5 minutes i average those numbers and set them to a new item I’ve created named AVG_Nursery

Then kick off the temperature checking based on that item updating (in case you’re interested or someone else comes across this and its helpful).

rule "Nursery Averaging"
when 
	Time cron "0 0/5 * * * ?"
then
	var Number NURAVG = Nursery_Temperature.averageSince(now.minusMinutes(5))
	sendCommand(AVG_Nursery,NURAVG)
	logInfo("nuravg since: ",NURAVG.toString)
end

rule "Nursery heating"
when
    Item VT_Heating_Mode_Nursery changed or
    Item VT_Heating_Setpoint_Nursery changed or
    //Item Nursery_Temperature changed
    Item AVG_Nursery changed
then
    // 0="Off", 1="On", 2="Auto"
    if (VT_Heating_Mode_Nursery.state == 0) {
        // heater off
        FF_Nursery_Heater.sendCommand(OFF)
    } else if (VT_Heating_Mode_Nursery.state == 1) {
        // heater on
        FF_Nursery_Heater.sendCommand(ON)
    } else if (VT_Heating_Mode_Nursery.state == 2) {
            var Number setpointN = VT_Heating_Setpoint_Nursery.state as DecimalType
            var Number turnOnTempN = setpointN - 0.5
            var Number turnOffTempN = setpointN + 0.5
            //var Number tempN = Nursery_Temperature.state as DecimalType
			var Number tempN = Nursery_Temperature.averageSince(now.minusMinutes(5)) //as DecimalType
			logInfo("Nursery averageSince: ",tempN.toString)
            // determine whether we need to turn on/off the heater
            if (tempN <= turnOnTempN) {
                FF_Nursery_Heater.sendCommand(ON)
            } else if (tempN >= turnOffTempN) {
                FF_Nursery_Heater.sendCommand(OFF)
            }
       else {
            FF_Nursery_Heater.sendCommand(OFF)
        	}
        
    }
end

Something else i’m thinking about trying to accomplish is putting a small display at each unit with 2 buttons for UP and DOWN modifying the openhab set point.
When attaching a switch the the ESP and pushing a momentary button i see this in the serial console:

SW   : State 0
EVENT: Nursery_Temp_Up#NUR_TEMP_UP=0.00
SW   : State 1
EVENT: Nursery_Temp_Up#NUR_TEMP_UP=1.00

in OH items how can I filter out either the 1.00 or 0.00 since I want a dedicated switch for up and down?

Switch Nursery_Temp_Up      "Nursery HW_TMP_UP"	{mqtt="<[oh2:/Nursery/Nursery_Temp_Up/NUR_TEMP_UP:state:default]" }

I’m still trying to figure it out on my own but don’t mind some guidance :slight_smile:

You could use the map transformation:

Switch Nursery_Temp_Up "Nursery HW_TMP_UP" {mqtt="<[oh2:/Nursery/Nursery_Temp_Up/NUR_TEMP_UP:state:MAP(onoff.map)]" }

onoff.map:

0.00=OFF
1.00=ON

Make sure you have the MAP transformation service installed.

oh good i was just reading about this map thing.
could i use the onoff map to ignore one or the other?
like
0.00=ON (and eventually use that as a temp up or down)
then just dont even map the 1.00?

Haven’t tried that.
I would use it the normal way first and if that works try the other way around :grinning:

btw, thanks for all your help in the past and going forward, its much appreciated

ultimately this switch will modify the setpoint
Number VT_Heating_Setpoint_Nursery “Nursery Setpoint [%.1f °F]”
i’m probably not looking at that until at least tomorrow. then the buttons will update this set point and when the setpoint changes it’ll send mqtt messages (or http cmds back to the esp, either way) that will update a value on the display representing the set point in openhab. i hope this all doesn’t sound crazy. to me it sounds like a cool project, if i can make it work. then every room can have its own little thermostat. eventually, when enough rooms call for heat or cool that can then modify the set point of my nest. :smiley:

I guess there’s really no reason to ignore on or off is there?

I would just be using if = on to change things so off doesn’t particularly matter.

EDIT
i had a few more minutes. I can at least get the button to increment a variable.

rule "Nursery Temp Control"
when
	Item Nursery_Temp_Up changed
then
	if (Nursery_Temp_Up.state == OFF) {
	setpointN = setpointN + 1
	logInfo("buttonpress: ", setpointN.toString)	
	}

results in this in the log

2017-03-06 15:35:32.083 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'demo.rules'
2017-03-06 15:35:36.985 [INFO ] [smarthome.model.script.buttonpress: ] - 71
2017-03-06 15:35:40.863 [INFO ] [smarthome.model.script.buttonpress: ] - 72

now need to figure out how to make it modify VT_Heating_Setpoint_Nursery instead