Heizungsschalter
für eine Oekofen Heizung mit Openhab
Motivation
Die meisten Leute schalten das Licht aus, wenn sie Haus oder Wohnung verlassen. Der größte Energieverbraucher ist aber die Heizung. Es macht also Sinn, einen Schalter im Flur vor dem Ausgang zu haben, mit dem man die Heizung ausschalten oder absenken kann.
Systemumgebung
Wir haben seit kurzem eine Pelletheizung von Oekofen und schon etwas länger eine Infrastruktur für Hausautomatisierung mit Openhab und Mosquitto.
Komponenten
Schalter
Als Schalter wird ein mit Tasmota geflashter Sonoff SwitchMan M5-1C-86 verwendet. Die geschalteten Ausgänge werden nicht genutzt, dieser Schalter zeigt aber den Schaltzustand über ein LED an. Der Schalter wird als MQTT Thing in Openhab eingerichtet.
Channel |
|
MQTT State Topic |
stat/schalter-heizung/POWER1 |
MQTT Command Topic |
cmnd/schalter-heizung/POWER1 |
Heizung
Heizungen von Ökofen (Pelletronic 4.02b in meinem Fall) haben ein via http zugängliches JSON Interface. Dieses ist unter
http://heizung:4321/****/
zu erreichen. Unter dieser URL findet man eine kurze Dokumentation.
Die Heizung wird entsprechend als HTTP Thing konfiguriert.
UID: http:url:<id> label: Heizung thingTypeUID: http:url configuration: authMode: BASIC_PREEMPTIVE ignoreSSLErrors: false baseURL: http://<ip>:4321/<json-pwd> delay: 3000 stateMethod: GET refresh: 60 commandMethod: GET encoding: iso8859-1 timeout: 3000 bufferSize: 2048 channels: … - id: betriebsart-heizkreis-int channelTypeUID: http:number label: Betriebsart Heizkreis (int) description: "" configuration: mode: READWRITE commandTransformation: - "" stateExtension: all commandExtension: hk1.mode_auto=%2$s stateTransformation: - JSONPATH:$.hk1.mode_auto
Nur der für den Schalter relevante Channel wurde gelistet. Für diesen Schalter wird ein Item angelegt.
label: Betriebsart Heizkreis (int) type: Number category: "" groupNames: - SchalterHeizungGruppe tags: - Point
Die Gruppe kommt im nächsten Abschnitt.
Gruppe HeizungSchalter
Die Synchronisation der Zustände von Schalter und Heizung ist erstaunlich komplex. Um auf alle Zustandsänderungen in einer Rule reagieren zu können wird eine Gruppe benötigt, die beide Items enthält.
Die Gruppe wird als Item vom Typ Gruppe angelegt. Sie hat den Schalter und das Betriebsart-Item als direkte Mitgleder.
Transformation
Der Heizkreis der Heizung hat 4 nummerierte Zustände, während der Schalter nur 2 hat. Deshalb wird folgendes Mapping verwendet:
$ cat /etc/openhab/transform/heizungsschalter.map ON = 1 OFF = 3 # Aus 0 = OFF # Auto 1 = ON # Heizen 2 = ON # Absenken 3 = OFF
Rule
configuration: {} triggers: - id: "1" configuration: groupName: SchalterHeizungGruppe type: core.GroupStateChangeTrigger conditions: [] actions: - inputs: {} id: "2" configuration: considerConditions: true ruleUIDs: - 9809810faf type: core.RunRuleAction
Die Action verweist auf ein Script. Dieses ist eine angepasste Variante aus einem Forumsbeitrag von Udo Hartmann.
// global var has to be defined first (no rules ahead) var Boolean lock = false // check if rule already started if(lock) // and break if true return; // lock rule lock = true val toStateOnOff = [ Item s | var state = s.state.toString if (state != "ON" && state != "OFF") { state = transform("MAP", "heizungsschalter.map", state) } state ] logInfo("test", "HeizungSchalterSync called for " + triggeringItem.name); // get a list of Alarm Switch Items without the triggering one. SchalterHeizungGruppe.members.filter[j|j.name != triggeringItem.name] // only ON/OFF changes should switch .filter[j|toStateOnOff.apply(j) != toStateOnOff.apply(triggeringItem)] .forEach[i| // and send the command to switch state i.sendCommand( transform("MAP", "heizungsschalter.map", triggeringItem.state.toString)) ] // give some time to rest Thread::sleep(500) // Unlock rule lock = false