Bauanleitung NodeMCU WIFI MQTT HomeAssistant - openv/openv GitHub Wiki

Zuerst möchte ich an dieser Stelle ein großes "Danke" an alle Beteiligten dieses genialen Projekts ausrichten.

Im Nachfolgenden zeige ich euch meinen Aufbau und die Implementierung der Viessmann-Steuerung über einen NodeMCU und die Anbindung per MQTT an die Software "HomeAssistant".

Meine Ausgangslage und Zielsetzung

Um meine Heizung jederzeit überwachen und steuern zu können, suchte ich eine kompakte WLAN-Lösung um dies mit größtenteils vorhandenen Geräten/Komponenten umzusetzen. Die Homeautomatisierungssoftware "HomeAssistant" ein MQTT-Broker (Mosquitto) und der Volkszähler zum Auswerten verschiedener Daten wurden schon im Vorfeld für die Steuerung und Visualisierung diverser Steckdosen / Temperatursensoren auf einer QNAP TS-212(Debian) aufgesetzt und eingerichtet. Ich werde auf die Installation dieser Tools nicht näher eingehen, da dies einfach zu viel für die Anleitung ist.

Die Realisierung

Hardware + Schaltkreis

Mit dem (für mich) schwierigsten Teil des Aufbaus, dem Optolink-Adapter inkl. Auslesen per NodeMCU, habe ich begonnen. Der Schaltkreis für die LED/den Fototransistor wurde wie hier gezeigt nachgebaut:

Schaltkreis

Mein NodeMCU wurde per USB-Kabel mit Strom versorgt und stellt die benötigten 3,3V und GND am entsprechenden Pin zur Verfügung. Der NodeMCU stellt zwei serielle Verbindungen zur Verfügung TXD0,RXD0(Serial0) und TXD2,RXD2(Serial1). Da die Verbindung mit den Serial1-Pin’s zum Optolink-Adapter nie wirklich funktioniert hatte, musste ich die Serial0 Ports nutzen. Hier bin ich auf große Probleme gestoßen, da die Serial0-Verbindung für die USB-Programmierung mitgenutzt wird. Wird also per Arduino-IDE der Sketch hochgeladen, wird unter Umständen der Upload des Sketch durch den Fotostransistor unterbrochen, oder verfälscht, sodass der NodeMCU im Anschluss nicht mehr den Sketch booten kann. Somit ist es wichtig, bei jedem Sktech-Upload die Verbindung zum Fototransistor zu trennen. Ein Workaround per Sketch-Upload über WLAN ist in meinem weiter unten genannten Sketch implementiert, sodass der Fototransistor nicht mehr getrennt werden muss um einen angepassten Sketch hochzuladen. Als V-Adapter für die LED und den Fototransistor wurde folgende STL aus dem 3D Drucker erstellt:

V-Adapter Optolink STL (Downloadlink folgt)

Falls kein 3D-Drucker vorhanden ist gibt es hier im OpenV-Wiki einige Alternativen.

Um den NodeMCU und den Schaltkreis zu schützen habe ich eine entsprechende „Viessmann-Box“ mit dem 3D-Drucker gedruckt.

Viessmann-Box - TinkerCad-Vorlage

(Meine erstes eigenen 3D-Design, die Wände könnten z.B. etwas schmaler sein :) )

Sieht gut aus, tut seinen Zweck, aber hier könnt ihr natürlich auch eine andere passende Box nutzen, oder gar keine Box verwenden.

Arduino NodeMCU-Software + Sketch

Bei meiner Recherche hier im Wiki bin ich auf das Github-Projekt „VitoWifi“ gestoßen, welches mir die Programmierung der Datenschnitstelle zum OpenV-Adapter sehr erleichtert. Da ich bisher nur mit der Arduino-IDE gearbeitet habe, nutze ich diese auch für die Programmierung des NodeMCU’s.

Zuerst solltet ihr euch die Arduino-IDE installieren: Arduino-IDE

Danach die Board-Bibliothek für den ESP8266: ESP8266-Library

! Hier nutze ich die Version 2.3.0, diese läuft bei mir stabil

Ist euer Board in der Arduino-IDE unter „Werkzeuge -> Board:“ aufgelistet hat die Installation der ESP8266-Board-Bibliothek soweit geklappt. Ich wähle für meinen NodeMCU Amica V2 das Board „NodeMCU 1.0“ aus. Bevor ihr hier weitermacht testet die Funktion mit dem aufspielen des „Blink“-Sktechs.

Ist der Test erfolgreich, bindet ihr die folgenden benötigten Bibliotheken ein:

Sind die beiden Bibliotheken erfolgreich eingebunden, können wir uns dem Sketch zuwenden. In meinem Repository findet ihr den Sketch: https://github.com/Schnup89/OpenV_NodeMCU

Den könnt Ihr, so wie er ist, erstmal testen. Bei mir läuft der Code auf dem NodeMCU stabil.

