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.

Home Assistant Energie Dashboard

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.conf” 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.

Tobi

Hallo, mein Name ist Tobias und ich habe diesen Blog im April 2009 ins Leben gerufen. Seitdem blogge ich hier über Software, Internet, Windows und andere Themen, die mich interessieren. SSDblog ist mein zweiter Blog, indem es rund um das Thema SSDs geht. Ich würde mich freuen, wenn ihr meinen Feed abonniert oder mir auf Twitter und Facebook folgt.

17 Antworten

  1. Rene sagt:

    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é

    • Tobi sagt:

      Hi René,
      danke für dein Lob.

      In den Container-Einstellungen unter “Advanced container settings” –> “Command & logging” –> “User”:

    • Daniel sagt:

      Hi Tobi,

      ich sitze hier nun seit Stunden und komme schlichtweg nicht weiter.
      Trotz des root Users kommt beim Start die Meldung: “opening logfile “/var/log/vzlogger/vzlogger.log” failed: No such file or directory”

      Woran kann das denn liegen?

      Grüße
      Daniel

    • Tobi sagt:

      Der richtige Pfad ist “/var/log/vzlogger.log”.

  2. Rene sagt:

    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é

    • Tobi sagt:

      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.

    • Moritz sagt:

      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

  3. Moritz sagt:

    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

    • Tobi sagt:

      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:

  4. Marko Junker sagt:

    Hi Tobi, toller Beitrag und Anleitung.

    Habe eine Frage. Ich habe auch einen Raspi im Hauptverteiler und dort zwei IR-Leseköpfe angeschlossen, wegen Wärmepumpe.

    Die Leseköpfe funktionieren und liefern Daten. Habe ich gecheckt via “cat /dev/ttyUSB0 und /dev/ttyUSB1”. Jetzt würde ich gerne via usb over ip lösen und Homeassistant die Schnittstellen über das Netzwerk zur Verfügung stellen. Dafür würde ich Proxmox als USB-Client installieren/konfigurieren und dann die Schnittstellen in die HA VM durchreichen. Danach die weitere Konfigruation in HA nach deinem Beispiel.

    Hast du auch darüber nachgedacht, hast du evtl. Erfahrung damit, weil ich stelle mir das bis jetzt nur in der Theorie vor, ohne zu wissen, ob sich das realisieren läßt. Oder hättest du noch einen anderen Vorschlag ?

    Danke für evtl. Antwort/en… :))

    • Tobi sagt:

      Ich wollte bei mir den Raspberry Pi komplett entfernen, darum war das keine Option.

      Ich verstehe ehrlich gesagt auch nicht, was du damit bezwecken möchtest? Den Raspberry Pi brauchst du in deiner Variante ja sowieso!? Daher spricht doch nichts dagegen die Daten via HTTP oder MQTT vom Raspberry Pi zu holen. Ist meiner Meinung nach deutlich einfacher und zuverlässiger als die Variante USB over IP.

  5. Juliane sagt:

    Ich habe das jetzt fast 2 Wochen versucht, zum Laufen zu bekommen, ohne Erfolg. Alles wie beschrieben gemacht, ich komme zu dem Schluss, dass mein Stromzähler gar nicht geeignet ist für das Vohaben, schade!

  6. Marko Junker sagt:

    Hi Tobi, danke für deine Antwort.

    Mein Pi ist einer der ersten Generation (wurde noch mit T-Shirt ausgelierfert) und ich hatte hier noch zwei USB IR-Leseköpfe für meine beiden “smarten” Stromzähler.

    Somit konnte ich beide an einem Device anschließen und hatte zusätzlich alles über LAN und nicht WLAN. Mein Home-Assistant ist nicht in der Nähe unseres Hauptverteilerkastens.

    Die Hauptrechenleistung (SML Protokol) soll nicht der Pi tragen, deswegen USB over IP oder ser2net nach Proxmox und dann in die VM Home-Assistant durchreichen.

    • Tobi sagt:

      OK dann verstehe ich dein Anliegen etwas besser. Dann könntest du es mit usbip versuchen. Allerdings kann ich dir hier keine Hilfestellung geben, da ich damit selbst noch nie gearbeitet hatte.

      Ich würde davor dennoch die Variante mit vzlogger auf dem Raspberry Pi ausprobieren. Kann mir nicht vorstellen, dass die Verarbeitung viel Rechenleistung benötigt. Mein eHZ-K Stromzähler arbeitet im Push-Betrieb und sendet die Daten alle 4 Sekunden. Das sollte selbst für einen Raspberry Pi 1 kein Problem darstellen. Wie schon erwähnt denke ich, dass diese Variante zuverlässiger arbeitet :)

  7. Marko Junker sagt:

    Hi Tobi.
    Habe es jetzt erstmal mit ser2net (ist im Repo von Bullseye) auf dem RPI1 realisiert. Kann nun auch über http und dem entsprechend konfigurierten Port in ser2net den Output von den beiden USB IR-Leseköpfen.

    Werde nun hingehen und in HA in der configuration.yaml einen Sensor mit den entsprechenden obis parametern versuchen anzulegen und dann mal schaun.

  8. Domi sagt:

    Hi Tobi, ich Versuche seit einiger Zeit auch meinen Stromzähler auszulesen. Mit dem Volkszähler und vzlogger klappt das auch. Mein Problem aber ist, ich möchte in Home Assistant die aktuelle Leistung haben, die im Haus benötigt wird. Aber den Wert habe ich bisher nicht in HA bekommen, auch nicht mit deiner Anleitung (aktueller Stromverbrauch) Ich habe das Gefühl, das immer ein Durchschnittswert für die aktuelle Leistung übermittelt wird, aber nicht der aktuelle Wert. Am Zähler sehe ich genau (unter 16.7.0), welche aktuelle Leistung abgerufen wird. Dieser Wert ist komplett anders zu dem was ich dann in dem Json File von dem Kanal auslese. Wie komme ich wirklich an den aktuellen Wert und nicht den average? Oder ist das bei deiner Lösung oben so, dass Du wirklich unter aktuellem Stromverbrauch auch die aktuelle Leistung bekommst? Danke und Gruss Domi

    • Tobi sagt:

      Hallo Domi,
      ja ich bekomme die aktuelle Leistung.
      Welchen Zähler hast du denn und was zeigt der Zähler selber an?
      Als Fehlerquellen könnte ich mir eine falsche “vzlogger.conf” vorstellen, oder dass der Zähler nicht freigeschaltet wurde.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert