Heizungsthermostate per Apple Home steuern

Heizungsthermostate per Apple Home steuern

Vor ein paar Tagen hat mir mein Vermieter ein verspätetes Weihnachtsgeschenk zukommen lassen. Die Nebenkostenabrechnung von 2018. Obwohl ich 2018 gerade erst frisch in meine neue Wohnung eingezogen war und damit gerade einmal zwei Monate dort gewohnt habe durfte ich nun 200€ Heizkosten nachzahlen. Da hat man direkt erst einmal was zu schlucken. Ganz schön deftig dachte ich mir. 

Also wurde es Zeit für eine Anpassung. Automatische Heizungsthermostate sollten her.
Den vernetzten Teilen vertraue ich sicherheitstechnisch nicht wirklich weit über den Weg, zumal man sich meistens noch eine zusätzliche Bridge anschaffen muss, die zusätzlich am Strom hängt.

Zum Glück habe ich ja bereits eine HomeBridge auf meinem Raspberry Pi Zero installiert und steuere so schon seit längerem erfolgreich meine diversen Steckdosen, welche ebenfalls über keine Internetverbindung verfügen. Blöde Steckdosen also einfach mal smart gemacht.

Angeschafft habe ich mir also Eqiva Bluetooth® Smart Heizkörperthermostat, 141771E. Diese Geräte sind mit etwa 20€ pro Stück sehr erschwindlich, nicht so wirklich "smart" und besitzen eine Bluetooth Verbindung, über die man die Thermostate verstellen kann.

HomeBridge und Bluetooth Thermostate - Eine Odesee

Nach kurzem Suchen habe ich ein perfekt erscheinendes Plugin für HomeBridge namens "homebridge-eq3ble" gefunden. Leider habe ich es auch nach 5 Stunden der intensiven Fehlersuche nicht geschafft das Teil ansatzweise ans Laufen zu bekommen. Für das Plugin müssen die weiteren Plugins noble und bluetooth-hci-socket installiert werden, welche allerdings nicht mit NodeJS 10, sondern nur mit NodeJS 8, kompatibel sind. Leider wollte auch die HomeBridge beim Wechsel auf NodeJS 8 nicht mehr arbeiten.
Alternativ kann man jedoch auf @abandonware/bluetooth-hci-socket und @abandonware/noble zurückgreifen. Diese werden jedoch nicht von homebridge-eq3ble unterstützt. Ein Mapping der neuen Plugins auf den Namen der alten Plugins hat HomeBridge zwar starten lassen, aber eine Bluetooth Verbindung haben sie deshalb aber immer noch nicht aufbauen können.
Kurzum:
Eine andere Lösung musste her! Diese hier war eine Katastophe!

Die Lösung

Der nun endlich funktionierende Weg heißt homebridge-web-thermostat in Verbindung mit einem anderen unabhängigen Script mit dem bedrohlichen Namen eQ-3-radiator-thermostat.

Die Funktionsweise dieser beiden Codeschnippsel ist eigentlich recht einfach, wenn auch nicht sonderlich trivial umzusetzen. Ich möchte an dieser Stelle gerne erklären, was wir nun tun. homebridge-web-thermostat dient dazu Apple Home ein Thermostat anzuzeigen und dieses aus der App heraus steuerbar zu machen. Selber besitzt es keine eigenen Daten und kann das Thermostat auch selber nicht steuern. Für diese beiden Eigenschaften ist das Script eQ-3-radiator-thermostat da. Damit das Plugin die Thermostate mittels des Scriptes eQ-3-radiator-thermostat "fernsteuern" kann müssen wir eine Verbindung herstellen. Einen zweiten kleinen Webserver, der die Befehle des Plugins entgegen nimmt und an das Script weiterleitet.

Das klingt im ersten Moment, als würde man mit Kanonen auf Spatzen schießen. Tun wir auch, allerdings hat dieses Vorgehen zwei große Vorteile:

  • Sollte die Bluetooth Verbindung nicht von der HomeBridge zu allen Thermostaten reichen, so können wir einfach einen zweiten Pi aufsetzen und jeden Winkel des Hauses abdecken.
  • Es funktioniert, im Gegensatz zu anderen Plugins :P

Hier einmal eine kleine Darstellung, zur Verdeutlichung:

