Stromzähler via IR-Lesekopf auslesen und Daten in Home Assistant erfassen
Meinen Stromzähler lese ich schon länger mit Hilfe eines IR-Schreib-Lesekopfs aus. Dieser hing bisher via USB-Interface an einem Raspberry Pi 3B+ mit vzlogger. Die Daten werden dann in Home Assistant erfasst und visualisiert. Grundsätzlich funktionierte die Variante sehr gut. Allerdings habe ich auf dem Raspberry Pi zwischendurch immer wieder andere Dinge getestet und das ein oder andere Mal musste ich ihn daher neu aufsetzen. Darüber hinaus wollte ich schon länger alle Services meines Smart Homes auf mein Intel NUC umziehen. Gesagt, getan. Heute war es soweit.
Für den Umbau muss sich das Intel NUC natürlich in der Nähe des Stromzählers befinden, da sonst der IR-Schreib-Lesekopf nicht via USB verbunden werden kann. In meinem Fall ist die Anschlussleitung ca. 2 Meter lang. Da sich mein Netzwerkschrank mit dem NUC in der Nähe befindet, war das Kabel geradeso ausreichend. Alternativ kann natürlich auch ein längeres Kabel verlötet werden. Mehr als 5 Meter sollten es aber nicht sein. Eine andere Möglichkeit wäre das Gerät, welches das Auslesen übernimmt, näher an den Lesekopf zu platzieren. Beispielsweise mit einem WLAN-fähigen IR-Schreib-Lesekopf, einem ESP32 oder einem Raspberry Pi. Aber genau diese Variante möchte ich in meinem Fall ja ersetzen… ;-)
Umsetzung
Hier eine kleine Übersicht, wie mein aktueller Aufbau aussieht:
EMH Metering eHZ-K Stromzähler –> IR-Schreib-Lesekopfs mit USB-Schnittstelle –> Intel NUC 11 –> Proxmox 7.3 –> Debian-VM (Docker Host) –> vzlogger 0.8.1 Docker-Container –> Home Assistant 2022.12.0
Zunächst habe ich den IR-Schreib-Lesekopf via USB mit meinem Intel NUC 11 verbunden. Über die Proxmox-Shell kann man prüfen, ob der IR-Schreib-Lesekopf erkannt wurde. Dieser Schritt kann in der Regel übersprungen werden, da das Gerät auch automatisch in der GUI verfügbar ist, sofern es keine Probleme beim Verbinden gab.
lsusb
Bus 001 Device 002: ID 10c4:ea60 Silicon Labs CP210x UART Bridge
In der Proxmox-Weboberfläche habe ich nun das USB-Gerät vom Proxmox-Host an meine Docker-VM durchgereicht. Dies funktioniert bei der entsprechenden VM unter “Hardware” mit Klick auf den Button “Add” und “USB Device”. Anschließend öffnet sich ein Dialog und unter “Use USB Port” sollte das gewünschte Gerät auftauchen. Dieses auswählen und mit “Add” bestätigen.
Die VM muss neugestartet werden, damit die Änderung wirksam und das USB-Gerät durchgeschleift wird.
Jetzt wird vzlogger als Docker-Container installiert. Zur Erstellung des Containers nutze ich Portainer.
Als Image verwende ich “stefanschoof/vzlogger:latest”. Darüber hinaus musste ich noch ein paar Dinge anpassen bzw. ergänzen.
- Port-Forwarding für Nutzung der REST-API einrichten, ich nutze Port 8081
- /etc des Containers auf den Docker Host mappen, sodass die Konfigurationsdatei einen Neustart des Containers überlebt
- User von “vz” in “root” ändern, da ansonsten kein Zugriff auf das Logfile “/var/log/vzlogger.log” möglich ist und vzlogger nicht startet
- IR-Schreib-Lesekopf vom Docker Host an den Container durchreichen
Für letzteres benötigen wir den genauen Pfad des USB-Geräts am Docker Host. Dieser kann folgendermaßen herausgefunden werden:
ls /dev/serial/by-id/
usb-Silicon_Labs_CP2104_USB_to_UART_Bridge_Controller_01A62BBF-if00-port0
Vom Host mappen wir also “/dev/serial/by-id/usb-Silicon_Labs_CP2104_USB_to_UART_Bridge_Controller_01A62BBF-if00-port0” in den Container als “/dev/ttyUSB0”.
Als letztes wird noch die “vzlogger.conf” benötigt. Ich konnte meine funktionsfähige Konfiguration direkt vom Raspberry Pi übernehmen und nach “/var/lib/docker/volumes/vzlogger_data/_data” auf dem Docker Host kopieren. Dadurch wird diese wie oben beschrieben im Container auf “/etc” gemappt.
Meine “vzlogger.conft” sieht folgendermaßen aus:
{
"retry": 0,
"daemon": true,
"verbosity": 0,
"log": "/var/log/vzlogger.log",
"push": [],
"local": {
"enabled": true,
"port": 8081,
"index": true,
"timeout": 0,
"buffer": 0
},
"meters": [
{
"enabled": true,
"allowskip": false,
"interval": -1,
"aggtime": -1,
"aggfixedinterval": true,
"channels": [
{
"uuid": "5078eef0-ea52-22e7-a3bb-8fdc47e03f0e",
"identifier": "1-0:1.8.0",
"api": "null",
"aggmode": "none"
},
{
"uuid": "9b835b00-ea52-22e7-a5c9-df2124ec3246",
"identifier": "1-0:2.8.0",
"api": "null",
"aggmode": "none"
},
{
"uuid": "88888888-2222-1111-aaaa-dd2222cc1111",
"identifier": "1-0:16.7.0",
"api": "null",
"aggmode": "none"
}
],
"protocol": "sml",
"device": "/dev/ttyUSB0",
"baudrate": 9600,
"parity": "8n1"
}
]
}
Sofern keine fertige “vzlogger.conf” existiert, kann diese mit Hilfe der Dokumentation, Beispiel-Konfigurationen und des Konfigurations-Editors selber erstellt werden.
Jetzt kann der Container gestartet werden. Wenn im Container Log keine Fehler erscheinen, passt alles.
Über das vorher eingerichtete Port-Forwarding kann man nun im Browser bereits die ausgelesenen Daten einsehen. Bei mir über “http://10.10.70.3:8081”.
In Home Assistant lese ich die Daten vom vzlogger via REST-API aus. Folgenden Code nutze ich in der “configuration.yaml”:
- platform: rest
name: stromzaehler_gesamtverbrauch_volkszaehler
device_class: 'energy'
state_class: 'total_increasing'
unit_of_measurement: "kWh"
scan_interval: 10
resource: http://10.10.70.3:8081
value_template: >
{% for i in value_json.data %}
{% if i.uuid == "5078eef0-ea52-22e7-a3bb-8fdc47e03f0e" %}
{{ i.tuples[0][1]|round(0) / 1000 }}
{% endif %}
{% endfor %}
method: GET
- platform: rest
name: stromzaehler_aktuellerverbrauch_volkszaehler
device_class: 'power'
state_class: 'measurement'
unit_of_measurement: "W"
scan_interval: 10
resource: http://10.10.70.3:8081
value_template: >
{% for i in value_json.data %}
{% if i.uuid == "88888888-2222-1111-aaaa-dd2222cc1111" %}
{{ i.tuples[0][1]|round(0) }}
{% endif %}
{% endfor %}
method: GET
Diese Variante habe ich bereits beim Raspberry Pi verwendet, welche bisher ohne Probleme funktioniert hatte. Daher habe ich lediglich die IP-Adressen angepasst und den Code ansonsten unverändert übernommen. In der Zukunft werde ich das Ganze aber ggf. noch gauf MQTT umbauen.
Hallo Tobi,
toller Beitrag. Ich versuche gerade auf diese Weise den Vzlogger über Portainer in HA einzubinden. Kannst du genauer sagen wie das mit der Änderung des Users von vz nach root funktioniert? Ich habe im Portainer schon ein Label (User root) eingetragen. Der Container läuft aber scheinbar weiterhin unter vz. Damit hat er keinen Zugriff auf /dev/ttyUSB0.
Gruß
René
Hi René,
danke für dein Lob.
In den Container-Einstellungen unter “Advanced container settings” –> “Command & logging” –> “User”:

Hi Tobi,
besten Dank. Ich habe echt schon überall gesucht. Da war ich wohl blind. Hatte es schon über Variablen unter Labels versucht. Manchmal ist es so einfach :).
Hast du deine Lösung zufällig schon auf MQTT umgestellt? Ich bin noch ziemlich neu in Home Assistant. Habe nun den Vzlogger laufen und schreibe aktuell parallel nach Influx und sende an MQTT. Die Darstellung im Energie Dashboard liegt noch vor mir.
Gruß
René
Hi René,
nein noch nicht. Aktuell habe ich nichts über MQTT laufen, daher gehe ich das erst an, wenn etwas anderes MQTT benötigt. Wird dann vermutlich der Wasserzähler werden, dauert aber sicher noch ein paar Wochen bis Monate.
Hi René,
vlt. hilft dir meine (geringe) Erfahrung ja weiter…ich lese die vzlogger-Topics, die in der vzlogger.conf definiert sind, in HA mit diesem Add-On: https://github.com/thomasnordquist/MQTT-Explorer
Um sie verweden zu können, habe ich drei simple Sensoren in angelegt:
mqtt:
sensor:
– state_topic: vzlogger/data/chn0/raw
name: “vz_aktueller_verbrauch”
unit_of_measurement: “W”
– state_topic: vzlogger/data/chn1/raw
name: “vz_zaehlerstand_einspeisung”
unit_of_measurement: “Wh”
– state_topic: vzlogger/data/chn2/raw
name: “vz_zaehlerstand_bezug”
unit_of_measurement: “Wh”
Da mir die Einheiten nicht gepasst haben, habe ich noch folgende Sensoren ergänzt:
# VZlogger Einheiten
– sensor:
– name: VZ Bezug
unique_id: vz_bezug
device_class: power
state: “{{ (states(‘sensor.vz_zaehlerstand_bezug’) | float(0) * 0.001) | round(2) }}”
unit_of_measurement: “kWh”
– sensor:
– name: VZ Einspeisung
unique_id: vz_einspeisung
device_class: power
state: “{{ (states(‘sensor.vz_zaehlerstand_einspeisung’) | float(0) * 0.001) | round(2) }}”
unit_of_measurement: “kWh”
– sensor:
– name: VZ Wirkleistung
unique_id: vz_wirkleistung
device_class: power
state: “{{ states(‘sensor.vz_aktueller_verbrauch’) | float(0) | round(2) }}”
unit_of_measurement: “W”
LG Moritz
Hi Tobi,
vielen Dank für Deine tolle Beschreibung und auch die Hinweise hier in den Kommentaren! Ich habe aktuell eine lauffähige Version auf einem Zero W, die ich mit deiner Anleitung umziehen möchte. Leider fehlt es mir an einigen Grundkenntnissen und ich muss mich eng an den Anleitungen entlang hangeln…
Daher bin ich auch damit überfordert “/etc des Containers auf den Docker Host [zu] mappen”. Kannst du mirzu auch einen weiteren Hinweis geben?
Ich weiß auch aktuell nicht, wie ich die vzlogger.conf von meinem zero w in den neuen container kopieren kann. Kannst du mir auch dabei helfen?
LG Moritz
Hi Moritz,
klar :)
Wenn du dich via SSH auf deinem Zero W verbindest, kannst du ganz einfach den Inhalt deiner alten “vzlogger.conf” ausgeben lassen, z.B. mit “less” oder “cat”. Diesen Inhalt kopierst du einfach und erstellst im Container eine neue “vzlogger.conf”, in welcher du den kopierten Inhalt einfügst.
Bezüglich mappen von “/etc” musst du zuerst ein neues Volume in Portainer anlegen. Sollte dann ungefähr so aussehen:

Anschließend kannst du “/etc” dann im vzlogger-Container mappen:
