Hier wird die Integration eines Austroflamm-Pelletofens mit einer Steuereinheit vom Fumis/ATech in eine OpenHAB-Instanz beschrieben.
HINWEIS: Dies ist noch eine Baustelle und die Software ist bei Weitem noch nicht fertig. Wer mag, darf gern ab und zu vorbei schauen.
Bei diesem Hobbyprojekt handelt es sich um einen Prototypen einer Idee und nicht um ein fertiges Produkt. Da hiermit ein Ofen gesteuert wird, kann und will ich keinerlei Verantwortung übernehmen für das was mit der Software geschieht!
Nachbau und Verwendung erfolgen auf eigenes Risiko!!!
Allgemeines
Unser heimischer Pelletofen unterstützt die Fernbedienung per App. Allerdings stören mich hierbei einige Dinge:
- Es handelt sich um einen Dienst eines Anbieters der bei Amazon gehostet ist
- Alle Pelletöfen dieser Art verbinden sich zentral zu einem Server
- Die Authentikation über eine (anscheinend fest vergebene) PIN erscheint aus IT-Sicherheitssicht zumindest fragwürdig
- und bei mir Ausschlaggebend: Es spielt nicht mit meiner lokal laufenden Gebäudeleitsoftware (heute auch smart Home) OpenHAB zusammen.
Also muss eine andere Lösung her, am Besten eine die alle Daten sprichwörtlich im Haus behält und bitte keine Wolkendienste benutzt. Als Segelflieger mag ich Wolken, wenn die aber meinen Ofen steuern fühle ich mich unwohl.
Funktionsbeschreibung
Im Grunde nutzt dieses System die sogenannte WiRCU-Box, ein Gateway vom ATech/Fumis spezifischen RS485-Protokoll auf W-LAN und bietet einen alternativen Server an, auf den sich diese Box verbindet.
Die Box versucht sich auf einen, soweit ich das erkennen kann, fest eingestellten Hostnamen zu verbinden. Hierbei wird WebSocket über TLS verwendet, was an sich schon einmal eine gute Idee ist. Über Websocket liefert die Box in regelmäßigen Abständen diverse Daten als JSON aus. Diese sind dankenswerterweise in Form einer halbwegs sinnvollen Baumstruktur. Die Box empfängt ähnlich formatierte JSON-Objekte vom Server und setzt Sollwerte entsprechend.
Allerdings verbindet die Box bereitwillig zu jedem Host der mit besagtem Namen auflöst und beginnt fröhlich ihr WebSocket-Sitzung, ohne dabei zu prüfen, ob das Zertifikat überhaupt für den Host ausgestellt geschweige denn auch richtig signiert ist. Auf eine Ausführung darüber warum das keine gute Idee für ein IoT-Gerät ist, sei an dieser Stelle verzichtet. Allerdings bestärkt mich dies darin, den Cloud-Service nicht zu nutzen.
Die Software stellt also nun einen WebSocket-Server zur Verfügung, nun braucht man noch beispielsweise stunnel oder einen ReverseProxy-TLS-Server im heimischen Netzwerk der die Verbindungen an die Script weiterreicht. Dieser braucht keine nach dem Stand der Technik als gültig zu betrachtenden Zertifikate zu besitzen, selbst signiert und auf irgendeinen Hostnamen reicht völlig aus.
Und schließlich wird z.B. mittels dnsmasq ein DNS-Server präsentiert, der ein mit der waren Identität des Servers api.fumis.si etwas flexibler umgeht und einfach die IP des TLS-Servers (stunnel oder reverse Proxy) antwortet.
Das Script stellt dann per MQTT alle Daten der WiRCU-Box bereit und gibt bestimmte Befehle/Sollwerte auch schreibend an die Box zurück.
Umsetzung
Das Script wurde für node-js, weder meine Lieblingsumgebung noch Sprache, geschrieben. Ziel war eine schnelle Umsetzung und nicht unbedingt absolut sauberes Design.
Es nutzt die Pakete “mqtt” und “ws” und bildet eine dünne Zwischenschicht die beide Welten miteinander verbindet.
Hilfsprogramme und Konfiguration
Es wird angenommen, dass das IoT-Netzwerk den IP-Kreis 10.0.0.0/24
hat.
Der Host auf dem alle Tools laufen hat in diesem Beispiel die Adresse 10.0.0.123
.
stunnel
stunnel
wurde verwendet um die TLS-Kommunikation mit der Box zu übernehmen,
um nicht auch noch TLS in der node-js Umgebung zuhaben.
Auf debianesqen Systemen kann man stunnel mittels apt-get install stunnel4
installieren.
; TLS front-end for fumis server, sends clear text connections to localhost:8080
[fumis]
accept = 5101
connect = 8080
cert = /etc/stunnel/stunnel.pem
Ein Zertifikat kann man sich mittels der folgenden Befehle zusammenhäkeln 1:
cd /etc/stunnel/
openssl req -new -x509 -days 365 -nodes -config stunnel.cnf -out stunnel.pem -keyout stunnel.pem
openssl gendh 2048 >> stunnel.pem
Hinweis: Anscheinend nutzt die WiRCU-Box keine Netzwerkzeit, sodass auch der Ablauf eines Zertifikats kein Problem darstellen sollte.
dnsmasq
Der dnsmasq
-Server verhilft dem heimischen IoT-Netz zu einem DNS-Server
mit Sonderfunktion: Er lügt über einen spezifischen Hostnamen, und das geht so:
local=/api.fumis.si/
Dazu wird in der /etc/hosts
folgender Eintrag ergänzt
10.0.0.123 api.fumis.si
node-js
Das Script wurde mit node-js 10.24 entwickelt und sollte auf neueren Versionen funktionieren. Unter Debian/Ubuntu empfiehlt es sich, die folgenden Pakete aus dem Bestand der Distribution zu installieren:
apt-get install node-ws npm
npm
Um alle weiteren Abhängigkeiten zu Laden führt man im Script-Verzeichnis
npm install
aus. Nun sollte es ein Unterverzeichnis node_moules/
geben.
Konfiguration des Adapters
Nun wird noch das eingangs beschriebene Adapterscript konfiguriert.
Dies geschieht, der Einfachheit der Implementation halber, mittels einer JSON-Datei mit folgender Struktur:
{
"mqtt":{
"username": "user",
"password": "pass",
"host": "127.0.0.1",
"port": "1883"
},
"websocket":{
"known_stoves": {
"0016D0000001": "1234"
}
},
"writable": [
"controller/command",
"controller/power/setPower"
]
}
Hierbei werden die beiden Schnittstellen, also WebSocket für die Heizungen und MQTT konfiguriert.
Während die MQTT-Seite relativ selbsterklärend ist, muss doch die WebSocket-Konfiguration
noch etwas erläutert werden: Die known_stoves
stellt eine Zuordnung von MAC-Adressen
zu PINs dar. Beide Informationen stehen auf der WiRCU-Box, jedoch muss die MAC-Adresse
ohne Trennzeichen und mit Großbuchstaben eingegeben werden. Nur wenn dies der Fall ist,
kann sich eine WiRCU-Box beim Server anmelden. Es können auch mehrere WiRCU-Boxen verbunden
werden, auch wenn dieser Anwendungsfall aktuell eher von theoretischem Wert ist.
Die Sektion writable
listet alle Knoten auf, die per MQTT mit dem Suffix :set
schreibbar
sein sollen. Bislang sind nur zwei davon erfolgreich getestet worden, diese sind in dem
Beispiel genannt.
Beim Starten des Scripts sollte etwa folgendes zu sehen sein:
$ node main.js /etc/own_stove.json
Will accecpt stoves: { '0016D0000000': '1234' }
Writable nodes in stoves are: [ 'controller/command', 'controller/power/setPower' ]
Connecting to mqtt://10.0.0.132:1883
MQTT connected
Stove connected
Data from stove 0016D0000000
Stove 0016D0000000 connected
Subscribe to topic 'fumis/0016D0000000/#'
Data from stove 0016D0000000
Hier ist zu sehen, dass die obige Konfiguration erfolgreich geladen wurde und der Ofen über stunnel erfolgreich eine Verbindung zum Script aufgebaut hat.
Nun sollte im MQTT Broker unter fumis/0016D0000000
eine Menge von Topics entstanden sein,
so auch z.B. fumis/0016D0000000/controller/power/setPower
. Dieser kann dann mittels
des Topics fumis/0016D0000000/controller/power/setPower:set
via MQTT verstellt werden.
Der Kommandokanal fumis/0016D0000000/controller/command:set
unterstützt zwei bekannte Befehle:
Wert | Bedeutung |
---|---|
1 | Ofen ausschalten |
2 | Ofen einschalten |
Konfiguration von OpenHAB
Es wird in diesem Dokument davon ausgegangen, dass bereits ein MQTT-Broker
konfiguriert ist (in diesem Beispiel hat dieser die UID mqtt:broker:0db42c4a
).
Ferner wird die “Mapping” Transformation benötigt, um den numerischen Statuswerten textuelle Beschreibungen zuzuordnen.
In OpenHAB wird ein Thing mit folgender Konfiguration erstellt:
label: Pelletofen
thingTypeUID: mqtt:topic
configuration: {}
bridgeUID: mqtt:broker:0db42c4a
location: Wohnzimmer
channels:
- id: PelletofenAn
channelTypeUID: mqtt:switch
label: Pelletofen
description: ""
configuration:
commandTopic: fumis/0016D0000000/controller/command:set
allowedStates: 1,2
qos: 0
stateTopic: fumis/0016D0000000/controller/command:set
off: "1"
on: "2"
- id: PelletofenLeistung
channelTypeUID: mqtt:number
label: Leistung
description: ""
configuration:
commandTopic: fumis/0016D0000000/controller/power/setPower:set
min: 1
stateTopic: fumis/0016D0000000/controller/power/setPower
max: 5
- id: PelletofenStatus
channelTypeUID: mqtt:string
label: Status
description: ""
configuration:
stateTopic: fumis/0016D0000000/controller/status
transformationPattern: MAP(fumis.map):%s
In /etc/openhab/transform/fumis.map
werden die Statuswerte Texten zugeordnet:
0=CONTROLLER_OFF
1=CONTROLLER_COLD_START_OFF
2=CONTROLLER_WOOD_BURNING_OFF
10=CONTROLLER_HEATUP
20=CONTROLLER_IGNITION
21=CONTROLLER_IGNITION_TEST
30=CONTROLLER_BURNING
40=CONTROLLER_BURNWAIT
50=CONTROLLER_COOLDOWN
60=CONTROLLER_HYBRID_INIT
80=CONTROLLER_HYBRID_START
90=CONTROLLER_WOOD_START
100=CONTROLLER_COLD_START
110=CONTROLLER_WOOD_BURNING
Downloads
Alle Quellcodes stehen unter https://github.com/ptwz/own_fumis zur Verfügung.