Als Erstes müssen wir das Plugin homebridge-web-thermostat und einige später benötigte Zusatzprogramme installieren. Dazu verbinden wir uns über SSH mit der HomeBride auf unserem Raspberry Pi. Hier tippen wir dann ein:

sudo apt-get update && sudo apt-get upgrade
sudo apt install expect
sudo apt-get install bluetooth bluez libbluetooth-dev libudev-devsudo apt-get bluez-tools bluetoothctl
sudo npm cache clean -f
sudo npm install -g n
sudo n 11.15.0
sudo npm install --unsafe-perm -g homebridge-web-thermostat

Anschließend sollte das Plugin in der Weboberfläche (sofern installiert) erscheinen:

Nun haben wir alle nötigen Programme und Plugins installiert, um der HomeBridge ein Thermostat hinzufügen zu können und uns über Bluetooth mit dem Theromstat zu verbinden. Was jetzt natürlich noch fehlt ist das Konfigurieren von HomeBridge, die eigentliche Verbindung zu den Thermostaten und das Steuern eben dieser.

Server aufsetzen

Als nächstes müssen wir uns einen Apache Server installieren, konfigurieren und diesen anleiten die Befehle an das Script eQ-3-radiator-thermostat weiterzuleiten.

Hierzu tippen wir wieder per SSH auf dem Pi ein:


sudo apt-get install apache2 php libapache2-mod-php
cd /var/www/html
sudo git clone https://github.com/artpetro/eQ-3-radiator-thermostat
sudo a2enmod rewrite
sudo nano /etc/apache2/sites-available/000-default.conf
sudo systemctl restart apache2


Nach dem vorletzten Befehl fügen wir dem Inhalt der Datei folgendes ein (bitte kurz vor dem ".../VirtualHost..." einfügen) und speichern die Eingabe mit Strg+x und y+Enter:


<Directory /var/www/html>
	Options Indexes FollowSymLinks MultiViews
	AllowOverride All
	Require all granted
</Directory>


Nun installieren wir noch das Script zum empfangen der Steuerbefehle:

cd /var/www/html
sudo wget https://staticfloat.de/content/thermostat.zip 
sudo unzip thermostat.zip
cd ./thermostat
sudo chmod 0777 status.json


Und zum Schluss richten wir noch zwei Cronjobs ein. Ein Cronjob überprüft alle 30min den Status der Thermostate. Ein zweiter Cronjob sendet innerhalb der App gemachte Änderungen in Intervallen von 5min an die Thermostate.
Dazu führen wir den Befehl "sudo crontab -e" aus und füge ans Ende der Datei folgende Zeilen ein:

*/5 * * * * curl -s http://127.0.0.1/thermostat/cronjob.php > /dev/null
*/30 * * * * curl -s http://127.0.0.1/thermostat/statusCronjob.php > /dev/null


Funktionsweise und Probleme des installierten Scriptes:

Ich habe nach dem ersten Aufsetzen der hier angesprochenen Lösung zwei Fehler bemerkt. Erstens wollten sich die Thermostate nicht per Siri steuern lassen. Zusätzlich wollten manchmal einige Thermostate ihre Temperatur nicht ändern, wenn ich 3 Thermostate gleichzeitig über eine Automation steuere. Woran liegt das?
Die Erklärung ist eigentlich recht einfach. Die Thermostate brauchen über Bluetooth zu lange!

Per Siri Befehl wurde ein Befehl an Homebridge weitergeleitet. Dieser hat den Befehl an den Apache Server weitergeleitet und dieser dann per Bluetooth und dem Script eQ-3-radiator-thermostat an die Thermostate -Uff ist das viel-.
Siri hat dann binnen weniger Millisekunden eine Rückmeldung verlangt, aber der Vorgang dauert halt einfach ein paar Sekunden länger. Es kam zu einem Fehler und einer unschönen Ansage von Siri.
Bei der Hausautomation sieht das Ganze recht ähnlich aus, allerdings überlagern sich möglicherweise einige Befehle. Es kann dabei passieren, dass der erste Befehl noch nicht fertig abgeschlossen ist und schon der zweite Befehl gesendet wird.

