Awesome. The code is technically stored in /var/lib/openhab2/jsondb/automation_rules.json
but you’ll probably want to update it via the OpenHAB PaperUI (under Configuration → Rules, IIRC).
You’ll find rules like “HeatingCtrl received command” which has the code when the heat should be turned on:
"description": "Control the fan"
}
},
"05a775d5-554d-4bf9-9012-166e6a217d6d": {
"class": "org.openhab.core.automation.dto.RuleDTO",
"value": {
"triggers": [
{
"id": "1",
"label": "HeatingCtrl received command",
"description": "This triggers the rule if an item receives a command.",
"configuration": {
"itemName": "HeatingCtrl"
},
"type": "core.ItemCommandTrigger"
}
],
"conditions": [
{
"inputs": {},
"id": "3",
And cooling:
"description": "Determines if the humidifier/dehumidifier should turn on"
}
},
"79e9a0ba-b377-4324-ac31-e187674a13f1": {
"class": "org.openhab.core.automation.dto.RuleDTO",
"value": {
"triggers": [
{
"id": "1",
"label": "CoolingCtrl",
"description": "This triggers the rule if an item receives a command.",
"configuration": {
"itemName": "CoolingCtrl"
},
"type": "core.ItemCommandTrigger"
}
],
"conditions": [
{
"inputs": {},
"id": "2",
And the logic for when to trigger the heating or cooling:
"type": "application/javascript",
"script": "var OPENHAB_CONF \u003d Java.type(\u0027java.lang.System\u0027).getenv(\u0027OPENHAB_CONF\u0027);\nload(OPENHAB_CONF + \u0027/automation/lib/hestia/utils.js\u0027);\n\nvar logName\u003d\"heatcool\";\n\nvar minSP \u003d items[\"MinTempSetpoint\"].class;\nvar maxSP \u003d items[\"MaxTempSetpoint\"].class;\nvar hyst \u003d items[\"Comfort_Value\"].class;\nvar temp \u003d items[\"MyTempProxy\"].class;\nvar comfMode \u003d items[\"Comfort_Mode\"].class;\n\nvar ok \u003d (minSP !\u003d UnDefType.class \u0026\u0026\n hyst !\u003d UnDefType.class \u0026\u0026\n temp !\u003d UnDefType.class \u0026\u0026\n comfMode !\u003d UnDefType.class);\nif(items[\"SystemType\"] \u003d\u003d \"US\") ok \u003d (ok \u0026\u0026 maxSP !\u003d UnDefType.class);\n\nif(!ok){\n if(items[\"SystemType\"] \u003d\u003d \"US\"){\n logError(logName, \"Cannot determine heating/cooling: MinTempSetpoint \u003d \" + items[\"MinTempSetpoint\"] + \" MaxTempSetpoint \u003d \" + items[\"MaxTempSetpoint\"] + \" MyTempProxy \u003d \" + items[\"MyTempProxy\"] + \" Comfort_Value \u003d \" + items[\"Comfort_Value\"]);\n }\n else {\n logError(logName, \"Cannot determine heating: MinTempSetpoint \u003d \" + items[\"MinTempSetpoint\"] + \" MyTempProxy \u003d \" + items[\"MyTempProxy\"] + \" Comfort_Value \u003d \" + items[\"Comfort_Value\"]);\n }\n}\n\n(ok);"
},
"type": "script.ScriptCondition"
}
],
"actions": [
{
"inputs": {},
"id": "3",
"label": "Determines whether to turn on/off the heater/ac based on temp and setpoint.",
"description": "Sends command to Heating/CoolingCtrl to change device\u0027s state.",
"configuration": {
"type": "application/javascript",
"script": "var OPENHAB_CONF \u003d Java.type(\u0027java.lang.System\u0027).getenv(\u0027OPENHAB_CONF\u0027);\nload(OPENHAB_CONF + \u0027/automation/lib/hestia/utils.js\u0027);\nload(OPENHAB_CONF + \u0027/automation/lib/hestia/defaults.js\u0027);\n\nvar mode \u003d event.itemName.replace(\"Check\", \"\");\nvar temp \u003d items[\"MyTempProxy\"].floatValue();\n\nvar minDelta \u003d items[\"MinTempSetpoint\"].floatValue() - temp; // positive means below setpoint, heating\nvar maxDelta \u003d temp - items[\"MaxTempSetpoint\"].floatValue(); // positive means above setpoint\nvar delta \u003d (mode \u003d\u003d \"Heating\") ? minDelta : maxDelta;\n\nvar comfHyst \u003d DEFAULTS.get(items[\"TempUnit\"]+\"_COMFORT_DEF\");\nvar ecoHyst \u003d items[\"Comfort_Value\"].floatValue();\nvar hysteresis \u003d (items[\"Comfort_Mode\"] \u003d\u003d \"COMFORT\") ? comfHyst : ecoHyst;\n\nvar turnOn \u003d (items[mode+\"Mode\"] \u003d\u003d \"Boost\" || delta \u003e\u003d hysteresis);\nvar turnOff \u003d delta \u003c\u003d 0;\n\nif(turnOn) {\n logInfo(\"heatingcooling\", \"TURN ON \" + mode + \": heating delta is \" + minDelta + \" cooling delta is \" + maxDelta + \" hysteresis is \" + hysteresis);\n events.sendCommand(mode+\"Ctrl\", \"ON\");\n}\nelse if(turnOff){\n logInfo(\"heatingcooling\", \"TURN OFF \" + mode + \": heating delta is \" + minDelta + \" cooling delta is \" + maxDelta + \" hysteresis is \" + hysteresis);\n events.sendCommand(mode+\"Ctrl\", \"OFF\");\n}\nelse {\n logInfo(\"heatingcooling\", \"Nothing to do: mode \u003d \" + mode + \" temp \u003d \" + temp + \" hysteresis \u003d \" + hysteresis + \" min delta \u003d \" + minDelta + \" max delta \u003d \" + maxDelta);\n}\n\nsleep(10); // keep the rule from running again too soon"
},
"type": "script.ScriptAction"
}
],
"configuration": {},
"configDescriptions": [],
I find the text file easier to navigate to figure out which rules I should look into and then I use the PaperUI to actually look at and modify the code. I’d highly recommend making a backup before and after you make changes.
If you want to contribute your changes back, it’d be very cool to have a third mode (US-Heat-Pump) to add to the existing US and EU modes. Then if you ever have to re-flash the card you won’t have to re-apply all your changes. Just switch from US to US-Heat-Pump and you’ll be good to go.