Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Einsteigerfragen
  4. Sofar Solar HYD10 KTL Wechselrichter an modbus Adapter

NEWS

  • Jahresrückblick 2025 – unser neuer Blogbeitrag ist online! ✨
    BluefoxB
    Bluefox
    17
    1
    2.5k

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    13
    1
    987

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    25
    1
    2.3k

Sofar Solar HYD10 KTL Wechselrichter an modbus Adapter

Geplant Angeheftet Gesperrt Verschoben Einsteigerfragen
187 Beiträge 20 Kommentatoren 25.1k Aufrufe 16 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • spicerS spicer

    Schon wieder. Adapter lief ca 3-4h.
    Man siehe den Log ab 2026-02-06 03:59:39.013.
    Da stirbt die Übertragung langsam bis ab 2026-02-06 03:59:56.664 nix mehr kommt.
    Wie bereits gesagt, funktioniert alles wieder nach einem Adapter neustart.

    2026-02-06 03:59:02.830  - info: modbus.0 (919438) Connected to slave 192.168.88.101
    2026-02-06 03:59:02.831  - debug: modbus.0 (919438) [DevID_1] Poll start ---------------------
    2026-02-06 03:59:02.831  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 - 1 registers
    2026-02-06 03:59:02.897  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 DONE
    2026-02-06 03:59:03.148  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1160 - 1 registers
    2026-02-06 03:59:03.207  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1160 DONE
    2026-02-06 03:59:03.458  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1476 - 1 registers
    2026-02-06 03:59:03.517  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1476 DONE
    2026-02-06 03:59:03.768  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1542 - 1 registers
    2026-02-06 03:59:03.827  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1542 DONE
    2026-02-06 03:59:04.078  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1544 - 1 registers
    2026-02-06 03:59:04.138  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1544 DONE
    2026-02-06 03:59:04.388  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1668 - 2 registers
    2026-02-06 03:59:04.477  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1668 DONE
    2026-02-06 03:59:10.408  - debug: modbus.0 (919438) Socket closed with error
    2026-02-06 03:59:10.408  - debug: modbus.0 (919438) Clearing timeout of the current request.
    2026-02-06 03:59:10.408  - debug: modbus.0 (919438) Cleaning up request fifo.
    2026-02-06 03:59:11.409  - debug: modbus.0 (919438) Closing client on purpose.
    2026-02-06 03:59:11.410  - info: modbus.0 (919438) Disconnected from slave 192.168.88.101
    2026-02-06 03:59:21.412  - info: modbus.0 (919438) Connected to slave 192.168.88.101
    2026-02-06 03:59:21.413  - debug: modbus.0 (919438) [DevID_1] Poll start ---------------------
    2026-02-06 03:59:21.413  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 - 1 registers
    2026-02-06 03:59:21.478  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 DONE
    2026-02-06 03:59:21.729  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1160 - 1 registers
    2026-02-06 03:59:21.788  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1160 DONE
    2026-02-06 03:59:22.039  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1476 - 1 registers
    2026-02-06 03:59:22.098  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1476 DONE
    2026-02-06 03:59:22.349  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1542 - 1 registers
    2026-02-06 03:59:22.408  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1542 DONE
    2026-02-06 03:59:22.659  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1544 - 1 registers
    2026-02-06 03:59:22.738  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1544 DONE
    2026-02-06 03:59:22.989  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1668 - 2 registers
    2026-02-06 03:59:23.048  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1668 DONE
    2026-02-06 03:59:28.009  - debug: modbus.0 (919438) Socket closed with error
    2026-02-06 03:59:28.009  - debug: modbus.0 (919438) Clearing timeout of the current request.
    2026-02-06 03:59:28.009  - debug: modbus.0 (919438) Cleaning up request fifo.
    2026-02-06 03:59:29.011  - debug: modbus.0 (919438) Closing client on purpose.
    2026-02-06 03:59:29.011  - info: modbus.0 (919438) Disconnected from slave 192.168.88.101
    2026-02-06 03:59:39.013  - info: modbus.0 (919438) Connected to slave 192.168.88.101
    2026-02-06 03:59:39.014  - debug: modbus.0 (919438) [DevID_1] Poll start ---------------------
    2026-02-06 03:59:39.014  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 - 1 registers
    2026-02-06 03:59:39.079  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 DONE
    2026-02-06 03:59:39.330  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1160 - 1 registers
    2026-02-06 03:59:39.389  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1160 DONE
    2026-02-06 03:59:39.639  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1476 - 1 registers
    2026-02-06 03:59:45.659  - debug: modbus.0 (919438) Socket closed with error
    2026-02-06 03:59:45.660  - debug: modbus.0 (919438) Clearing timeout of the current request.
    2026-02-06 03:59:45.660  - debug: modbus.0 (919438) Cleaning up request fifo.
    2026-02-06 03:59:46.660  - debug: modbus.0 (919438) Closing client on purpose.
    2026-02-06 03:59:46.661  - info: modbus.0 (919438) Disconnected from slave 192.168.88.101
    2026-02-06 03:59:56.664  - info: modbus.0 (919438) Connected to slave 192.168.88.101
    2026-02-06 03:59:56.664  - debug: modbus.0 (919438) [DevID_1] Poll start ---------------------
    2026-02-06 03:59:56.665  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 - 1 registers
    2026-02-06 04:00:02.690  - debug: modbus.0 (919438) Socket closed with error
    2026-02-06 04:00:02.690  - debug: modbus.0 (919438) Clearing timeout of the current request.
    2026-02-06 04:00:02.690  - debug: modbus.0 (919438) Cleaning up request fifo.
    2026-02-06 04:00:03.692  - debug: modbus.0 (919438) Closing client on purpose.
    2026-02-06 04:00:03.692  - info: modbus.0 (919438) Disconnected from slave 192.168.88.101
    2026-02-06 04:00:13.696  - info: modbus.0 (919438) Connected to slave 192.168.88.101
    2026-02-06 04:00:13.696  - debug: modbus.0 (919438) [DevID_1] Poll start ---------------------
    2026-02-06 04:00:13.696  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 - 1 registers
    2026-02-06 04:00:19.720  - debug: modbus.0 (919438) Socket closed with error
    2026-02-06 04:00:19.720  - debug: modbus.0 (919438) Clearing timeout of the current request.
    2026-02-06 04:00:19.720  - debug: modbus.0 (919438) Cleaning up request fifo.
    2026-02-06 04:00:20.721  - debug: modbus.0 (919438) Closing client on purpose.
    2026-02-06 04:00:20.722  - info: modbus.0 (919438) Disconnected from slave 192.168.88.101
    2026-02-06 04:00:30.725  - info: modbus.0 (919438) Connected to slave 192.168.88.101
    2026-02-06 04:00:30.726  - debug: modbus.0 (919438) [DevID_1] Poll start ---------------------
    2026-02-06 04:00:30.726  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 - 1 registers
    2026-02-06 04:00:36.751  - debug: modbus.0 (919438) Socket closed with error
    2026-02-06 04:00:36.751  - debug: modbus.0 (919438) Clearing timeout of the current request.
    2026-02-06 04:00:36.751  - debug: modbus.0 (919438) Cleaning up request fifo.
    2026-02-06 04:00:37.752  - debug: modbus.0 (919438) Closing client on purpose.
    2026-02-06 04:00:37.753  - info: modbus.0 (919438) Disconnected from slave 192.168.88.101
    2026-02-06 04:00:47.756  - info: modbus.0 (919438) Connected to slave 192.168.88.101
    2026-02-06 04:00:47.757  - debug: modbus.0 (919438) [DevID_1] Poll start ---------------------
    2026-02-06 04:00:47.757  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 - 1 registers
    2026-02-06 04:00:53.781  - debug: modbus.0 (919438) Socket closed with error
    2026-02-06 04:00:53.782  - debug: modbus.0 (919438) Clearing timeout of the current request.
    2026-02-06 04:00:53.782  - debug: modbus.0 (919438) Cleaning up request fifo.
    2026-02-06 04:00:54.782  - debug: modbus.0 (919438) Closing client on purpose.
    2026-02-06 04:00:54.783  - info: modbus.0 (919438) Disconnected from slave 192.168.88.101
    2026-02-06 04:01:04.785  - info: modbus.0 (919438) Connected to slave 192.168.88.101
    2026-02-06 04:01:04.786  - debug: modbus.0 (919438) [DevID_1] Poll start ---------------------
    2026-02-06 04:01:04.786  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 - 1 registers
    2026-02-06 04:01:10.812  - debug: modbus.0 (919438) Socket closed with error
    2026-02-06 04:01:10.812  - debug: modbus.0 (919438) Clearing timeout of the current request.
    2026-02-06 04:01:10.813  - debug: modbus.0 (919438) Cleaning up request fifo.
    2026-02-06 04:01:11.812  - debug: modbus.0 (919438) Closing client on purpose.
    2026-02-06 04:01:11.813  - info: modbus.0 (919438) Disconnected from slave 192.168.88.101
    2026-02-06 04:01:21.815  - info: modbus.0 (919438) Connected to slave 192.168.88.101
    2026-02-06 04:01:21.816  - debug: modbus.0 (919438) [DevID_1] Poll start ---------------------
    2026-02-06 04:01:21.816  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 - 1 registers
    2026-02-06 04:01:27.843  - debug: modbus.0 (919438) Socket closed with error
    2026-02-06 04:01:27.843  - debug: modbus.0 (919438) Clearing timeout of the current request.
    2026-02-06 04:01:27.843  - debug: modbus.0 (919438) Cleaning up request fifo.
    2026-02-06 04:01:28.845  - debug: modbus.0 (919438) Closing client on purpose.
    2026-02-06 04:01:28.845  - info: modbus.0 (919438) Disconnected from slave 192.168.88.101
    

    Konfiguration:

    grafik.png

    grafik.png

    grafik.png

    HomoranH Nicht stören
    HomoranH Nicht stören
    Homoran
    Global Moderator Administrators
    schrieb am zuletzt editiert von
    #178

    @spicer sagte in Sofar Solar HYD10 KTL Wechselrichter an modbus Adapter:

    Da stirbt die Übertragung langsam bis ab 2026-02-06 03:59:56.664 nix mehr kommt.

    was startet bei dir um 04:00?

    kein Support per PN! - Fragen im Forum stellen - es gibt fast nichts, was nicht auch für andere interessant ist.

    Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

    der Installationsfixer: curl -fsL https://iobroker.net/fix.sh | bash -

    1 Antwort Letzte Antwort
    0
    • spicerS Offline
      spicerS Offline
      spicer
      schrieb am zuletzt editiert von spicer
      #179

      Laut Log nichts zur Fraglichen Zeit.
      Die gelesenen Register nehmen schon vor sofarcloud und weathersense ab.

      2026-02-06 03:59:39.013  - info: modbus.0 (919438) Connected to slave 192.168.88.101
      2026-02-06 03:59:39.014  - debug: modbus.0 (919438) [DevID_1] Poll start ---------------------
      2026-02-06 03:59:39.014  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 - 1 registers
      2026-02-06 03:59:39.079  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 DONE
      2026-02-06 03:59:39.330  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1160 - 1 registers
      2026-02-06 03:59:39.389  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1160 DONE
      2026-02-06 03:59:39.639  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1476 - 1 registers
      2026-02-06 03:59:45.659  - debug: modbus.0 (919438) Socket closed with error
      2026-02-06 03:59:45.660  - debug: modbus.0 (919438) Clearing timeout of the current request.
      2026-02-06 03:59:45.660  - debug: modbus.0 (919438) Cleaning up request fifo.
      2026-02-06 03:59:46.660  - debug: modbus.0 (919438) Closing client on purpose.
      2026-02-06 03:59:46.661  - info: modbus.0 (919438) Disconnected from slave 192.168.88.101
      2026-02-06 03:59:56.664  - info: modbus.0 (919438) Connected to slave 192.168.88.101
      2026-02-06 03:59:56.664  - debug: modbus.0 (919438) [DevID_1] Poll start ---------------------
      2026-02-06 03:59:56.665  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 - 1 registers
      2026-02-06 04:00:02.690  - debug: modbus.0 (919438) Socket closed with error
      2026-02-06 04:00:02.690  - debug: modbus.0 (919438) Clearing timeout of the current request.
      2026-02-06 04:00:02.690  - debug: modbus.0 (919438) Cleaning up request fifo.
      2026-02-06 04:00:03.692  - debug: modbus.0 (919438) Closing client on purpose.
      2026-02-06 04:00:03.692  - info: modbus.0 (919438) Disconnected from slave 192.168.88.101
      2026-02-06 04:00:07.029  - info: host.iobroker instance system.adapter.weathersense.0 in version "4.2.1" started with pid 933290
      2026-02-06 04:00:09.479  - info: weathersense.0 (933290) starting. Version 4.2.1 in /opt/iobroker/node_modules/iobroker.weathersense, node: v22.22.0, js-controller: 7.0.7
      2026-02-06 04:00:09.509  - info: weathersense.0 (933290) Start cloud query after 20 Seconds...
      2026-02-06 04:00:13.696  - info: modbus.0 (919438) Connected to slave 192.168.88.101
      2026-02-06 04:00:13.696  - debug: modbus.0 (919438) [DevID_1] Poll start ---------------------
      2026-02-06 04:00:13.696  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 - 1 registers
      2026-02-06 04:00:19.720  - debug: modbus.0 (919438) Socket closed with error
      2026-02-06 04:00:19.720  - debug: modbus.0 (919438) Clearing timeout of the current request.
      2026-02-06 04:00:19.720  - debug: modbus.0 (919438) Cleaning up request fifo.
      2026-02-06 04:00:20.721  - debug: modbus.0 (919438) Closing client on purpose.
      2026-02-06 04:00:20.722  - info: modbus.0 (919438) Disconnected from slave 192.168.88.101
      2026-02-06 04:00:29.030  - info: host.iobroker instance system.adapter.sofarcloud.0 in version "3.3.0" started with pid 933306
      2026-02-06 04:00:30.725  - info: modbus.0 (919438) Connected to slave 192.168.88.101
      2026-02-06 04:00:30.726  - debug: modbus.0 (919438) [DevID_1] Poll start ---------------------
      2026-02-06 04:00:30.726  - debug: modbus.0 (919438) [DevID_1/holdingRegs] Poll address 1157 - 1 registers
      2026-02-06 04:00:31.877  - info: sofarcloud.0 (933306) starting. Version 3.3.0 in /opt/iobroker/node_modules/iobroker.sofarcloud, node: v22.22.0, js-controller: 7.0.7
      2026-02-06 04:00:32.002  - info: sofarcloud.0 (933306) Start cloud query after 112 seconds...
      2026-02-06 04:00:32.413  - info: weathersense.0 (933290) Terminated (NO_ERROR): Everything done. Going to terminate till next schedule
      2026-02-06 04:00:32.952  - info: host.iobroker instance system.adapter.weathersense.0 having pid 933290 terminated with code 0 (NO_ERROR)
      2026-02-06 04:00:36.751  - debug: modbus.0 (919438) Socket closed with error
      2026-02-06 04:00:36.751  - debug: modbus.0 (919438) Clearing timeout of the current request.
      2026-02-06 04:00:36.751  - debug: modbus.0 (919438) Cleaning up request fifo.
      2026-02-06 04:00:37.752  - debug: modbus.0 (919438) Closing client on purpose.
      2026-02-06 04:00:37.753  - info: modbus.0 (919438) Disconnected from slave 192.168.88.101
      

      Wenn es mehrere Möglichkeiten gibt, eine Aufgabe zu erledigen, und eine davon in einer Katastrophe endet oder sonstwie unerwünschte Konsequenzen nach sich zieht, dann wird es jemand genau so machen. Alles, was schiefgehen kann, wird auch schiefgehen.
      (Murphys Gesetz)

      1 Antwort Letzte Antwort
      0
      • spicerS Offline
        spicerS Offline
        spicer
        schrieb am zuletzt editiert von
        #180

        Aber ist schon auffällig, dass es immer um die gleiche Zeit passiert.
        Kann ich iwie den Adapter immer um 4:01 neu starten?

        Wenn es mehrere Möglichkeiten gibt, eine Aufgabe zu erledigen, und eine davon in einer Katastrophe endet oder sonstwie unerwünschte Konsequenzen nach sich zieht, dann wird es jemand genau so machen. Alles, was schiefgehen kann, wird auch schiefgehen.
        (Murphys Gesetz)

        1 Antwort Letzte Antwort
        0
        • spicerS Offline
          spicerS Offline
          spicer
          schrieb am zuletzt editiert von spicer
          #181

          Jetzt hat es um 2026-02-06 16:04:24.546 angefangen. Nach nur ein paar Minuten!

          Mir gefällt das "Socket closed with error" jedesmal nicht.
          Das könnte doch irgend etwas füllen bis zum Crash.
          Sauber ist das auf jeden Fall nicht.

          Wenn es mehrere Möglichkeiten gibt, eine Aufgabe zu erledigen, und eine davon in einer Katastrophe endet oder sonstwie unerwünschte Konsequenzen nach sich zieht, dann wird es jemand genau so machen. Alles, was schiefgehen kann, wird auch schiefgehen.
          (Murphys Gesetz)

          1 Antwort Letzte Antwort
          0
          • R Online
            R Online
            RISSN
            schrieb am zuletzt editiert von
            #182

            https://www.solarvie.at/en-eu/products/sofarsolar-ethernet-dongle-lse-3

            kaufe dir einfach dieses Teil und du hast Ruhe, 55 Euro kostet weniger als die Nerven die du lassen musst. Vor allem hast du es gleich auch noch in der App

            1 Antwort Letzte Antwort
            0
            • spicerS Offline
              spicerS Offline
              spicer
              schrieb am zuletzt editiert von spicer
              #183

              Habe mir eine eigene Lösung geschrieben, welche ich euch nicht vorenthalten möchte.
              Habe in einem LXC, welcher für diverse Skripte zuständig ist, folgendes Python Script drauf gemacht plus eine config.yaml .
              Dies sendet die Sofar-Daten per MQTT an den ioBroker.

              /opt/modbus-mqtt/modbus_tcp_rtu.py

              #!/usr/bin/env python3
              
              import socket
              import struct
              import time
              import yaml
              import logging
              import paho.mqtt.client as mqtt
              import os
              import re
              
              CONFIG_FILE = "/opt/modbus-mqtt/config.yaml"
              LOG_FILE = "/var/log/modbus-mqtt.log"
              
              logging.basicConfig(
                  filename=LOG_FILE,
                  level=logging.INFO,
                  format="%(asctime)s [%(levelname)s] %(message)s"
              )
              
              logging.info("Starting modbus-mqtt with config from disk")
              
              try:
                  with open(CONFIG_FILE, "r") as f:
                      cfg = yaml.safe_load(f)
              except Exception as e:
                  logging.error(f"Failed to load config: {e}")
                  exit(1)
              
              last_mtime = os.path.getmtime(CONFIG_FILE)
              
              MODBUS_HOST = cfg["modbus"]["host"]
              MODBUS_PORT = cfg["modbus"]["port"]
              UNIT_ID = cfg["modbus"]["unit_id"]
              
              MQTT_HOST = cfg["mqtt"]["host"]
              MQTT_PORT = cfg["mqtt"]["port"]
              BASE_TOPIC = cfg["mqtt"]["base_topic"]
              
              POLL_INTERVAL = cfg["poll_interval"]
              REGISTERS = cfg["registers"]
              
              mqttc = mqtt.Client(client_id="modbus_mqtt_bridge", clean_session=True)
              
              mqtt_user = cfg["mqtt"].get("username")
              mqtt_pass = cfg["mqtt"].get("password")
              
              if mqtt_user and mqtt_pass:
                  mqttc.username_pw_set(mqtt_user, mqtt_pass)
              elif mqtt_user or mqtt_pass:
                  logging.warning("MQTT username or password missing. Authentication disabled.")
              else:
                  logging.info("No auth data found. Start without authentication")
              
              mqttc.connect(MQTT_HOST, MQTT_PORT)
              mqttc.loop_start()
              
              # ---------------------------------------------------------
              # Text bereinigen
              # ---------------------------------------------------------
              
              def sanitize(text):
                  # Umlaute ersetzen
                  text = (
                      text.replace("ä", "ae")
                          .replace("ö", "oe")
                          .replace("ü", "ue")
                          .replace("Ä", "Ae")
                          .replace("Ö", "Oe")
                          .replace("Ü", "Ue")
                          .replace("ß", "ss")
                  )
              
                  # Problematische Zeichen ersetzen
                  text = text.replace("-", "_")
                  text = text.replace(":", "_")
              
                  # Erlaubt: A-Z, a-z, 0-9, _
                  text = re.sub(r"[^A-Za-z0-9_]+", "_", text)
              
                  # Mehrere Unterstriche zu einem machen
                  text = re.sub(r"_+", "_", text)
              
                  # Anfang/Ende säubern
                  return text.strip("_")
              
              # ---------------------------------------------------------
              # CRC16 Modbus
              # ---------------------------------------------------------
              
              def crc16(data):
                  crc = 0xFFFF
                  for pos in data:
                      crc ^= pos
                      for _ in range(8):
                          if crc & 1:
                              crc = (crc >> 1) ^ 0xA001
                          else:
                              crc >>= 1
                  return crc.to_bytes(2, byteorder="little")
              
              # ---------------------------------------------------------
              # RTU‑Frame senden über TCP
              # ---------------------------------------------------------
              
              def read_holding_registers_rtu_tcp(unit, address, count):
                  # Build RTU frame: [unit][function][addr_hi][addr_lo][count_hi][count_lo][crc_lo][crc_hi]
                  frame = bytearray()
                  frame.append(unit)
                  frame.append(0x03)  # Function code: Read Holding Registers
                  frame += struct.pack(">HH", address, count)
                  frame += crc16(frame)
              
                  # TCP socket
                  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                  s.settimeout(2)
                  s.connect((MODBUS_HOST, MODBUS_PORT))
                  s.send(frame)
              
                  # Response
                  response = s.recv(256)
                  s.close()
              
                  # Validate minimum length
                  if len(response) < 5:
                      raise Exception("Invalid response length")
              
                  # Validate CRC
                  data = response[:-2]
                  crc_received = response[-2:]
                  crc_calc = crc16(data)
                  if crc_received != crc_calc:
                      raise Exception("CRC mismatch")
              
                  # Byte count
                  byte_count = response[2]
                  if byte_count != count * 2:
                      raise Exception("Unexpected byte count")
              
                  # Extract registers
                  registers = []
                  for i in range(count):
                      hi = response[3 + i*2]
                      lo = response[4 + i*2]
                      registers.append((hi << 8) | lo)
              
                  return registers
              
              # ---------------------------------------------------------
              # Poll‑Loop
              # ---------------------------------------------------------
              
              last_values = {}
              
              while True:
                  # Auto‑Reload wenn config.yaml geändert wurde
                  current_mtime = os.path.getmtime(CONFIG_FILE)
                  if current_mtime != last_mtime:
                      logging.info("Config changed, restarting...")
                      mqttc.loop_stop()
                      exit(0)
              
                  for reg in REGISTERS:
                      addr = reg["addr"]
                      reg_type = reg["type"]
                      factor = reg["factor"]
                      length = 2 if reg_type == "uint32" else 1
              
                      try:
                          regs = read_holding_registers_rtu_tcp(UNIT_ID, addr, length)
              
                          if reg_type == "int16":
                              value = struct.unpack(">h", struct.pack(">H", regs[0]))[0]
                          elif reg_type == "uint16":
                              value = regs[0]
                          elif reg_type == "uint32":
                              value = (regs[0] << 16) | regs[1]
                          else:
                              continue
              
                          value *= factor
              
                          # Nachkommastellen basierend auf config.yaml
                          decimals = reg.get("decimals", None)
                          if decimals is not None:
                              value = round(value, decimals)
              
                          # Beschreibung + Name in Topic einbauen
                          name = reg.get("name", "")
                          desc = reg.get("description", "")
              
                          name_clean = sanitize(name)
                          desc_clean = sanitize(desc)
              
                          # Format: addr:name-description
                          topic_suffix = str(addr)
              
                          if name_clean:
                              topic_suffix += f"_{name_clean}"
              
                          if desc_clean:
                              topic_suffix += f"_{desc_clean}"
              
                          topic = f"{BASE_TOPIC}/register/{topic_suffix}"
              
                          # Nur senden, wenn sich der Wert geändert hat
                          if addr in last_values and last_values[addr] == value:
                              continue  # Wert unverändert → nicht senden
              
                          last_values[addr] = value
                          mqttc.publish(topic, value)
                          #logging.info(f"Published {topic} = {value}")
              
                      except Exception as e:
                          logging.error(f"Error reading register {addr}: {e}")
              
                      time.sleep(0.2)
              
                  time.sleep(POLL_INTERVAL)
              
              

              /opt/modbus-mqtt/config.yaml

              modbus:
                host: "192.168.88.101"
                port: 8899
                unit_id: 1
              
              mqtt:
                host: "192.168.1.251"
                port: 1883
                base_topic: "modbus/inverter"
                username: "mqtt_user"
                password: "mqtt_passwort"
              
              poll_interval: 13
              
              registers:
                - addr: 1199                      # Total Verbrauch in kW
                  name: "ActivePower_Load_Sys"
                  type: "uint16"
                  factor: 0.01
                  decimals: 2
                  description: "Total Verbrauch"
              
                - addr: 1160                      # BKW Netz in kW
                  name: "ActivePower_PCC_Total"
                  type: "int16"
                  factor: 0.01
                  decimals: 2
                  description: "BKW Netz"
              
                - addr: 1476                      # PV Produktion in kW
                  name: "Power_PV_Total"
                  type: "uint16"
                  factor: 0.1
                  decimals: 2
                  description: "PV Produktion"
              
                - addr: 1542                      # Akku Leistung in kW
                  name: "Power_Bat1"
                  type: "int16"
                  factor: 0.01
                  decimals: 2
                  description: "Akku Leistung"
              
                - addr: 1544                      # Akku Ladung in %
                  name: "SOC_Bat1"
                  type: "uint16"
                  factor: 1
                  decimals: 0
                  description: "Akku Ladung"
              
                - addr: 1668                      # PV Produktion heute in kWh
                  name: "PV_Generation_Today"
                  type: "uint32"
                  factor: 0.01
                  decimals: 2
                  description: "PV Produktion heute"
              

              Beim Waveshare musste ich auf "Transparent" (anstelle von "modbus TCP <=> modbus RTU") stellen.
              In der config seht ihr auch, dass LXCs und der Waveshare nicht im gleichen Netzwerk sind. WAN von 192.168.88.0 (MikroTik Router) hängt am Netz 192.168.1.0 (Fritzbox). Da hab ich eine Route definiert, damit man vom einen ins andere Netz zugreifen kann.
              Die IPs, Ports, Usernames und Passwörter müsst ihr natürlich auf eure Gegebenheiten anpassen.

              In der /etc/systemd/system/modbus-mqtt.service

              [Unit]
              Description=Modbus RTU over TCP to MQTT Gateway
              After=network-online.target
              Wants=network-online.target
              
              [Service]
              Type=simple
              User=root
              WorkingDirectory=/opt/modbus-mqtt
              ExecStart=/usr/bin/env python3 /opt/modbus-mqtt/modbus_tcp_rtu.py
              Restart=always
              RestartSec=5
              Environment=PYTHONUNBUFFERED=1
              
              [Install]
              WantedBy=multi-user.target
              

              Wenn alles fertig ist, eingeben:

              sudo systemctl daemon-reload
              sudo systemctl enable modbus-mqtt.service
              sudo systemctl start modbus-mqtt.service
              

              Die Daten werden nun per MQTT an den ioBroker gesendet.
              Der Datenpunkt sieht dann etwa so aus:

              mqtt.0.modbus.inverter.register.{Registeradresse}

              c231d92c-1d69-4e52-a206-48dfd9e63cf5-grafik.png

              Wenn es mehrere Möglichkeiten gibt, eine Aufgabe zu erledigen, und eine davon in einer Katastrophe endet oder sonstwie unerwünschte Konsequenzen nach sich zieht, dann wird es jemand genau so machen. Alles, was schiefgehen kann, wird auch schiefgehen.
              (Murphys Gesetz)

              HomoranH 1 Antwort Letzte Antwort
              0
              • spicerS spicer

                Habe mir eine eigene Lösung geschrieben, welche ich euch nicht vorenthalten möchte.
                Habe in einem LXC, welcher für diverse Skripte zuständig ist, folgendes Python Script drauf gemacht plus eine config.yaml .
                Dies sendet die Sofar-Daten per MQTT an den ioBroker.

                /opt/modbus-mqtt/modbus_tcp_rtu.py

                #!/usr/bin/env python3
                
                import socket
                import struct
                import time
                import yaml
                import logging
                import paho.mqtt.client as mqtt
                import os
                import re
                
                CONFIG_FILE = "/opt/modbus-mqtt/config.yaml"
                LOG_FILE = "/var/log/modbus-mqtt.log"
                
                logging.basicConfig(
                    filename=LOG_FILE,
                    level=logging.INFO,
                    format="%(asctime)s [%(levelname)s] %(message)s"
                )
                
                logging.info("Starting modbus-mqtt with config from disk")
                
                try:
                    with open(CONFIG_FILE, "r") as f:
                        cfg = yaml.safe_load(f)
                except Exception as e:
                    logging.error(f"Failed to load config: {e}")
                    exit(1)
                
                last_mtime = os.path.getmtime(CONFIG_FILE)
                
                MODBUS_HOST = cfg["modbus"]["host"]
                MODBUS_PORT = cfg["modbus"]["port"]
                UNIT_ID = cfg["modbus"]["unit_id"]
                
                MQTT_HOST = cfg["mqtt"]["host"]
                MQTT_PORT = cfg["mqtt"]["port"]
                BASE_TOPIC = cfg["mqtt"]["base_topic"]
                
                POLL_INTERVAL = cfg["poll_interval"]
                REGISTERS = cfg["registers"]
                
                mqttc = mqtt.Client(client_id="modbus_mqtt_bridge", clean_session=True)
                
                mqtt_user = cfg["mqtt"].get("username")
                mqtt_pass = cfg["mqtt"].get("password")
                
                if mqtt_user and mqtt_pass:
                    mqttc.username_pw_set(mqtt_user, mqtt_pass)
                elif mqtt_user or mqtt_pass:
                    logging.warning("MQTT username or password missing. Authentication disabled.")
                else:
                    logging.info("No auth data found. Start without authentication")
                
                mqttc.connect(MQTT_HOST, MQTT_PORT)
                mqttc.loop_start()
                
                # ---------------------------------------------------------
                # Text bereinigen
                # ---------------------------------------------------------
                
                def sanitize(text):
                    # Umlaute ersetzen
                    text = (
                        text.replace("ä", "ae")
                            .replace("ö", "oe")
                            .replace("ü", "ue")
                            .replace("Ä", "Ae")
                            .replace("Ö", "Oe")
                            .replace("Ü", "Ue")
                            .replace("ß", "ss")
                    )
                
                    # Problematische Zeichen ersetzen
                    text = text.replace("-", "_")
                    text = text.replace(":", "_")
                
                    # Erlaubt: A-Z, a-z, 0-9, _
                    text = re.sub(r"[^A-Za-z0-9_]+", "_", text)
                
                    # Mehrere Unterstriche zu einem machen
                    text = re.sub(r"_+", "_", text)
                
                    # Anfang/Ende säubern
                    return text.strip("_")
                
                # ---------------------------------------------------------
                # CRC16 Modbus
                # ---------------------------------------------------------
                
                def crc16(data):
                    crc = 0xFFFF
                    for pos in data:
                        crc ^= pos
                        for _ in range(8):
                            if crc & 1:
                                crc = (crc >> 1) ^ 0xA001
                            else:
                                crc >>= 1
                    return crc.to_bytes(2, byteorder="little")
                
                # ---------------------------------------------------------
                # RTU‑Frame senden über TCP
                # ---------------------------------------------------------
                
                def read_holding_registers_rtu_tcp(unit, address, count):
                    # Build RTU frame: [unit][function][addr_hi][addr_lo][count_hi][count_lo][crc_lo][crc_hi]
                    frame = bytearray()
                    frame.append(unit)
                    frame.append(0x03)  # Function code: Read Holding Registers
                    frame += struct.pack(">HH", address, count)
                    frame += crc16(frame)
                
                    # TCP socket
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.settimeout(2)
                    s.connect((MODBUS_HOST, MODBUS_PORT))
                    s.send(frame)
                
                    # Response
                    response = s.recv(256)
                    s.close()
                
                    # Validate minimum length
                    if len(response) < 5:
                        raise Exception("Invalid response length")
                
                    # Validate CRC
                    data = response[:-2]
                    crc_received = response[-2:]
                    crc_calc = crc16(data)
                    if crc_received != crc_calc:
                        raise Exception("CRC mismatch")
                
                    # Byte count
                    byte_count = response[2]
                    if byte_count != count * 2:
                        raise Exception("Unexpected byte count")
                
                    # Extract registers
                    registers = []
                    for i in range(count):
                        hi = response[3 + i*2]
                        lo = response[4 + i*2]
                        registers.append((hi << 8) | lo)
                
                    return registers
                
                # ---------------------------------------------------------
                # Poll‑Loop
                # ---------------------------------------------------------
                
                last_values = {}
                
                while True:
                    # Auto‑Reload wenn config.yaml geändert wurde
                    current_mtime = os.path.getmtime(CONFIG_FILE)
                    if current_mtime != last_mtime:
                        logging.info("Config changed, restarting...")
                        mqttc.loop_stop()
                        exit(0)
                
                    for reg in REGISTERS:
                        addr = reg["addr"]
                        reg_type = reg["type"]
                        factor = reg["factor"]
                        length = 2 if reg_type == "uint32" else 1
                
                        try:
                            regs = read_holding_registers_rtu_tcp(UNIT_ID, addr, length)
                
                            if reg_type == "int16":
                                value = struct.unpack(">h", struct.pack(">H", regs[0]))[0]
                            elif reg_type == "uint16":
                                value = regs[0]
                            elif reg_type == "uint32":
                                value = (regs[0] << 16) | regs[1]
                            else:
                                continue
                
                            value *= factor
                
                            # Nachkommastellen basierend auf config.yaml
                            decimals = reg.get("decimals", None)
                            if decimals is not None:
                                value = round(value, decimals)
                
                            # Beschreibung + Name in Topic einbauen
                            name = reg.get("name", "")
                            desc = reg.get("description", "")
                
                            name_clean = sanitize(name)
                            desc_clean = sanitize(desc)
                
                            # Format: addr:name-description
                            topic_suffix = str(addr)
                
                            if name_clean:
                                topic_suffix += f"_{name_clean}"
                
                            if desc_clean:
                                topic_suffix += f"_{desc_clean}"
                
                            topic = f"{BASE_TOPIC}/register/{topic_suffix}"
                
                            # Nur senden, wenn sich der Wert geändert hat
                            if addr in last_values and last_values[addr] == value:
                                continue  # Wert unverändert → nicht senden
                
                            last_values[addr] = value
                            mqttc.publish(topic, value)
                            #logging.info(f"Published {topic} = {value}")
                
                        except Exception as e:
                            logging.error(f"Error reading register {addr}: {e}")
                
                        time.sleep(0.2)
                
                    time.sleep(POLL_INTERVAL)
                
                

                /opt/modbus-mqtt/config.yaml

                modbus:
                  host: "192.168.88.101"
                  port: 8899
                  unit_id: 1
                
                mqtt:
                  host: "192.168.1.251"
                  port: 1883
                  base_topic: "modbus/inverter"
                  username: "mqtt_user"
                  password: "mqtt_passwort"
                
                poll_interval: 13
                
                registers:
                  - addr: 1199                      # Total Verbrauch in kW
                    name: "ActivePower_Load_Sys"
                    type: "uint16"
                    factor: 0.01
                    decimals: 2
                    description: "Total Verbrauch"
                
                  - addr: 1160                      # BKW Netz in kW
                    name: "ActivePower_PCC_Total"
                    type: "int16"
                    factor: 0.01
                    decimals: 2
                    description: "BKW Netz"
                
                  - addr: 1476                      # PV Produktion in kW
                    name: "Power_PV_Total"
                    type: "uint16"
                    factor: 0.1
                    decimals: 2
                    description: "PV Produktion"
                
                  - addr: 1542                      # Akku Leistung in kW
                    name: "Power_Bat1"
                    type: "int16"
                    factor: 0.01
                    decimals: 2
                    description: "Akku Leistung"
                
                  - addr: 1544                      # Akku Ladung in %
                    name: "SOC_Bat1"
                    type: "uint16"
                    factor: 1
                    decimals: 0
                    description: "Akku Ladung"
                
                  - addr: 1668                      # PV Produktion heute in kWh
                    name: "PV_Generation_Today"
                    type: "uint32"
                    factor: 0.01
                    decimals: 2
                    description: "PV Produktion heute"
                

                Beim Waveshare musste ich auf "Transparent" (anstelle von "modbus TCP <=> modbus RTU") stellen.
                In der config seht ihr auch, dass LXCs und der Waveshare nicht im gleichen Netzwerk sind. WAN von 192.168.88.0 (MikroTik Router) hängt am Netz 192.168.1.0 (Fritzbox). Da hab ich eine Route definiert, damit man vom einen ins andere Netz zugreifen kann.
                Die IPs, Ports, Usernames und Passwörter müsst ihr natürlich auf eure Gegebenheiten anpassen.

                In der /etc/systemd/system/modbus-mqtt.service

                [Unit]
                Description=Modbus RTU over TCP to MQTT Gateway
                After=network-online.target
                Wants=network-online.target
                
                [Service]
                Type=simple
                User=root
                WorkingDirectory=/opt/modbus-mqtt
                ExecStart=/usr/bin/env python3 /opt/modbus-mqtt/modbus_tcp_rtu.py
                Restart=always
                RestartSec=5
                Environment=PYTHONUNBUFFERED=1
                
                [Install]
                WantedBy=multi-user.target
                

                Wenn alles fertig ist, eingeben:

                sudo systemctl daemon-reload
                sudo systemctl enable modbus-mqtt.service
                sudo systemctl start modbus-mqtt.service
                

                Die Daten werden nun per MQTT an den ioBroker gesendet.
                Der Datenpunkt sieht dann etwa so aus:

                mqtt.0.modbus.inverter.register.{Registeradresse}

                c231d92c-1d69-4e52-a206-48dfd9e63cf5-grafik.png

                HomoranH Nicht stören
                HomoranH Nicht stören
                Homoran
                Global Moderator Administrators
                schrieb am zuletzt editiert von
                #184

                @spicer sagte in Sofar Solar HYD10 KTL Wechselrichter an modbus Adapter:

                Beim Waveshare musste ich auf "Transparent" (anstelle von "modbus TCP <=> modbus RTU") stellen.

                das ist, warum mir ein solcher Konverter zu komplex ist.
                Dann noch bei gleichem Hersteller unterschiedliche Einstellungen braucht....

                @spicer sagte in Sofar Solar HYD10 KTL Wechselrichter an modbus Adapter:

                dass LXCs und der Waveshare nicht im gleichen Netzwerk sind.

                davon war bisher keine Rede

                kein Support per PN! - Fragen im Forum stellen - es gibt fast nichts, was nicht auch für andere interessant ist.

                Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

                der Installationsfixer: curl -fsL https://iobroker.net/fix.sh | bash -

                spicerS 1 Antwort Letzte Antwort
                0
                • HomoranH Homoran

                  @spicer sagte in Sofar Solar HYD10 KTL Wechselrichter an modbus Adapter:

                  Beim Waveshare musste ich auf "Transparent" (anstelle von "modbus TCP <=> modbus RTU") stellen.

                  das ist, warum mir ein solcher Konverter zu komplex ist.
                  Dann noch bei gleichem Hersteller unterschiedliche Einstellungen braucht....

                  @spicer sagte in Sofar Solar HYD10 KTL Wechselrichter an modbus Adapter:

                  dass LXCs und der Waveshare nicht im gleichen Netzwerk sind.

                  davon war bisher keine Rede

                  spicerS Offline
                  spicerS Offline
                  spicer
                  schrieb am zuletzt editiert von
                  #185

                  @Homoran sagte in Sofar Solar HYD10 KTL Wechselrichter an modbus Adapter:

                  davon war bisher keine Rede

                  Das hat ja auch nichts mit den "Hängern" zutun ;)
                  Der Adapter läuft ja ein paar Stunden gut.

                  Wenn es mehrere Möglichkeiten gibt, eine Aufgabe zu erledigen, und eine davon in einer Katastrophe endet oder sonstwie unerwünschte Konsequenzen nach sich zieht, dann wird es jemand genau so machen. Alles, was schiefgehen kann, wird auch schiefgehen.
                  (Murphys Gesetz)

                  HomoranH 1 Antwort Letzte Antwort
                  0
                  • spicerS spicer

                    @Homoran sagte in Sofar Solar HYD10 KTL Wechselrichter an modbus Adapter:

                    davon war bisher keine Rede

                    Das hat ja auch nichts mit den "Hängern" zutun ;)
                    Der Adapter läuft ja ein paar Stunden gut.

                    HomoranH Nicht stören
                    HomoranH Nicht stören
                    Homoran
                    Global Moderator Administrators
                    schrieb am zuletzt editiert von
                    #186

                    @spicer sagte in Sofar Solar HYD10 KTL Wechselrichter an modbus Adapter:

                    Das hat ja auch nichts mit den "Hängern" zutun ;)

                    sicher?

                    der socket wird angemeckert!

                    kein Support per PN! - Fragen im Forum stellen - es gibt fast nichts, was nicht auch für andere interessant ist.

                    Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

                    der Installationsfixer: curl -fsL https://iobroker.net/fix.sh | bash -

                    spicerS 1 Antwort Letzte Antwort
                    0
                    • HomoranH Homoran

                      @spicer sagte in Sofar Solar HYD10 KTL Wechselrichter an modbus Adapter:

                      Das hat ja auch nichts mit den "Hängern" zutun ;)

                      sicher?

                      der socket wird angemeckert!

                      spicerS Offline
                      spicerS Offline
                      spicer
                      schrieb am zuletzt editiert von spicer
                      #187

                      @Homoran sagte in Sofar Solar HYD10 KTL Wechselrichter an modbus Adapter:

                      @spicer sagte in Sofar Solar HYD10 KTL Wechselrichter an modbus Adapter:

                      Das hat ja auch nichts mit den "Hängern" zutun ;)

                      sicher?

                      der socket wird angemeckert!

                      Ja eben. Das hab ich weiter oben ja schon festgehalten.
                      Da konnte mir niemand einen Rat geben.
                      Darum hab ich dann ein eigenes Script erstellt ;)
                      Und das läuft seit der Erstellung stabil.

                      Wenn es mehrere Möglichkeiten gibt, eine Aufgabe zu erledigen, und eine davon in einer Katastrophe endet oder sonstwie unerwünschte Konsequenzen nach sich zieht, dann wird es jemand genau so machen. Alles, was schiefgehen kann, wird auch schiefgehen.
                      (Murphys Gesetz)

                      1 Antwort Letzte Antwort
                      0
                      Antworten
                      • In einem neuen Thema antworten
                      Anmelden zum Antworten
                      • Älteste zuerst
                      • Neuste zuerst
                      • Meiste Stimmen


                      Support us

                      ioBroker
                      Community Adapters
                      Donate

                      559

                      Online

                      32.6k

                      Benutzer

                      82.3k

                      Themen

                      1.3m

                      Beiträge
                      Community
                      Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                      ioBroker Community 2014-2025
                      logo
                      • Anmelden

                      • Du hast noch kein Konto? Registrieren

                      • Anmelden oder registrieren, um zu suchen
                      • Erster Beitrag
                        Letzter Beitrag
                      0
                      • Home
                      • Aktuell
                      • Tags
                      • Ungelesen 0
                      • Kategorien
                      • Unreplied
                      • Beliebt
                      • GitHub
                      • Docu
                      • Hilfe