Last active
December 31, 2019 10:46
-
-
Save cyclingengineer/9923758 to your computer and use it in GitHub Desktop.
OpenHAB Heating Control Rules
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
OpenHAB Heating Example | |
======================== | |
This heating example shows three rooms in my house with 1 radiator valve, 1 temperature sensor per room and a single boiler. It could be adapted for different situations. | |
The rules allow for simple addition of items in rooms as long as they follow the naming convention and have at least a valve, a thermometer, setpoint and a demand switch. | |
The demand switch is purely internal and is used to indicate if the room requires heat or not. All rooms are OR'd together to define the boiler status and each room demand (On/Off) is applied to the radiator valves. | |
It could be more generic for multiple thermometers/valves per room - but it suits my needs for now. If I make it more generic I will update it accordingly. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Heating Control Items | |
* Contains the items used to manage the house heating system. This includes | |
* temperature monitors and radiators */ | |
/* Groups */ | |
Group gf_heating | |
Group gf_heating_temps (gf_heating) | |
Group gf_heating_humidity (gf_heating) | |
Group gf_heating_valves (gf_heating) | |
Group gf_heating_sources (gf_heating) | |
Group gf_heating_setpoint (gf_heating, ctrl_heating_setpoint) | |
Group:Switch:OR(ON, OFF) gf_heating_demand (gf_heating, ctrl_heating_demand) | |
Group ff_heating | |
Group ff_heating_temps (ff_heating) | |
Group ff_heating_humidity (ff_heating) | |
Group ff_heating_valves (ff_heating) | |
Group ff_heating_sources (ff_heating) | |
Group ff_heating_setpoint (ff_heating, ctrl_heating_setpoint) | |
Group:Switch:OR(ON, OFF) ff_heating_demand (ff_heating, ctrl_heating_demand) | |
Group:Switch:OR(ON, OFF) ctrl_heating_demand (ctrl) | |
Group ctrl_heating_setpoint (ctrl) | |
/* Chart groups */ | |
Group chart_lounge_heating | |
Group chart_kitchen_heating | |
Group chart_bedroom1_heating | |
/* Boiler & heat sources */ | |
Switch gf_utility_heating_Boiler "Boiler Status [MAP(BoilerStatus.map):%s]" <heating> (gf_heating_sources, gf_utility) { jeelinkha=">0.0:SALUSRT500RF:Command" } | |
/* Lounge */ | |
Number gf_lounge_heating_RadTherm "Lounge Rad Therm [%.1f °C]" <heating> (gf_lounge, gf_heating_valves) { maxcube="XXXXXXXXX", autoupdate="false"} | |
Number gf_lounge_heating_temp "Lounge Temperature [%.1f °C]" <temperature> (gf_lounge, gf_heating_temps, chart_lounge_heating) { rfxcom="<47361:Temperature" } | |
Number gf_lounge_heating_humidity "Lounge Humidity [%.1f %%]" <temperature> (gf_lounge, gf_heating_humidity) { rfxcom="<XXXXX:Humidity" } | |
Number gf_lounge_heating_setpoint "Lounge Set Temp [%.1f °C]" <temperature> (gf_lounge, gf_heating_setpoint, chart_lounge_heating) | |
Switch gf_lounge_heating_demand "Lounge Heating Demand [MAP(BoilerStatus.map):%s]" <temperature> (gf_lounge, gf_heating_demand) | |
Number gf_lounge_heating_valvePos "Lounge Valve Pos [%d %%]" <heating> (gf_lounge, gf_heating_valves) { maxcube="XXXXXXXX:type=valve", autoupdate="false"} | |
/* Kitchen */ | |
Number gf_kitchen_heating_RadTherm "Kitchen Rad Therm [%.1f °C]" <heating> (gf_kitchen, gf_heating_valves) { maxcube="XXXXXXX", autoupdate="false"} | |
Number gf_kitchen_heating_temp "Kitchen Temperature [%.1f °C]" <temperature> (gf_kitchen, gf_heating_temps, chart_kitchen_heating) { rfxcom="<XXXXXX:Temperature" } | |
Number gf_kitchen_heating_humidity "Kitchen Humidity [%.1f %%]" <temperature> (gf_kitchen, gf_heating_humidity) { rfxcom="<XXXXX:Humidity" } | |
Number gf_kitchen_heating_setpoint "Kitchen Set Temp [%.1f °C]" <temperature> (gf_kitchen, gf_heating_setpoint, chart_kitchen_heating) | |
Switch gf_kitchen_heating_demand "Kitchen Heating Demand [MAP(BoilerStatus.map):%s]" <temperature> (gf_kitchen, gf_heating_demand) | |
Number gf_kitchen_heating_valvePos "Kitchen Valve Pos [%d %%]" <heating> (gf_kitchen, gf_heating_valves) { maxcube="XXXXXXXX:type=valve", autoupdate="false"} | |
/* FF main front bedroom - bedroom 1 */ | |
Number ff_bedroom1_heating_RadTherm "Bedroom Rad Therm [%.1f °C]" <heating> (ff_bedroom1, ff_heating_valves) { maxcube="XXXXXXXXX", autoupdate="false"} | |
Number ff_bedroom1_heating_temp "Bedroom Temperature [%.1f °C]" <temperature> (ff_bedroom1, ff_heating_temps, chart_bedroom1_heating) { rfxcom="<XXXX:Temperature" } | |
Number ff_bedroom1_heating_humidity "Bedroom Humidity [%.1f %%]" <temperature> (ff_bedroom1, ff_heating_humidity) { rfxcom="<XXXXX:Humidity" } | |
Number ff_bedroom1_heating_setpoint "Bedroom Set Temp [%.1f °C]" <temperature> (ff_bedroom1, ff_heating_setpoint, chart_bedroom1_heating) | |
Switch ff_bedroom1_heating_demand "Bedroom Heating Demand [MAP(BoilerStatus.map):%s]" <temperature> (ff_bedroom1, ff_heating_demand) | |
Number ff_bedroom1_heating_valvePos "Bedroom Valve Pos [%d %%]" <heating> (ff_bedroom1, ff_heating_valves) { maxcube="XXXXXXX:type=valve", autoupdate="false"} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.openhab.core.library.types.* | |
val Number hysteresis = 0.3 | |
rule "Heating - demand check" | |
when | |
Item ctrl_heating_setpoint received update | |
or Item gf_heating_temps received update | |
or Item ff_heating_temps received update | |
then | |
ctrl_heating_setpoint?.allMembers.forEach[sp| | |
/* strip off _setpoint */ | |
logDebug("Setpoint - ",sp.name) | |
val String base_name = sp.name.substring(0, sp.name.indexOf("_setpoint")) | |
var OnOffType oldState = house.allMembers.filter(m | m.name.equals(base_name+"_demand")).last.state as OnOffType | |
var OnOffType newState = oldState | |
/* find _temp - should only come up with 1 */ | |
val temp = house.allMembers.filter(m | m.name.equals(base_name+"_temp")).last.state as DecimalType | |
logDebug(base_name+"_temp state => ",temp.toString) | |
logDebug(base_name+"_setpoint state => ",sp.state.toString) | |
/* compare _temp and _setpoint then set _demand*/ | |
if (oldState == ON) | |
{ | |
if (temp >= (sp.state as DecimalType)) | |
{ | |
newState = OFF | |
} else | |
{ | |
newState = ON | |
} | |
} else { | |
if (temp < (sp.state as DecimalType) - hysteresis) | |
{ | |
newState = ON | |
} else | |
{ | |
newState = OFF | |
} | |
} | |
if (newState != oldState) | |
{ | |
postUpdate(house.allMembers.filter(m | m.name.equals(base_name+"_demand")).last,newState) | |
sendCommand(house.allMembers.filter(m | m.name.equals(base_name+"_RadTherm")).last, newState) | |
} | |
logDebug(base_name+"_demand state => ",house.allMembers.filter(m | m.name.equals(base_name+"_demand")).last.state.toString) | |
] | |
end | |
rule "Heating - Boiler Control" | |
when | |
Time cron "0 * * * * ?" | |
then | |
logDebug("Demand group state", (ctrl_heating_demand.state as OnOffType).toString) | |
sendCommand(gf_utility_heating_Boiler, ctrl_heating_demand.state as OnOffType) | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Top Level | |
* Contains top level items - this is to manage top level groups | |
*/ | |
/* Whole house */ | |
Group house | |
/* Ground floor (gf) groups */ | |
Group gf (house) | |
Group gf_utility (gf) | |
Group gf_lounge (gf) | |
Group gf_kitchen (gf) | |
Group gf_hallway (gf) | |
Group gf_toilet (gf) | |
/* First floor (ff) groups */ | |
Group ff (house) | |
Group ff_bedroom1 (ff) | |
Group ff_bedroom2 (ff) | |
Group ff_bedroom3 (ff) | |
Group ff_bathroom (ff) | |
Group ff_landing (ff) | |
Group ff_stairs (ff) | |
/* Control groups - used for rules */ | |
Group ctrl |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment