ESP8266 oder ESP32 als Home Assistant Schalter und Sensoren

In letzer Zeit experimentiere ich viel mit der Cloud-freien Heimautomatisierungssoftware Home Assistant. Bister habe ich viele Sensoren und Aktoren einzeln betrieben, quasi unabhängig von einem zentralen System. So loggte meine Wetterstation in eine Datenbank, ebenso mein Stromzähler in eine andere. Dafür gab es dann jeweils eine Visualisierung. Meine Bewässerungssteuerung wurde von einem Raspberry Pi mit einer selbst gebauten Oberfläche verwaltet. Nun jedoch möchte ich die Dinge zusammenführen und kosolidieren, um eine bessere Usability zu haben und den WAF zu verbessern.

Kürzlich habe ich daher bereits über meine Integration eines Stromzählers in Home Assistant geschrieben, nun stehen meine Bewässerungssteuerung bzw. meine Relaissteuerung auf dem Plan. Bisher habe ich dafür oben genannten Raspberry Pi verwendet – doch diesen mit einem Raspbian 99% des Tages nichts tun zu lassen halte ich für Verschwendung.

Deswegen kommt nun ein ESP8266-basierter Mikrocontroller (Wemos D1 mini) zum Einsatz, den ich mit der Arduino-IDE ein HTTP-Interface zum Setzen und Abrufen von Ausgängen und Eingängen ausgestattet habe. Beispielhaft für ein Wemos D1 mini mit dem offiziellen Relais-Schild werde ich den Code hier einmal zusammenfassen.

Arduino-Code

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

#ifndef STASSID
#define STASSID "WLAN-NAME"
#define STAPSK  "WLAN-PASSWORT"
#endif

const char *ssid = STASSID;
const char *password = STAPSK;

ESP8266WebServer server(80);

void handleRoot() {
   server.send(200, "text/plain", String(analogRead(A0))); // Testweise den Analogwert ausgeben
}

void handleSet() {
  for (uint8_t i=0; i<server.args(); i++){
    if (server.argName(i)=="D1") { digitalWrite(D1, server.arg(i).toInt()); }
  }
  server.send(200, "text/plain","OK");
}

void handleGet() {
  for (uint8_t i=0; i<server.args(); i++){
    if (server.argName(i)=="D1") { server.send(200, "text/plain", String(digitalRead(D1))); }
    }
  server.send(200, "text/plain","OK");
}

void setup() {
  //IO
  pinMode(D1, OUTPUT);
  digitalWrite(D1, OFF);

  //WIFI
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }

  //HTTP
  server.on("/", handleRoot);
  server.on("/set", handleSet);
  server.on("/get", handleGet);
  server.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
  server.handleClient();
  MDNS.update();
  ArduinoOTA.handle();
}

Home Assistant-Code

Hier wird Beispielhaft die IP des ESP als 192.168.178.77 angenommen – dies ist natürlich anzupassen.


#Aktor Wemos D1 mini mit Rückmeldung
switch:
  - platform: command_line 
    switches:
      esp_aktor_001_d1:
        friendly_name: "Aktor 001 D1"
        command_state: "/usr/bin/curl 192.168.178.77/get?D1"
        command_on: "/usr/bin/curl 192.168.178.77/set?D1=1"
        command_off: "/usr/bin/curl 192.168.178.77/set?D1=0"
        value_template: '{{ value == "1" }}'

#Sensor Wemos D1 mini
  - platform: command_line
    name: "Aktor 001 A0"
    command: "/usr/bin/curl 192.168.178.77/get?A0"

Auf diese Weise kann der Relais-Status geschrieben und gelesen werden. Auch den Analog-Eingang kann man auswerten.

Natürlich bleibt es einem überlassen, mehr Ein- oder Ausgänge zu implementieren. Ich beispielweise nutze den erwähnten Wemos mit einem 8-fach Relais-Board, was diesen beinahe auslastet. Mit einem D32 oder ähnlichem wäre da bei weitem mehr möglich.

EasyMeter Stromzähler in Home Assistant einbinden

Unser Messstellenbetreiber nutzt die “smarten” Stromzähler der Firma EasyMeter GmbH, speziell den Easy Meter Q3M. Dies ist ein Drehstromzähler, der dahingehend “smart” ist, dass man einige Daten auslesen kann. Je nach Konfiguration des Messstellenbetreibers können die aktuelle Gesamtleistung, die Leistung pro Phase in Watt und die “verbrauchte” sowie eingespeiste Energie in Wattstunden ausgelesen werden. Dazu wird eine optische Schnittstelle namens “Info-DSS” bereitgestellt, die nichts anderes ist als eine unidirektionale Implementierung des SML Protokolls.

Über das SML Protokoll werden mittels sogenannter OBIS-Codes die oben genannten Informationen sekündlich über die Schnittstelle gepusht. Diese Daten muss man “nur” noch abgreifen und bereitstellen. Dazu benötigt man – zusätzlich zum bestehenden Home Assistant System – ein Gerät direkt am Zähler, dass die Daten der Info-DSS-Schnittstelle entgegennimmt und lesbar umwandelt. Ich nutze dafür einen Raspberry Pi (Zero W), aber auch andere Geräte mit einem Linux funktionieren. Die Anbindung funktioniert bei mir über einen IR-Lesekopf, den man sich aber auch selber bauen kann.

Auf meinem Raspebrry Pi habe ich dann die Software vzlogger installiert – wohlgemerkt ohne die Volkszähler-Middleware, die sonst die Speicherung und Darstellung der Daten übernimmt. Der vzlogger kann die aktuellen Daten problemlos allein auswerten und als json bereitstellen. Dafür ist in /etc/vzlogger.conf folgende Konfiguration notwendig:

{
  "retry": 0,
  "daemon": true,
  "verbosity": 3,
  "local": {
    "enabled": true,
    "port": 8084,
    "index": true,
    "timeout": 0,
    "buffer": -1
  },
  "meters": [
    {
      "enabled": true,
      "allowskip": true,
      "interval": -1,
      "aggtime": -1,
      "aggfixedinterval": false,
      "channels": [
        {
          "api": "null",
          "uuid": "abcdefgh-ijkl-mnop-qrst-uvwxyz012345",
          "identifier": "1-0:1.8.0*255",
          "aggmode": "max",
          "duplicates": 3600
        }
	  ],
      "protocol": "sml",
      "device": "/dev/ttyUSB0",
      "pullseq": "",
      "baudrate": 9600,
      "parity": "8n1",
      "use_local_time": true
    }
  ]
}

Wobei ich die uuid hier unkenntlich gemacht habe und der Übersicht halber nur einen “channel”, nämlich die Energiemenge “Verbrauch” erfasse. Nachdem die Datei gespeichert ist wird der vzlogger-Daemon neu gestartet:

sudo systemctl restart vzlogger

Und somit kann man die aktuellen Daten unter der IP des Raspberry Pi abrufen: http://[ip_des_pi]:8084 . Das Ganze könnte dann so aussehen:

{
	"version": "0.8.0",
	"generator": "vzlogger",
	"data":[ {
		"uuid": "abcdefgh-ijkl-mnop-qrst-uvwxyz012345", 
		"last": 1634638205040,
		"interval": -1,
		"protocol": "sml",
		"tuples": [ [ 1634638205040, 7418885.2847000007 ] ] 
	} ]
}

In dem Tuple steht also der aktuelle Zählerstand in Wh. Diesen müssen wir nun über Home Assistant auslesen, dazu wird in der Datei /config/configuration.yaml zuerst folgender Bereich eingefügt:

#Zählerstand Verbrauch
sensor:
  - platform: rest
    resource: http://192.168.178.202:8084/
    value_template: >
      {% for i in value_json.data %}
        {% if i.uuid == "abcdefgh-ijkl-mnop-qrst-uvwxyz012345" %}
           {{ '%.2f'%(i.tuples[0][1]) | float }}
        {% endif %}
      {% endfor %}
    method: GET
    name: "Zählerstand Verbrauch"
    unit_of_measurement: Wh
    device_class: energy

Zu beachten an dieser Stelle: Der String, der aus dem Tuple extrahiert wird, bekommt mittels ‘%.2f’% eine Begrenzung der Kommastellen auf 2. Sonst wird der Float regelmäßig mit einer unterschiedlichen Anzahl Kommastellenangezeigt, was die Lesbarkeit beeinträchtigt. Mittels | float wandel ich den String direkt in einen Float um, damit kann ein PC immer besser umgehen als mit String-Zahlen.

Nun könnte man über sensor.zahlerstand_verbrauch schon den aktuellen Zählerstand in Homeassistandt nutzen, aber unglücklicherweise nicht im neuen Energy-Management. Denn dafür muss der Sensor eine Eigenschaft mit state_class haben – die es aber Stand heute nicht gibt (Featue-Request läuft). Daher müssen einige wenige weitere Anpassungen in der /config/configuration.yaml vorgenommen werden:

homeassistant:
  customize:
    #grid consumption
    sensor.zahlerstand_verbrauch:
      state_class: total_increasing

Mit diesen Zeilen teilen wir Home Assistant mit, dass unser Zählerstand eine Gesamtsumme ist, die immer weiter wächst. So kann dann sensor.zahlerstand_verbrauch auch endgültig ins neue Energy-Management eingefügt werden:

Abschließend sei angemerkt, dass diese Integration im Prinzip mit allen Daten funktioniert, die der vzLogger produziert und das ist eine ganze Menge. Implementiert sind unter anderem das OMS-Protokoll, mit dem man funkende Wasserzähler, elektronische Heizkostenverteile und Wärmemengenzähler empfangen kann, aber auch diverse andere sind auf der Info-Seite vermerkt. Von der verfügbaren volkszähler-Implementierung für Home Assistant kann ich leider nur abraten. Diese bietet weder die Performance wie der hier dargestellte Ansatz, noch können die Daten ins Energy-Management einfließen. Auch würde man sich damit eine doppelte Datenhaltung ins Haus holen.

Stromzähler mit S0-Impulsausgang an Raspberry Pi mit Volkszähler auswerten

Ich nutze seit geraumer Zeit das freies Smart Meter von Volkszähler, um meinen Stromverbrauch am Stromzähler grafisch zu erfassen. Ich habe als Stromzähler eine “moderne Messeinrichtung”, also einen Stromzähler mit SML Datenschnittstelle. Aber um diesen Zähler soll es heute gar nicht gehen. Interessieren soll uns heute ein einfach Wechselstromzähler mit einem Impulsausgang.

Der Impulsausgang wird in diesem Fall “S0”-Schnittstelle genannt und ist nicht mit der gleichnamigen S0-Schnittstelle von ISDN zu verwechseln. Im Prinzip handelt es sich um einen potentialfreien Schaltkontakt, der oft über einen Optokoppler ausgeführt ist, so auch in meinem Beispiel bei dem Wechselstromzähler Typ DDS5188. Dieser gibt wür jede “verbrauchte” Kilowattstunde 2000 Impulse aus, sprich einen Impuls pro 0,5 Wattstunden. Die Anbindung an Volkszähler, genauer gesagt den VZLogger hat mir einiges an grauen Haaren bereitet, denn ich wollte nicht die Impulse aufsummiert dargestellt haben, sondern live die verbrauchte Leistung darstellen.

Hardware-Setup

In den meisten Fällen haben die Zähler einen “S0+”- und einen “S0-“-Anschluss. Ich habe den “S0-“-Anschluss direkt auf Masse gelegt, wenn der Zähler einen Impuls ausgibt, wird der “S0+”-Anschluss also gegen Masse gezogen. Damit dieser sonst nicht in der Luft hängt, kann man am GPIO den Pullup-Widerstand aktivieren, oder man baut einen ein, wie im Schaltplan dargestellt. Wichtig: Die GPIO des Raspberry Pi sind nicht 5V-tolerant, man muss den Pullup also auf 3,3V legen!

Wechselstromzähler mit S0 Impulsausgang am Raspberry Pi Zero

Bei jedem Impuls des Zählers, also bei jeder “verbrauchten” halben Wattstunde bekommt der Raspberry Pi an GPIO 18 (Pin 12) nun also einen negativen Impuls von einigem Millisekunden. Nun gilt es, den vzlogger dafür zu konfigurieren.

Konfiguration des vzloggers

Die Konfiguration des vzloggers befindet sich in der Datei /etc/vzlogger.conf und muss mit root rechten bearbeitet werden. Es folgt eine erläuterte Beispiel-Konfiguration für den Zähler:

{
  "retry": 0,
  "verbosity": 3, //die SD-karte nicht zu sehr belasten...
  "log": "/var/log/vzlogger.log",
  "local": {  //Ich möchte auf lokal auf die Daten zugreifen, ohne push
    "enabled": true,
    "port": 8084,
    "index": true,
    "timeout": 0,
    "buffer": 0
  },
  "meters": [
  {
    "enabled": true,
    "allowskip": false,
    "aggtime": 0, //Die Daten werden nicht zusammengefasst
    "aggfixedinterval": false,
    "aggmode": "sum",
    "protocol": "s0", //S0-Impulse
    "gpio": 18, //Broadcom-Pin an dem der Impulsausgang hängt
    "mmap": "",
    "gpio_dir": -1,
    "configureGPIO": true, //vzlogger soll die GPIO für mich konfigurieren
    "resolution": 1, //hier könnte man die 2000 Impulse pro kWh eintragen
    "send_zero": false, //keine Nullen übertragen
    "channels": [
        {
          "uuid": "4307f540-dcb4-11eb-b124-5da08f82312d",
          "identifier": "Power", //DAS ist die wichtigste Stelle! Wer hier "Impulse" einträgt bekommt nicht die aktuelle Leistung
          "api": "volkszaehler",
          "middleware": "http://localhost/middleware.php",
          "timeout" : 10,
          "duplicates": 30
        }
    ]
  }
  ]
}

Das Ganze kann dann so aussehen:

Leistung dargestellt über die Zeit

Möchte man mehrere Zähler mit einem Raspberry Pi auslesen, so müssen mehrere “meters” in geschweiften Klammern angelegt werden. Leider auch dann, wenn man pro Phase einen S0-Ausgang hat.

Als kleinen Tipp am Ende kann ich noch die fertigen Images für den Raspberry Pi von Volkszähler empfehlen: https://wiki.volkszaehler.org/howto/raspberry_pi_image

IR-Code der Wamsler-Pelletofen-Fernbedienung

Ich besitze einen Pelletofen der Firma Wamsler, genauer gesagt einen Westminster Quattro 6. Dieser Ofen kann über eine IR-Fernbedienung “programmiert” werden, sprich es können Parameter wie Solltemperatur, Timer, Lüftergeschwindigkeit usw. eingestellt werden und zuguterletzt der Ofen natürlich ein- und ausgeschaltet werden. Ich möchte diese Funktionen jedoch aus der Ferne steuern können – beispielsweise den Ofen von der Arbeit aus vorheizen.

