Ankündigung

Einklappen
Keine Ankündigung bisher.

Einbindung von Modbus TCP

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • aldaris
    antwortet
    Hi,

    gerade ein weiteres Problem festgestellt. Ich habe meine WP (also den Controller) neugestartet, der hat damit seine Modbus Seite neu gestartet. smartHomeNG, bzw. das Plugin, hat das nicht überlebt:
    2026-02-19 00:02:40 ERROR lib.scheduler.tasks Method plugins.modbus_tcp_wpl.poll_device_192.168.178.17 exception: [Errno 32] Broken pipe
    > Traceback (most recent call last):
    > File "/usr/local/smarthome/lib/scheduler.py", line 806, in _task
    > obj()
    > File "/usr/local/smarthome/plugins/modbus_tcp/__init__.py", line 270, in poll_device
    > raw_value = self.__read_Registers(regPara)
    > File "/usr/local/smarthome/plugins/modbus_tcp/__init__.py", line 534, in __read_Registers
    > result = self._Mclient.read_input_registers(address, count=registerCount, slave=slaveUnit)
    > File "/usr/local/lib/python3.10/site-packages/pymodbus/client/mixin.py", line 136, in read_input_registers
    > return self.execute(no_response_expected, pdu_reg.ReadInputRegistersRequest(address=address, count=count, dev_id=slave))
    > File "/usr/local/lib/python3.10/site-packages/pymodbus/client/base.py", line 203, in execute
    > return self.transaction.sync_execute(no_response_expected , request)
    > File "/usr/local/lib/python3.10/site-packages/pymodbus/transaction/transaction.py", line 132, in sync_execute
    > self.pdu_send(request)
    > File "/usr/local/lib/python3.10/site-packages/pymodbus/transaction/transaction.py", line 199, in pdu_send
    > self.low_level_send(self.trace_packet(True, packet), addr=addr)
    > File "/usr/local/lib/python3.10/site-packages/pymodbus/client/tcp.py", line 221, in send
    > return self.socket.send(request)
    > BrokenPipeError: [Errno 32] Broken pipe​

    Ich musste shng neustarten. Wäre hier vielleicht etwas wie ein retry mit steigender Verzögerung sinnvoll?

    Einen Kommentar schreiben:


  • Morg
    antwortet
    Wenn die beiden Werte nach 30 Sekunden garantiert da sind, könnte das gehen. Ich finde es mit dem zusätzlichen Scheduler im Item aber etwas komplex (zumal der auch zweimal getriggert wird).

    Du müsstest die Werte zwischenspeichern und prüfen, ob beide Werte aktualisiert sind; dann beide Werte gleichzeitig in die shng-Items schreiben. Das geht mit Hilfsitems und etwas komplizierteren evals, oder (einfacher) mit einer Logik, denke ich.

    Ich habe ähnliche "Probleme", weil meine Leistungsmessungen vom PV-Leistungsmesser über die PV-Anlage im Sekundentakt kommen, die Leistungswerte von den "Stromzählern" ( ) aber nur alle ca. 30 Sekunden, und das nicht synchron. Für den Moment lebe ich damit.
    Zuletzt geändert von Morg; 17.12.2025, 10:52.

    Einen Kommentar schreiben:


  • aldaris
    antwortet
    Ich habe es probiert. Die Reihenfolge in den Items ist leider zufällig. Also bei gleicher Itemstruktur an zwei Tage verschiedene Reihenfolge.

    Das mit der Logik würde natürlich gehen, kam aber gerade auf die Idee, ob nicht eine "einfache" Verzögerung gehen würde:

    Code:
     Heizung:
    name: Heizung
    eval_trigger: Haus.Zentral.Zentral.PhotovoltaikEnergy.Raw.HeizungD|Haus.Zentral.Zentral.PhotovoltaikEnergy.Raw.HeizungTotalK
    eval: sh.scheduler.add(
                  'update',
                  30,
                  sh.Haus.Zentral.Zentral.PhotovoltaikEnergy.Raw.Heizung._update,
                  value=sh...HeizungD() + sh...HeizungTotalK()
              )​
    type: num
    database: init
    database_maxage: 31​​
    Geht das so?

    Einen Kommentar schreiben:


  • bmx
    antwortet
    Ich vermute in Deiner Heizung wird es eine Reihenfolge der Aktualisierung geben die sich nicht ändert.
    Je nachdem wie die Abfragezeit ist, kannst Du Dich vermutlich auch nicht darauf verlassen das D auf 0 gesetzt wurde obwohl man zur Nacht hin vermuten sollte das sich dann nichts mit PV tut. Es sei denn es ist Sommer und Du wohnst in Norwegen oder so...

    Die Abfrage der Modbus Adressen erfolgt vermutlich in der Reihenfolge wie die Item aus den Yaml Dateien gelesen werden aber das ich nicht als sicher anzunehmen.

    Ich würde also den Wert der Heizung nicht durch ein eval ermitteln sonder mir eine Logik bauen die durch beide Items getriggert wird.
    Dann kannst Du beim Aufruf prüfen ob die Items gerade eben also z.B. innerhalb der letzten 2-3 Sekunden beide aktualisiert wurden oder nur eines davon. Im letzteren Fall kannst Du die Logik schlicht verlassen, im ersteren Fall kannst Du die Summe beider Itemwerte bilden wie vorgesehen und an Heizung zuweisen.

    Einen Kommentar schreiben:


  • aldaris
    antwortet
    Einmal muss ich noch nachfragen, hier gibt es vielleicht einen Trick, den ich noch nicht kenne:

    Ich habe zwei Modbus Adressen. Eine liefert den Tagesverbrauch ab 0:00 Uhr und der andere der Gesamtverbrauch seit erstem Start bis 0:00 Uhr. Warum auch immer.

    Ich will jedenfall die Gesamtenergie, also addiere ich beide Werte:
    Code:
          HeizungD:
                name: HeizungD
                modBusObjectType@wpl: InputRegister
                modBusAddress@wpl: 3510
                modBusDataType@wpl: int16
                modBusFactor@wpl: 1
                modBusUnit@wpl: 3
                type: num
                database: init
                database_maxage: 31
              HeizungTotalK:
                name: HeizungTotalK
                modBusObjectType@wpl: InputRegister
                modBusAddress@wpl: 3511
                modBusDataType@wpl: int16
                modBusFactor@wpl: 1
                modBusUnit@wpl: 3
                type: num
                database: init
                database_maxage: 31
              Heizung:
                name: Heizung
                eval_trigger: Haus.Zentral.Zentral.PhotovoltaikEnergy.Raw.HeizungD|Haus.Zentral.Zentral.PhotovoltaikEnergy.Raw.HeizungTotalK
                eval: (sh...HeizungD() + sh...HeizungTotalK())
                type: num
                database: init
                database_maxage: 31​
    Das Problem ist hier, dass im um 00:00 ein "flackern" kriege, je nachdem welcher Wert zuerst aktualisiert wird.
    Also
    D: 20, Total 100 => 120
    D: 0, Total 100 => 100
    D: 0, Total 120 => 120
    Oder
    D: 20, Total 100 => 120
    D: 20, Total 120 => 140
    D: 0, Total 120 => 120​

    Beides ist schlecht, weil ich über Min / Max auf dem Item auswertungen machen will.

    Ich hatte schon mal den Plan auf Monotonie zu gehen, dann muss ich aber sicherstellen, 3510 zuerst gesetzt wird.
    eval: (sh...HeizungD() + sh...HeizungTotalK()) if (sh...HeizungD() + sh...HeizungTotalK()) >= sh..() else None
    => Ist die Reihenfolge irgendwie deterministisch oder zufällig?
    => Kann man die beeinflussen?
    => Oder habe ich einfach ein Brett vor dem Kopf und es geht leicher?

    Einen Kommentar schreiben:


  • aldaris
    antwortet
    Naja, der Trick war ja jetzt zu wissen, dass es diesen Offset gibt und der "Ok" ist. Die Werte anzupassen nicht jetzt nicht der Aufwand. Also nicht viel mehr als es zentral einzustellen => Ich brauche es nicht

    Einen Kommentar schreiben:


  • bmx
    antwortet
    Theoretisch könnte man ins Plugin einbauen das er zu jeder Adresse erst noch einen Offset addiert oder subtrahiert damit man nicht alle Adressen ändern muss wenn man sie irgendwoher genommen hat. Ich brauche das Feature aber nicht und weiß nicht ob es allgemeine Verwendung dafür gibt?

    Einen Kommentar schreiben:


  • bmx
    antwortet
    Ja, weil Modbus Adressen eigentlich 0 basiert sind aber das unterschiedliche Geräte und Clients anders aufbereiten. Der Unterschied ist nur ein Offset von 1 bei allen Adressen mit absoluten Registerangaben

    Einen Kommentar schreiben:


  • aldaris
    antwortet
    Hi,

    ich versuche gerade meine neue Wärmepumpe auszulesen. Irgendwie habe ich einen Register Offset. Vermutlich mache ich was falsch, aber ich sehe es einfach nicht.

    Ziel: Die Leistungsaufnahme der berechnen. Das sieht in der UI so aus:
    grafik.png​​

    Laut Stiebel sind das die Register 3511, 3512 und 3513
    grafik.png

    Wenn ich die über einen ModbusClient am Handy auslese erreiche ich:
    3511: 20
    3512: 8
    3513: 0

    Ich lese Input Register.

    Bis auf die fehlenden Nachkommastellen stimmt das. Jetzt das ganze schnell in smarthomeng:

    Code:
    StiebelA:
                name: StiebelA
                modBusObjectType@wpl: InputRegister
                modBusAddress@wpl: 3511
                modBusDataType@wpl: int16
                modBusUnit@wpl: 3
                type: num
                database: init
                database_maxage: 31
            StiebelB:
                name: StiebelB
                modBusObjectType@wpl: InputRegister
                modBusAddress@wpl: 3512
                modBusDataType@wpl: int16
                modBusUnit@wpl: 3
                type: num
                database: init
                database_maxage: 31        
            StiebelC:
                name: StiebelC
                modBusObjectType@wpl: InputRegister
                modBusAddress@wpl: 3513
                modBusDataType@wpl: int16
                modBusUnit@wpl: 3
                type: num
                database: init
                database_maxage: 31
            StiebelD:
                name: StiebelD
                modBusObjectType@wpl: InputRegister
                modBusAddress@wpl: 3510
                modBusDataType@wpl: int16
                modBusUnit@wpl: 3
                type: num
                database: init
                database_maxage: 31​
    Gibt e sirgendeine sinnvolle Erklärung, warum die Register scheinbar verschoben sind?
    grafik.png
    Angehängte Dateien

    Einen Kommentar schreiben:


  • aldaris
    antwortet
    Danke. Die Lösung war: Ich hatte die falsche unitId. Mit der richtigen geht's dann wie erwartet

    Einen Kommentar schreiben:


  • whe
    antwortet
    Hol Dir mal qModMaster: https://sourceforge.net/projects/qmodmaster/
    ist eine einfache .exe für Windows, die nicht installiert werden muss (nur downloaden und anklicken)
    damit kannst die Register die Du brauchst testen bevor Du sie als Items in SHNG einbaust.

    Einen Kommentar schreiben:


  • whe
    antwortet
    das sieht doch nach 0xFFFF FFFF aus, dass diese Werte gar nicht vorhanden sind "NaN"
    versuche es doch mal mit Registern, deren Inhalt Du kennst.

    Einen Kommentar schreiben:


  • aldaris
    antwortet
    Hi,
    so ähnlich habe ich das auch:
    Items:
    Code:
    Test:
      A:
        type: num
        name: TestIR
        enforce_updates: True
        modBusAddress: 31393
        modBusDataType:  uint32
      B:
        type: num
        name: TestHR
        enforce_updates: True
        modBusAddress: 31395
        modBusDataType: uint32​
    Doku SMA z.B.
    grafik.png

    Beide Items haben aber dann einen seltsamen (gleichen) Wert
    grafik.png

    Einen Kommentar schreiben:


  • whe
    antwortet
    was heißt denn "komisch" ?
    es gelten zwar default Werte, aber oft muss Du natürlich bei den items mehr vorgeben:
    z.B den "modbusDataType" und manchmal auch mit dem "modbusFactor" den Wert anpassen.
    hast Du mal in die Doku geschaut, was man da alles spezifizieren kann.
    und hast Du eine SMA Doku zu den Modbus Registern ?

    Beispiel:
    Code:
                grid:
                    name: Netz Wirkleistung
                    type: num
                    modBusFactor@fenecon: -1
                    modBusAddress@fenecon: 315
                    modBusDataType@fenecon: 'float32'​
    Zuletzt geändert von whe; 04.11.2024, 21:11.

    Einen Kommentar schreiben:


  • aldaris
    antwortet
    Hallo,

    Ich versuche mich gerade an diesem Plugin versucht, um mit meinem Wechselrichter zu sprechen. Plugin läuft, Status connected.

    Die Werte die ich kriege sind aber komisch, ich vermute, das RegisterFormat ist falsch. Hat schonmal jemand eine SMA WR zum laufen bekommen und ein Demo Item?

    Einen Kommentar schreiben:

Lädt...
X