Wir umgehen die Problematik, indem unser Apache Server einfach so tut, als hätte er den Befehl erfolgreich ausgeführt! Tatsächlich werden die zu sendenden Änderungen jedoch erst einmal nur in einer status.json-Datei untergespeichert.
Über die installierten Cronjobs wird das eigentliche Steuern der Thermostate dann in Intervallen von 5min nachgeholt.
Um die Batterie der Thermostate zu schonen und zusätzlich die Meldung "Keine Antwort" zu umgehen wird zusätzlich ein zweiter Cronjob installiert, der in Intervallen von 30min den Status der Thermostate ausliest und für jede Nachfrage zwischenspeichert.

Selbstverständlich können die Stellen "*/5" und "*/30" auch beliebig verändert werden.
Beispielweise in "*" für jede Minute, "*/15" für jede Viertelstunde oder "0" für jede Stunde.


Mit Thermostaten verbinden

Für das Verbinden der Thermostate ist wieder die Eingabe via SSH nötig und schnelle Finger.
Aktiviert als Erstes bitte Bluetooth an euren Thermostaten (Menu 3 Sekunden drücken, drehen bis "ble" erscheint, Drehrad klicken, "On", klicken).

Anschließend suchen wir eine neue MAC Adresse in unserer Umgebung. Notiert euch diese bitte.


sudo hcitool lescan

Die Adresse sollte mit "CC-RT-BLE" enden. Ähnlich dieser Ausgbe hier:

Nun geben wir folgendes in der Konsole ein:


sudo bluetoothctl
agent on
scan on
scan off
trust MAC_ADDRESSE
-- 4 sekunden den Drehknopf drücken, bis dort steht "PAIr"
pair MAC_ADDRRESSE
connect MAC_ADDRESSE
exit


DIESEN VORGANG MÜSSEN WIR MIT ALLEN THERMOSTATEN DURCHFÜHREN!

Thermostate steuern

Nun fehlt nur noch die Konfiguration in der HomeBridge.
Fügt in die []-Klammern, vor denen "acessoirs" steht folgendes ein (für jedes Thermostat einmal):

{
        "accessory": "Thermostat",
        "name": "Thermostat Wohnzimmer",
        "apiroute": "http://localhost/thermostat/MAC-ADRESSE",
        "maxTemp": 29,
        "minTemp": 5,
        "listener": false,
        "timeout": 20000,
        "model": "eQ3 Bluetooth",
        "serial": "Homebridge",
        "manufacturer": "eQ3",
        "firmware": "1.1"
    }

Bitte ersetzt immer das "MAC-ADRESSE" durch die Adresse des Therostats. Sollten hier mehrere Thermostate eingefügt werden, so muss hinter jeder der }-Klammern ein ",". Ausgenommen davon ist die letzte }-Klammer.


Update - 14.04.2020:

Aufgrund eines Fehlers konnte es passieren, dass das gleichzeitige Schalten aller Thermostate einige Thermostate aus der status.json-Datei entfernt hat.
Dieser Fehler trat auf, wenn der Befehl "Hey Siri, setze die Temperatur im ganzen Haus auf 20 Grad" benannt wurde. Der HomePod oder das iPhone hat an dieser Stelle das Ändern der Temperatur zu schnell veranlasst. Das erste Thermostat wurde noch nicht korrekt in die status.json-Datei geschrieben, während schon der zweite Befehl nun eine scheinbar leere Datei vorfand und nun nur noch ein Thermostat gespeichert hat.
Dieser Fehler wurde durch eine Schreib- und parallele Lesesperre behoben, welche das Lesen und geleichzeitige Schreiben durch eine Warteschlange verhindert. (Stichwort: FILE_LOCK)

Für ein Upgrade müssen folgende Schritte befolgt werden:

cd /var/www/html
sudo rm thermostat.zip
sudo rm -r ./thermostat
sudo wget https://staticfloat.de/content/thermostat.zip
sudo unzip thermostat.zip
cd ./thermostat
sudo chmod 0777 status.json 


Marvin

Ich bin ein Mensch, der sich neben der Programmierung noch für tausend andere Dinge interessiert, die mal mehr und mal weniger verrückt sind. Vor allem aber bin ich Feuer und Flamme mit der Programmierung von eigenen kleinen Apps und Programmen, die mein Leben bereichern.