Dafür bietet die Firma Wamsler zwar ein WiFi-Modul mit Cloudanbindung an, aber dieses kann ich nicht nur nicht in meine private Hausautomatisierung integrieren, es weist auch einige weitere gravierende Nachteile auf, die mich bewogen haben, das Gerät nicht einzusetzen. Zu den eben erwähnten Gründen zählt unter anderem, dass die Identifikation nur über eine numerische Hardware-ID erfolgt, ohne Passwortschutz. Finde ich die Hardware-ID eines anderen WiFi-Moduls heraus, kann ich diesen steuern – ein eklatanter Sicherheitsmangen. Abgesehen davon sind rund 150€ für ein ESP-Modul auf einer Platine mit 3 LEDs in einem Gehäuse ohne CE-Kennzeichnung eine Fars.

Daher habe ich mich entschlossen, mit das Übermittlungsprotokoll der Fernbedienung genauer anzusehen und bin über die Variation alles einstellbaren Parameter zu folgender Liste gekommen:

areaexplenationcalculationunit
bit 0 to 1currently unknown
bit 2timer “auto”1 = true, 0 = false
bit 3stove on / off1 = on, 0 = off
bit 4“turbo” mode on / off1 = on, 0 = off
bit 5 to 7blower level1 + binToDec; 6 = AUTO
bit 8“econo” mode on / off1 = on, 0 = off
bit 9currently unknown
bit 10 to 15temperature7 + binToDec°C
bit 16 to 20timer 1 ON hourbinToDechours
bit 21 to 23timer 1 ON minutebinToDec * 10minutes
bit 24 to 28timer 1 OFF hourbinToDechours
bit 29 to 31timer 1 OFF minutebinToDec * 10minutes
bit 32 to 36timer 2 ON hourbinToDechours
bit 37 to 39timer 2 ON minutebinToDec * 10minutes
bit 40 to 44timer 2 OFF hourbinToDechours
bit 45 to 47timer 2 OFF minutebinToDec * 10minutes
bit 48 to 49currently unknown, maybe part of 50..55
bit 50 to 55hour of daybinToDechours
bit 56 to 57currently unknown, maybe part of 59..64
bit 59 to 63minute of daybinToDecminutes
bit 64timer 1 ON active1 = true, 0 = false
bit 65timer 1 OFF active1 = true, 0 = false
bit 66timer 2 ON active1 = true, 0 = false
bit 67timer 1 OFF active1 = true, 0 = false
bit 68 to 71custom checksumsee below
Wamsler-IR-Fernbedienungsprotokoll, siehe hier

Um nun eigene Telegramme zu erstellen habe ich eine C++-Klasse geschrieben, über die alle Parameter festgelegt werden können und am Ende ein valides Telegramm auswerfen kann.

#pragma once
#include <string>
#include <iostream>

class telegram
{
public:
	//Variablen
	int OnOff = 0;	
	int AUTOTimer = 0;
	int Turbo = 0;
	int Econo = 0;
	int timer1onActive = 0;
	int timer1offActive = 0;
	int timer2onActive = 0;
	int timer2offActive = 0;

	//Funktionen, Set
	bool setBlowerLevel(int level = 0);
	bool setTemperature(int temperature = 20);
	bool setTimer1on(int hour = 0, int minute = 0);
	bool setTimer1off(int hour = 0, int minute = 0);
	bool setTimer2on(int hour = 0, int minute = 0);
	bool setTimer2off(int hour = 0, int minute = 0);
	bool setTime(int hour = 0, int minute = 0);

	//Funktionen, Output
	std::string toString();
	

private:
	bool data[72] = { 0 };	
	bool calcTelegram();
	bool calcPruefsumme();
};

Der entsprechende Programmcode und ein Beispiel ist auch schon auf Github zu finden. Nächster Schritt wird nun, einen Arduino-kompatiblen Mikrocontroller mit RTC als Sender zu programmieren und eine entsprechende Web-Schnittstelle zur Verfügung zu stellen. Wenn es soweit ist, wird dieser Artikel aktualisiert.

VDSL-Ausbau in Neukirchen / Pleiße teilweise abgeschlossen

