I am not a programmer, so I am embarrassed to share it since I know it could be simplified. Each thermostat temp, heat setpoint, cool setpoint, and mode state are part of a group for each floor named Foo, Bar, and Baz. The group from each floor allows me to reconfigure my dampers any time there is a temp change in a room, mode of the thermostat changes, or someone changes the heat or cool setpoints.
hvac.rules:
rule "Basement Dampers"
when
Item Foo changed
then
// Heat Basement
if (Basement_Tstat_HeatSetPoint.state > Basement_Tstat_Temperature.state) {
if (Basement_Tstat_Temperature.state > Basement_HVAC_Supply.state) {
sendCommand(Basement_Damper, ON)
} else {
sendCommand(Basement_Damper, OFF)
}
// Cool Basement
} else if (Basement_Tstat_CoolSetPoint.state < Basement_Tstat_Temperature.state) {
if (Basement_Tstat_Temperature.state < Basement_HVAC_Supply.state) {
sendCommand(Basement_Damper, ON)
} else {
sendCommand(Basement_Damper, OFF)
}
} else {
sendCommand(Basement_Damper, ON)
}
// Heat Office
if (Office_Tstat_HeatSetPoint.state > Office_Tstat_Temperature.state) {
if (Office_Tstat_Temperature.state > Basement_HVAC_Supply.state) {
sendCommand(Office_Damper, ON)
} else {
sendCommand(Office_Damper, OFF)
}
// Cool Office
} else if (Office_Tstat_CoolSetPoint.state < Office_Tstat_Temperature.state) {
if (Office_Tstat_Temperature.state < Basement_HVAC_Supply.state) {
sendCommand(Office_Damper, ON)
} else {
sendCommand(Office_Damper, OFF)
}
} else {
sendCommand(Office_Damper, ON)
}
// Heat Shop
if (Shop_Tstat_HeatSetPoint.state > Shop_Tstat_Temperature.state) {
if (Shop_Tstat_Temperature.state > Basement_HVAC_Supply.state) {
sendCommand(Shop_Damper, ON)
} else {
sendCommand(Shop_Damper, OFF)
}
// Cool Shop
} else if (Shop_Tstat_CoolSetPoint.state < Shop_Tstat_Temperature.state) {
if (Shop_Tstat_Temperature.state < Basement_HVAC_Supply.state) {
sendCommand(Shop_Damper, ON)
} else {
sendCommand(Shop_Damper, OFF)
}
} else {
sendCommand(Shop_Damper, ON)
}
// Heat Electric_Room
if (Electric_Room_Tstat_HeatSetPoint.state > Electric_Room_Tstat_Temperature.state) {
if (Electric_Room_Tstat_Temperature.state > Basement_HVAC_Supply.state) {
sendCommand(Electric_Room_Damper, ON)
} else {
sendCommand(Electric_Room_Damper, OFF)
}
// Cool Electric_Room
} else if (Electric_Room_Tstat_CoolSetPoint.state < Electric_Room_Tstat_Temperature.state) {
if (Electric_Room_Tstat_Temperature.state < Basement_HVAC_Supply.state) {
sendCommand(Electric_Room_Damper, ON)
} else {
sendCommand(Electric_Room_Damper, OFF)
}
} else {
sendCommand(Electric_Room_Damper, ON)
}
// Heat Water_Room
if (Water_Room_Tstat_HeatSetPoint.state > Water_Room_Tstat_Temperature.state) {
if (Water_Room_Tstat_Temperature.state > Basement_HVAC_Supply.state) {
sendCommand(Water_Room_Damper, ON)
} else {
sendCommand(Water_Room_Damper, OFF)
}
// Cool Water_Room
} else if (Water_Room_Tstat_CoolSetPoint.state < Water_Room_Tstat_Temperature.state) {
if (Water_Room_Tstat_Temperature.state < Basement_HVAC_Supply.state) {
} else {
sendCommand(Water_Room_Damper, OFF)
}
} else {
sendCommand(Water_Room_Damper, ON)
}
// Heat Basement_Storage
if (Basement_Storage_Tstat_HeatSetPoint.state > Basement_Storage_Tstat_Temperature.state) {
if (Basement_Storage_Tstat_Temperature.state > Basement_HVAC_Supply.state) {
sendCommand(Basement_Storage_Damper, ON)
} else {
sendCommand(Basement_Storage_Damper, OFF)
}
// Cool Basement_Storage
} else if (Basement_Storage_Tstat_CoolSetPoint.state < Basement_Storage_Tstat_Temperature.state) {
if (Basement_Storage_Tstat_Temperature.state < Basement_HVAC_Supply.state) {
sendCommand(Basement_Storage_Damper, ON)
} else {
sendCommand(Basement_Storage_Damper, OFF)
}
} else {
sendCommand(Basement_Storage_Damper, OFF)
}
end
rule "First FLoor Dampers"
when
Item Bar changed
then
// Heat First_Floor
if (First_Floor_Tstat_HeatSetPoint.state > First_Floor_Tstat_Temperature.state) {
if (First_Floor_Tstat_Temperature.state > First_Floor_HVAC_Supply.state) {
sendCommand(First_Floor_Damper, ON)
} else {
sendCommand(First_Floor_Damper, OFF)
}
// Cool First_Floor
} else if (First_Floor_Tstat_CoolSetPoint.state < First_Floor_Tstat_Temperature.state) {
if (First_Floor_Tstat_Temperature.state < First_Floor_HVAC_Supply.state) {
sendCommand(First_Floor_Damper, ON)
} else {
sendCommand(First_Floor_Damper, OFF)
}
} else {
sendCommand(First_Floor_Damper, ON)
}
// Heat Living_Room
if (Living_Room_Tstat_HeatSetPoint.state > Living_Room_Tstat_Temperature.state) {
if (Living_Room_Tstat_Temperature.state > First_Floor_HVAC_Supply.state) {
sendCommand(Living_Room_Damper, ON)
} else {
sendCommand(Living_Room_Damper, OFF)
}
// Cool Living_Room
} else if (Living_Room_Tstat_CoolSetPoint.state < Living_Room_Tstat_Temperature.state) {
if (Living_Room_Tstat_Temperature.state < First_Floor_HVAC_Supply.state) {
sendCommand(Living_Room_Damper, ON)
} else {
sendCommand(Living_Room_Damper, OFF)
}
} else {
sendCommand(Living_Room_Damper, ON)
}
// Heat Master_Bedroom
if (Master_Bedroom_Tstat_HeatSetPoint.state > Master_Bedroom_Tstat_Temperature.state) {
if (Master_Bedroom_Tstat_Temperature.state > First_Floor_HVAC_Supply.state) {
sendCommand(Master_Bedroom_Damper, ON)
} else {
sendCommand(Master_Bedroom_Damper, OFF)
}
// Cool Master_Bedroom
} else if (Master_Bedroom_Tstat_CoolSetPoint.state < Master_Bedroom_Tstat_Temperature.state) {
if (Master_Bedroom_Tstat_Temperature.state < First_Floor_HVAC_Supply.state) {
sendCommand(Master_Bedroom_Damper, ON)
} else {
sendCommand(Master_Bedroom_Damper, OFF)
}
} else {
sendCommand(Master_Bedroom_Damper, ON)
}
// Heat Guest_Bedroom
if (Guest_Bedroom_Tstat_HeatSetPoint.state > Guest_Bedroom_Tstat_Temperature.state) {
if (Guest_Bedroom_Tstat_Temperature.state > First_Floor_HVAC_Supply.state) {
sendCommand(Guest_Bedroom_Damper, ON)
} else {
sendCommand(Guest_Bedroom_Damper, OFF)
}
// Cool Guest_Bedroom
} else if (Guest_Bedroom_Tstat_CoolSetPoint.state < Guest_Bedroom_Tstat_Temperature.state) {
if (Guest_Bedroom_Tstat_Temperature.state < First_Floor_HVAC_Supply.state) {
sendCommand(Guest_Bedroom_Damper, ON)
} else {
sendCommand(Guest_Bedroom_Damper, OFF)
}
} else {
sendCommand(Guest_Bedroom_Damper, ON)
}
// Heat Kitchen
if (Kitchen_Tstat_HeatSetPoint.state > Kitchen_Tstat_Temperature.state) {
if (Kitchen_Tstat_Temperature.state > First_Floor_HVAC_Supply.state) {
sendCommand(Kitchen_Damper, ON)
} else {
sendCommand(Kitchen_Damper, OFF)
}
// Cool Kitchen
} else if (Kitchen_Tstat_CoolSetPoint.state < Kitchen_Tstat_Temperature.state) {
if (Kitchen_Tstat_Temperature.state < First_Floor_HVAC_Supply.state) {
sendCommand(Kitchen_Damper, ON)
} else {
sendCommand(Kitchen_Damper, OFF)
}
} else {
sendCommand(Kitchen_Damper, ON)
}
end
rule "Second FLoor Dampers"
when
Item Baz changed
then
// Heat Second_Floor
if (Second_Floor_Tstat_HeatSetPoint.state > Second_Floor_Tstat_Temperature.state) {
if (Second_Floor_Tstat_Temperature.state > Second_Floor_HVAC_Supply.state) {
sendCommand(Second_Floor_Damper, ON)
} else {
sendCommand(Second_Floor_Damper, OFF)
}
// Cool Second_Floor
} else if (Second_Floor_Tstat_CoolSetPoint.state < Second_Floor_Tstat_Temperature.state) {
if (Second_Floor_Tstat_Temperature.state < Second_Floor_HVAC_Supply.state) {
sendCommand(Second_Floor_Damper, ON)
} else {
sendCommand(Second_Floor_Damper, OFF)
}
} else {
sendCommand(Second_Floor_Damper, OFF)
}
// Heat Great_Room
if (Great_Room_Tstat_HeatSetPoint.state > Great_Room_Tstat_Temperature.state) {
if (Great_Room_Tstat_Temperature.state > Second_Floor_HVAC_Supply.state) {
sendCommand(Great_Room_Damper, ON)
} else {
sendCommand(Great_Room_Damper, OFF)
}
// Cool Great_Room
} else if (Great_Room_Tstat_CoolSetPoint.state < Great_Room_Tstat_Temperature.state) {
if (Great_Room_Tstat_Temperature.state < Second_Floor_HVAC_Supply.state) {
sendCommand(Great_Room_Damper, ON)
} else {
sendCommand(Great_Room_Damper, OFF)
}
} else {
sendCommand(Great_Room_Damper, ON)
}
// Heat Emma_Bedroom
if (Emma_Bedroom_Tstat_HeatSetPoint.state > Emma_Bedroom_Tstat_Temperature.state) {
if (Emma_Bedroom_Tstat_Temperature.state > Second_Floor_HVAC_Supply.state) {
sendCommand(Emma_Bedroom_Damper, ON)
} else {
sendCommand(Emma_Bedroom_Damper, OFF)
}
// Cool Emma_Bedroom
} else if (Emma_Bedroom_Tstat_CoolSetPoint.state < Emma_Bedroom_Tstat_Temperature.state) {
if (Emma_Bedroom_Tstat_Temperature.state < Second_Floor_HVAC_Supply.state) {
sendCommand(Emma_Bedroom_Damper, ON)
} else {
sendCommand(Emma_Bedroom_Damper, OFF)
}
} else {
sendCommand(Emma_Bedroom_Damper, ON)
}
// Heat Joshua_Bedroom
if (Joshua_Bedroom_Tstat_HeatSetPoint.state > Joshua_Bedroom_Tstat_Temperature.state) {
if (Joshua_Bedroom_Tstat_Temperature.state > Second_Floor_HVAC_Supply.state) {
sendCommand(Joshua_Bedroom_Damper, ON)
} else {
sendCommand(Joshua_Bedroom_Damper, OFF)
}
// Cool Joshua_Bedroom
} else if (Joshua_Bedroom_Tstat_CoolSetPoint.state < Joshua_Bedroom_Tstat_Temperature.state) {
if (Joshua_Bedroom_Tstat_Temperature.state < Second_Floor_HVAC_Supply.state) {
sendCommand(Joshua_Bedroom_Damper, ON)
} else {
sendCommand(Joshua_Bedroom_Damper, OFF)
}
} else {
sendCommand(Joshua_Bedroom_Damper, ON)
}
// Heat Breezeway
if (Breezeway_Tstat_HeatSetPoint.state > Breezeway_Tstat_Temperature.state) {
if (Breezeway_Tstat_Temperature.state > Second_Floor_HVAC_Supply.state) {
sendCommand(Breezeway_Damper, ON)
} else {
sendCommand(Breezeway_Damper, OFF)
}
// Cool Breezeway
} else if (Breezeway_Tstat_CoolSetPoint.state < Breezeway_Tstat_Temperature.state) {
if (Breezeway_Tstat_Temperature.state < Second_Floor_HVAC_Supply.state) {
sendCommand(Breezeway_Damper, ON)
} else {
sendCommand(Breezeway_Damper, OFF)
}
} else {
sendCommand(Breezeway_Damper, ON)
}
// Heat Apartment
if (Apartment_Tstat_HeatSetPoint.state > Apartment_Tstat_Temperature.state) {
if (Apartment_Tstat_Temperature.state > Second_Floor_HVAC_Supply.state) {
sendCommand(Apartment_Damper, ON)
} else {
sendCommand(Apartment_Damper, OFF)
}
// Cool Apartment
} else if (Apartment_Tstat_CoolSetPoint.state < Apartment_Tstat_Temperature.state) {
if (Apartment_Tstat_Temperature.state < Second_Floor_HVAC_Supply.state) {
sendCommand(Apartment_Damper, ON)
} else {
sendCommand(Apartment_Damper, OFF)
}
} else {
sendCommand(Apartment_Damper, ON)
}
// Heat Mom_Bedroom
if (Mom_Bedroom_Tstat_HeatSetPoint.state > Mom_Bedroom_Tstat_Temperature.state) {
if (Mom_Bedroom_Tstat_Temperature.state > Second_Floor_HVAC_Supply.state) {
sendCommand(Mom_Bedroom_Damper, ON)
} else {
sendCommand(Mom_Bedroom_Damper, OFF)
}
// Cool Mom_Bedroom
} else if (Mom_Bedroom_Tstat_CoolSetPoint.state < Mom_Bedroom_Tstat_Temperature.state) {
if (Mom_Bedroom_Tstat_Temperature.state < Second_Floor_HVAC_Supply.state) {
sendCommand(Mom_Bedroom_Damper, ON)
} else {
sendCommand(Mom_Bedroom_Damper, OFF)
}
} else {
sendCommand(Mom_Bedroom_Damper, ON)
}
// Heat Dad_Bedroom
if (Dad_Bedroom_Tstat_HeatSetPoint.state > Dad_Bedroom_Tstat_Temperature.state) {
if (Dad_Bedroom_Tstat_Temperature.state > Second_Floor_HVAC_Supply.state) {
sendCommand(Dad_Bedroom_Damper, ON)
} else {
sendCommand(Dad_Bedroom_Damper, OFF)
}
// Cool Dad_Bedroom
} else if (Dad_Bedroom_Tstat_CoolSetPoint.state < Dad_Bedroom_Tstat_Temperature.state) {
if (Dad_Bedroom_Tstat_Temperature.state < Second_Floor_HVAC_Supply.state) {
sendCommand(Dad_Bedroom_Damper, ON)
} else {
sendCommand(Dad_Bedroom_Damper, OFF)
}
} else {
sendCommand(Dad_Bedroom_Damper, ON)
}
end
rule "HVAC_Delta"
when
Time cron "0 * * * * ?"
then
postUpdate(Basement_HVAC_Delta, (Basement_HVAC_Supply.state as Number) - (Basement_HVAC_Return.state as Number))
postUpdate(First_Floor_HVAC_Delta, (First_Floor_HVAC_Supply.state as Number) - (First_Floor_HVAC_Return.state as Number))
postUpdate(Second_Floor_HVAC_Delta, (Second_Floor_HVAC_Supply.state as Number) - (Second_Floor_HVAC_Return.state as Number))
end