Hat dir dieser Artikel gefallen?

Kommentar hinzufügen

*Pflichtfeld

Hallo Marvin,
danke für den Artikel - ich kämpfe mich da grad durch. Eine Frage zur Node-Version: werden auch aktueller Versionen laufen?

Grüße
Martin

Hallo Martin,

Es freut mich sehr, dass ich dir hiermit helfen kann.

Homebridge selber kann mit NodeJS 12 laufen (https://github.com/homebridge/homebridge/wiki/Install-Homebridge-on-Raspbian#step-1-install-nodejs). Für das Plugin kann ich bisher nur dafür sprechen, dass Node.js v10.18.0 und auch v11.15.0 einwandfrei funktionieren.

Ich werde die Tage noch einmal ein Update des Apache PHP Skriptes zur Verfügung stellen und ein Anleitung zum Update zur Verfügung stellen. Nach längeren Tests ist mir aufgefallen, dass das Schalten von allen Thermostaten gleichzeitig zum Löschen der Thermostate aus meinem Skript (nicht Homebridge) führen kann. Anschließend ist ein einzelnes Schalten der Thermostate nötig, um sie wieder hinzuzufügen.
Der Fehler ist ach schon gefunden, nur noch nicht ausreichend getestet.

Gruß,
Marvin

Hallo Martin,

ich habe die neue Version meines Skriptes nun hochgeladen.
Falls dein Server bereits laufen sollte muss für ein Update folgendes durchgeführt werden:
cd /var/www/html
sudo rm thermostat.zip
sudo rm -r ./thermostat
sudo wget https://staticfloat.de/content/thermostat.zip
sudo unzip thermostat.zip
cd ./thermostat
sudo chmod 0777 status.json

Gruß
Marvin

Moin Marvin,
danke für deine tolle Alternative. So etwas habe ich schon lange gesucht. Leider bekomme ich es nicht zum Laufen...

1. Ich verstehe bei den Cronjobs die IP nicht. Was bedeutet 127.0.0.1 ?
2. In den Code, der in die Config.json muss, scheinen noch Zeichenfehler zu sein...

Wäre klasse, wenn du mir helfen könntest. Ich bin leider auch absoluter Anfänger, aber um jede Hilfe dankbar! Würde mich freuen, wenn ich die Teile in Homebridge zum Laufen bekomme. Dein Ansatz scheint mir der Beste zu sein! Hoffe, es wird bei mir klappen! Danke.
Leon.

Hallo Leon,

bei Fragen kannst du immer gerne in den Kommentaren auf mich zu kommen und bei größeren Codeschnippseln auch gerne bei E-Mail.

Zu deinen Fragen:
1. Die IP "127.0.0.1" steht stellvertretend für "localhost" und damit die IP des eigenen Rechners. Jeder Rechner (egal ob Win, Linux, Mac, Android, ...), welcher diese IP aufruft wird immer bei sich selber landen.
2. Du hast selbstverständlich vollkommen Recht und ich habe die entsprechende Stelle im Artikel korrigiert. Vielen Dank für den Hinweis.

Gruß
Marvin

Danke Dir. Jetzt er halte ich folgenden Fehler

4/18/2020, 12:56:23 PM] [Thermostat Arbeitszimmer] Listen server: http://192.168.178.45:2000
[4/18/2020, 12:56:23 PM] SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse ()
at Thermostat. (/usr/local/lib/node_modules/homebridge-web-thermostat/index.js:103:25)
at Request._callback (/usr/local/lib/node_modules/homebridge-web-thermostat/index.js:88:7)
at Request.self.callback (/usr/local/lib/node_modules/homebridge-web-thermostat/node_modules/request/request.js:185:22)
at Request.emit (events.js:193:13)
at Request. (/usr/local/lib/node_modules/homebridge-web-thermostat/node_modules/request/request.js:1154:10)
at Request.emit (events.js:193:13)
at IncomingMessage. (/usr/local/lib/node_modules/homebridge-web-thermostat/node_modules/request/request.js:1076:12)
at Object.onceWrapper (events.js:281:20)
at IncomingMessage.emit (events.js:198:15)

---- das war meine Conti JSON