Nach aktuellen Informationen von Georg von Wagner, dem Pressesprecher der Telekom, wurde der Breitbandausbau in Neukirchen / Pleße teilweise abgeschlossen.

[…] von den zwölf Kabelverzweigern, die in Neukirchen/Pleiße modernisiert werden sollen, sind neun umgestellt. Bei den drei restlichen kommt es zu Verzögerungen, weil wir dort bisher keine Genehmigung erhalten haben. Einer von den drei soll dem Vernehmen nach in den kommenden zwei bis drei Wochen in Betrieb gehen. Für die anderen beiden liegen derzeit keine Fertigstellungstermine vor.

Georg von Wagner, Corporate Communications, Pressesprecher Telekom

Mittlerweile kann ich eine erfolgte Schaltung im Bereich der Gartenstraße (100Mbit/s) und des Carthäuserwegs (ca 75Mbit/s), sowie mehrere weitere erfolgreiche Anträge auf einen Technologiewechsel (100Mbit/s und 50Mbit/s) bestätigen. Die Information die mir leider noch fehlt, ist, wo die drei Bereiche sind, in denen noch kein Ausbau erfolgt ist.

Wie komme ich zu schnellem Internet?

Wer jetzt schon umsteigen möchte, dem empfehle ich bei der Hotline seines Internetanbieters anzurufen um einen “Technologiewechsel” zu beantragen. Wichtig ist aber, sich vorher schlau zu machen, welche Tarife es zu welchem Preis gibt (Info hier), damit einem kein teurerer Vertrag “angedreht” wird. Meine Empfehlung: Ein Angebot per E-Mail zuschicken lassen, dass dann online bestätigt werden muss. Das können heutzutage alle Anbieter.

Je nach dem, wie nah man am Verteilerkasten ist, können nach meiner Recherche bis zu 250 Mbit/s gebucht werden. Für die meisten Haushalte sollte jedoch eine 50 MBit/s Leitung ausreichen. Sind Kinder (auch größere) im Haushalt, oder Homeoffice angesagt, so kann sich ein 100 Mbit/s Anschluss lohnen. Gründe für die 250 Mbits/s oder für die Tarife mit 175 Mbit/s sehe ich derzeit nur für große Haushalte mit mehr als 4 Personen.

Ich würde mich freuen, wenn ihr hier kommentiert, wo Ihr erfolgreich oder nicht erfolgreich einen Technologiewechsel beantragt habt und wann eine Schaltung des neuen Anschlusses mit welcher Geschwindigkeit erfolgt ist!

[Update 27.01.2021]

Mittlerweile ist unsere Leitung seit knapp einer Woche geschaltet und stabil. Bei einer Leitungslängte von rund 480m zur DSL Vermittlungsstelle erreichen wir stabil 88 Mbit/s in Empfangsrichtung und 35 Mbit/s in Senderichtung (gebucht 100 / 40 Mbit/s). Das ist – insbesondere in Anbetracht des Abstands zum Outddor DSLAM – ein sehr guter Wert. Zuerst hatte unsere Leitung nur mit 75 / 33 Mbit/s synchronisiert, nach einem Austausch der Leitung von der “Telefon”-dose zum DSL-Modem gegen ein wesentlich kürzeres konnte die Datenrate nochmal auf die oben genannten 88 / 35 Mbit/s gesteigert werden. Es sei erwähnt, dass dies überdurchschnittlich gut ist bei der Leitungslänge.

Fritz!Box DSL Übersicht
Fritz!Box DSL
Fritz!Box DSL Spektrum

[Update 29.01.2021]

Die Telekom hat ihre Ausbaukarte für Neukirchen aktualisiert. Nun sind die ausgebauten Bereiche endlich markiert.

Screenshot Karte Bretbandausbau telekom.de

Alles südlich der Bahnhofstraße jedoch ist absolut unausgebaut – da dürften die 2 bis 3 unausgebauten Kösten stehen, die Herr von Wagner erwähnt hat.