Virtual thermostat

I had a need to control electric heaters via thermostat. I built a virtual thermostat consisting of a temp sensor (Fibaro Universal Binary Sensor FGBS0001 + DS18B20), z-wave switch/socket and some OH rules. DS18B20 temp sensor is either attached to the heater (if I want to control the heater temp, like the for towel hanger in the bathroom), embedded in floor (for floor heating) or is measuring ambient temperature.

There are four items per each virtual thermostat:

Sensor:
Number Sensor_Temp_Towels "Towel's heater [%.2f °C]" <temperature> { zwave="5:3:command=sensor_multilevel" }
Thermostat:
Number Thermostat_Towels "Towel's heater [%.1f °C]" <heating> (G_Bathroom,Thermostats)
Thermostat switch (for the sitemap):
Switch Sw_Heater_Towels "Towel's heater" <heating> (G_Bathroom, Heating)

Execution switch (for controling z-wave execution item)
Switch Sw_Heater_Towels_exec "Towel's heater exec" <heating> (G_Bathroom, Heating) { zwave="14:1:command=SWITCH_BINARY,refresh_interval=60" }

Sitemap example:
In the bathroom section:

Switch item=Sw_Heater_Towels
Setpoint item=Thermostat_Towels step=0.5 minValue=18 maxValue=45

Rule:

rule "Thermostat towels"
        when
            Item Sensor_Temp_Towels changed or
            Item Thermostat_Towels changed or
            Item Sw_Heater_Towels changed
        then
            if (Thermostat_Towels.state == Uninitialized) postUpdate(Thermostat_Towels,32)
            if (Sw_Heater_Towels.state==OFF) sendCommand(Sw_Heater_Towels_exec,OFF)
            if (Sensor_Temp_Towels.state>Thermostat_Towels.state && Sw_Heater_Towels_exec.state==ON ) {
                logInfo("Heater","Towel heater off")
                sendCommand(Switch Sw_Heater_Towels_exec,OFF)
            }
            if (Sensor_Temp_Towels.state<Thermostat_Towels.state && Sw_Heater_Towels.state==ON)       {
                logInfo("Heater","Towel heater on")
                sendCommand(Switch Sw_Heater_Towels_exec,ON)
            }
end

Thanks for sharing, the only problem I can see is that if you manually turn off your heater (Sw_Heater_Towels) and the temp sensor is below your threshold, it will just turn back on again, in the second half of your rule.

Here is a very similar rule I use;

rule "Nursery heating"
when
    Item VT_Heating_Mode_Nursery changed or
    Item VT_Heating_Setpoint_Nursery changed or
    Item FF_Nursery_Temp changed or 
    Item FF_Nursery_Window 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) {
        // only fire up the heater if the nursery window is closed
        if (FF_Nursery_Window.state == CLOSED) {
            // get the current setpoint for the nursery
            var Number setpoint = VT_Heating_Setpoint_Nursery.state as DecimalType

            // calculate the turn on/off temperatures
            var Number turnOnTemp = setpoint - 0.5
            var Number turnOffTemp = setpoint + 0.5

            // get the current temperature in the nursery
            var Number temp = FF_Nursery_Temp.state as DecimalType
            
            // determine whether we need to turn on/off the heater
            if (temp <= turnOnTemp) {
                // turn on temp has been reached so switch on the heater
                FF_Nursery_Heater.sendCommand(ON)
            } else if (temp >= turnOffTemp) {
                // turn off temp has been reached so switch off the heater
                FF_Nursery_Heater.sendCommand(OFF)
            }
        } else {
            // heater off
            FF_Nursery_Heater.sendCommand(OFF)
        }
    }
end

Using the following items;

// heating setpoints
Number      VT_Heating_Setpoint_Nursery "Nursery Setpoint [%.1f °C]"    <degreesc>

// heating modes: 0 - Off, 1 - On, 2 - Auto
Number      VT_Heating_Mode_Nursery     "Nursery Heating Mode"          <heating>

Switch      FF_Nursery_Heater           "Nursery Heater"         <fire>          { zwave="32:command=SWITCH_BINARY" }
Number      FF_Nursery_Temp             "Nursery [%.1f °C]"      <temperature>   { rfxcom="<14082:Temperature" }

Then finally in my sitemap;

                Switch item=VT_Heating_Mode_Nursery label="Heating Mode" mappings=[0="Off", 1="On", 2="Auto"]
                Setpoint item=VT_Heating_Setpoint_Nursery label="Target Temperature [%.1f °C]" minValue=16 maxValue=24 step=0.5 visibility=[VT_Heating_Mode_Nursery==2]
                Text item=FF_Nursery_Heater

So I can either manually override and set the heater on/off, or set it to auto and adjust the setpoint to control the temp. The Text item=FF_Nursery_Heater just shows the state of the heater, i.e. whether it is on or off.

4 Likes

Hi ben_jones12

I have used your code and it works great but im having issues with endpoint temperature set for auto mode its very slow and unresponsive sometimes i have to keep pressing and it wount change right away.