{
"accessory": "Thermostat",
"name": "Thermostat Arbeitszimmer",
"apiroute": "http://192.168.178.45:8091/thermostat/00:1A:22:14:AC:44",
"maxTemp": 29,
"minTemp": 5,
"listener": true,
"timeout": 20000,
"model": "eQ3 Bluetooth",
"serial": "Homebridge",
"manufacturer": "eQ3",
"firmware": "1.1"
}

Könntest du mir vielleicht den Rest der Config senden?
Es scheint so, als wenn der Fehler an einer anderen Stelle liegt.

Gruß

Leon

Moin, Danke für deine Antwort! Du kannst mir gerne per Mail antworten, dann können wir da weiter sehen. Zuerst: Danke für deine Unterstützung.

Also: Wenn ich in der Config Datei die config von dir übernehme und bei der iproute "http://" eingebe, bekomme ich folgende Fehlermeldung in meinem log angezeigt:

[4/20/2020, 5:16:59 PM] [Thermostat Wohnzimmer] Initializing Thermostat accessory...
[4/20/2020, 5:16:59 PM] [DysonPureCoolPlatform] Device credentials not stored, asking Dyson API. If you want to prevent communication with the Dyson API, copy the credentials for each device from the coming log entries to the config.json.
[4/20/2020, 5:16:59 PM] [DysonPureCoolPlatform] Signing in.
[4/20/2020, 5:16:59 PM] [PhilipsHueSyncBoxPlatform] Cached accessories loaded.
[4/20/2020, 5:16:59 PM] [Thermostat Wohnzimmer] Listen server: http://192.168.178.45:2000
[4/20/2020, 5:17:00 PM] SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse ()
at Thermostat. (/usr/local/lib/node_modules/homebridge-web-thermostat/index.js:103:25)
at Request._callback (/usr/local/lib/node_modules/homebridge-web-thermostat/index.js:88:7)
at Request.self.callback (/usr/local/lib/node_modules/homebridge-web-thermostat/node_modules/request/request.js:185:22)
at Request.emit (events.js:193:13)
at Request. (/usr/local/lib/node_modules/homebridge-web-thermostat/node_modules/request/request.js:1154:10)
at Request.emit (events.js:193:13)
at IncomingMessage. (/usr/local/lib/node_modules/homebridge-web-thermostat/node_modules/request/request.js:1076:12)
at Object.onceWrapper (events.js:281:20)
at IncomingMessage.emit (events.js:198:15)


und die Homebridge startet neu...

Wenn ich nun aber lediglich die IP eingebe - also wie folgt:

{
"accessory": "Thermostat",
"name": "Thermostat Wohnzimmer",
"apiroute": "192.168.178.45:8091/thermostat/00:1A:22:14:A4:B6",
"maxTemp": 29,
"minTemp": 5,
"listener": true,
"timeout": 20000,
"model": "eQ3 Bluetooth",
"serial": "Homebridge",
"manufacturer": "eQ3",
"firmware": "1.1"
}

funktioniert es zwar (also die Homebridge bootet ganz normal). Innerhalb der Home-App steht aber ständig "Gerät nicht erreichbar"

Hast Du noch einen Tipp?

Danke!

Viele Grüße
Leon

Marvin

Hallo Leon,

mir scheint es so, als wenn Homebridge schon funktioniert.
Allerdings würde ich per Ferndiagnose darauf tippen, dass der Apache Server aktuell noch einen falschen Rückgabewert hat.
Deinen Logs nach zu urteilen kann Homebridge den Status der Thermostate nicht herausfinden, da Homebridge ein JSON erwartet, jedoch einen XML-Tag bekommt (das "<") in der Fehlermeldungszeile "[4/20/2020, 5:17:00 PM] SyntaxError: Unexpected token < in JSON at position 0".

Für eine bessere Ferndiagnose würde ich dich darum bitten einmal in der Config das "listener: true" auf "listener: false" zu setzen und dann per Browser diese drei URL's aufzurufen und in die Antwort des Browsers in die Kommentare zu schreiben:
http://192.168.178.45:8091/thermostat/00:1A:22:14:A4:B6/status
http://192.168.178.45:8091/thermostat/00:1A:22:14:A4:B6/targetTemperature/18
http://192.168.178.45:8091/thermostat/00:1A:22:14:A4:B6/status

Gruß
Marvin