Im Abschnitt Konfiguration solltet Ihr entsprechend eure Daten vom MQTT-Broker und eurer WLAN-Verbindung eintragen. Wollt ihr nun einen angepassten Sketch auf euren NodeMCU hochladen, einfach per Webbrowser (http://vitowifi) auf die IP oder den Hostnamen eures NodeMCU’s verbinden, und dort unter „Update“ eure Kompilierte „.bin“-Datei hochladen. Der NodeMCU startet neu, und auf der Übersichtsseite sollte anschließend die Uhrzeit der Kompilierung eurer neuesten Version stehen. Die Datei wird im Sketch-Ordner erzeugt, sobald ihr in der Arduino-IDE den Punkt „Sketch -> Kompilierte Binärdatei exportieren“ auswählt.

In der aktuellen Initialversion sind nur die PartyModus-Datenpunkte für Heizkreis1 und Heizkreis2 als „set-Datenpunkte“ deklariert. Alle anderen sind auskommentiert, sollten aber funktionieren.

Datenübertragung MQTT testen

Zum Test, ob die Daten richtig verarbeitet und ausgelesen werden, kann folgendes Kommando auf dem Mosquitto MQTT-Broker ausgeführt werden:

root@HomeNas:~# mosquitto_sub -t '#' -u myMQTTUser -P myMQTTPass -v -R

Danach sollten nach der im Sketch definierten Abfragezeit (default 60s) die Werte folgendermaßen übermittelt/ausgegeben werden:

gettempa  -1.10
getalarmstatus 0
gettempwwist  33.60
gettempwwsoll 55
gettempkist  31.30
getbrennerstatus 0
getbrennerstunden1 8042.68
gettempvlistm1  31.30
gettempvlistm2  28.50
gettempraumnorsollm1 24
gettempraumnorsollm2 21
getbetriebpartym1 0
getbetriebpartym2 0

Ist dies der Fall, fehlt uns nur noch die Verarbeitung der Daten.

Visualisierung im Volkszähler

Um die Daten im Volkszähler zu visualisieren, müssen im Volkszähler-Webinterface zuerst die Kanäle angelegt werden, als Beispiel die Außentemperatur:

  • Volkszähler-Webseite öffnen, „Kanal hinzufügen“
  • Register „Kanal erstellen“ auswählen
  • Typ: Temperatur
  • Titel: Außentemperatur
  • Mit „Erstellen“ den Kanal erstellen und die UUID merken

Nun müssen wir diesen Kanal anhand seiner UUID mit Werten der Nachrichten vom MQTT-Broken füllen. Ich nutze dafür ein kleines Script, welches per Crontab jede Minute gestartet wird:

* * * * * bash /etc/scripts/vzpush.sh

Das Script liest per mosquitto_sub den gewünschten Wert aus, und schreibt ihn anhand der UUID in den entsprechenden Kanal:

root@HomeNas:~# cat /etc/scripts/vzpush.sh
#!bin/dash

while read msg; do
    /usr/local/bin/vzclient -u 7378e5c0-eea7-11e8-b601-6fb1ee2318a4 add data value=$msg;
 done < <(mosquitto_sub -t 'gettempa' -u myMQTTUser-P myMQTTPass -C 1)

Den Datenimport könnt ihr, anstelle des Scripts auch mit dem Tool „NodeRed“ automatisieren. Anleitungen dazu gibt es im Internet genügend.

Visualisierung und Steuerung per HomeAssistant

Die Einstellungen beziehen sich auf die „UI-Lovelace“, können aber auch auf das Standard-UI von HomeAssistant adaptiert werden.

Zuerst definieren wir unseren MQTT-Broker in der „configurations.yaml“:

mqtt:
  broker: 192.168.10.60
  port: 1883
  client_id: home-assistant-1
  username: myMQTTUser
  password: myMQTTPass
  keepalive: 60

Danach werden in derselben Datei die Elemente erzeugt, und dort die MQTT-Topics angegeben:

  - platform: mqtt
    name: "Erreichbar"
    state_topic: "VITOWIFI/$status/online"
  - platform: mqtt
    name: "Sammelstoerung"
    state_topic: "getalarmstatus"
  - platform: mqtt
    name: "Aussentemperatur"
    state_topic: "gettempa"
    unit_of_measurement: "C"
  - platform: mqtt
    name: "Wasserspeicher"
    state_topic: "gettempwwist"
    unit_of_measurement: "C"
  - platform: mqtt
    name: "Wasserspeicher Soll"
    state_topic: "gettempwwsoll"
  - platform: mqtt
    name: "Kesseltemperatur"
    state_topic: "gettempkist"
    unit_of_measurement: "C"
  - platform: mqtt
    name: "Brennerstatus"
    state_topic: "getbrennerstatus"
  - platform: mqtt
    name: "Brenner Betriebsstunden"
    state_topic: "getbrennerstunden1"
  - platform: mqtt
    name: "HK1 Vorlauf"
    state_topic: "gettempvlistm1"
    unit_of_measurement: "C"
  - platform: mqtt
    name: "HK2 Vorlauf"
    state_topic: "gettempvlistm2"
    unit_of_measurement: "C"
  - platform: mqtt
    name: "HK1 Modus"
    state_topic: "getbetriebartm1"
  - platform: mqtt
    name: "HK2 Modus"
    state_topic: "getbetriebartm2"
  - platform: mqtt
    name: "HK1 Partymodus"
    state_topic: "getbetriebpartym1"
  - platform: mqtt
    name: "HK2 Partymodus"
    state_topic: "getbetriebpartym2"

Wer noch die Temperaturen aus HomeAssistant regeln möchte benötigt noch folgende Anpassungen:

configuration.yaml:

input_number:
  input_wasserspeicher_soll:
    name: Wasserspeicher Soll
    min: 45
    max: 60
    step: 1
  input_hk1_soll:
    name: HK1 Solltemperatur
    min: 3
    max: 37
    step: 1
  input_hk2_soll:
    name: HK2 Solltemperatur
    min: 3
    max: 37
    step: 1

automations.yaml

##### Heizung: Setze Wasser Solltemp
###
##
- alias: setze wassertemp soll input
  trigger:
    platform: mqtt
    topic: 'gettempwwsoll'
  action:
    service: input_number.set_value
    data_template:
      entity_id: input_number.input_wasserspeicher_soll
      value: "{{ trigger.payload }}"
- alias: setze wassertemp soll mqtt
  trigger:
    platform: state
    entity_id: input_number.input_wasserspeicher_soll
  action:
    service: mqtt.publish
    data_template:
      topic: 'VITOWIFI/setTempWWsoll'
      retain: true
      payload: "{{ states('input_number.input_wasserspeicher_soll') | int }}"
##
###
#####

##### Heizung: Setze HK1 Solltemp
###
##
- alias: setze HK1 Temp Soll input
  trigger:
    platform: mqtt
    topic: 'gettempraumnorsollm1'
  action:
    service: input_number.set_value
    data_template:
      entity_id: input_number.input_hk1_soll
      #value: "3"
      value: "{{ trigger.payload }}"
- alias: setze HK1 Temp Soll mqtt
  trigger:
    platform: state
    entity_id: input_number.input_hk1_soll
  action:
    service: mqtt.publish
    data_template:
      topic: 'VITOWIFI/setTempRaumNorSollM1'
      retain: true
      payload: "{{ states('input_number.input_hk1_soll') | int }}"
##
###
#####

##### Heizung: Setze HK2 Solltemp
###
##
- alias: setze HK2 Temp Soll input
  trigger:
    platform: mqtt
    topic: 'gettempraumnorsollm2'
  action:
    service: input_number.set_value
    data_template:
      entity_id: input_number.input_hk2_soll
      value: "{{ trigger.payload }}"
- alias: setze HK2 Temp Soll mqtt
  trigger:
    platform: state
    entity_id: input_number.input_hk2_soll
  action:
    service: mqtt.publish
    data_template:
      topic: 'VITOWIFI/setTempRaumNorSollM2'
      retain: true
      payload: "{{ states('input_number.input_hk2_soll') | int }}"
##
###
#####

Ob die Werte korrekt von HomeAssistant ausgelesen werden, könnt ihr im Menü unter dem <> -Symbol überprüfen. Dort sollten eure oben definierten Objekte die entsprechenden Werte von der Heizung liefern.

Die Visualisierung habe ich folgendermaßen realisiert:

ui-lovelace.yaml

- title: Heizung
    cards:
      - type: markdown
        content: HK1 = 1.+2. OG <br> HK2 = EG Fussbodenheizung
      - type: entities
        entities:
          - entity: counter.zaehlergas
            icon: mdi:gas-station
          - entity: sensor.erreichbar
            icon: mdi:access-point-network
          - entity: sensor.sammelstoerung
            icon: mdi:alert
          - entity: light.hk1_partymodus
            icon: mdi:glass-wine
          - entity: light.hk2_partymodus
            icon: mdi:glass-wine
          - entity: sensor.aussentemperatur
            icon: mdi:thermometer
          - entity: sensor.wasserspeicher
            icon: mdi:water-pump
          - entity: input_number.input_wasserspeicher_soll
            icon: mdi:water-pump
          - entity: input_number.input_hk1_soll
            icon: mdi:water-pump
          - entity: input_number.input_hk2_soll
            icon: mdi:water-pump            
          - entity: sensor.kesseltemperatur
            icon: mdi:cup-water
          - entity: sensor.brennerstatus
            icon: mdi:fire
          - entity: sensor.brenner_betriebsstunden 
            icon: mdi:fire
          - entity: sensor.hk1_vorlauf
            icon: mdi:pipe-leak
          - entity: sensor.hk1_modus
            icon: mdi:theme-light-dark
          - entity: sensor.hk2_vorlauf
            icon: mdi:pipe-leak
          - entity: sensor.hk2_modus
            icon: mdi:theme-light-dark

Somit sollten die Daten in HomeAssistant und dem Volkszähler angezeigt werden.

Das Endresultat

Viessmann-Anlage mit Optolink-Adapter und Steuerung (in der schwarzen Box rechts oben)


Optolink-Adapter


NodeMCU und Lötplatine versteckt in der „Viessmann-Box“


Auswertung Volkszähler


HomeAssistant Dashboard „Heizung“