Ankündigung

Einklappen
Keine Ankündigung bisher.

Neues Plugin: SMAModbus (zu Auslesen eines SMA-Wechselrichters über speedwire/modbus)

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

    Neues Plugin: SMAModbus (zu Auslesen eines SMA-Wechselrichters über speedwire/modbus)

    Hallo,
    leider haben bei mir die Plugins zum Auslesen meines SMA-Wechselrichters über bluetooth nicht zuverlässig funktioniert.
    Deshalb habe ich mich als blutiger Anfänger in Sachen Python an einem neuen Plugin versucht.

    Bitte beachtet auch die Hinweise des Herstellers und prüft vorher auf der Homepage https://www.sma.de/ ob Euer Wechselrichter die Modbusregister unterstützt.

    Bei Fragen, Anregungen und Verbesserungen bitte melden.

    Nutzung auf eigene Gefahr :-)

    Modul installieren:

    Code:
     pip3 install pymodbus

    Code:
    #!/usr/bin/env python3
    #
    #########################################################################
    #  Copyright 2017 kla.b                               kla.b(a)gmx.de
    #  Version 1.3.0
    #########################################################################
    #  Free for non-commercial use
    #  
    #  Plugin for the software SmartHome.py (NG), which allows to read
    #  devices such as the SMA Inverter
    #
    #  SmartHomeNG is free software: you can redistribute it and/or modify
    #  it under the terms of the GNU General Public License as published by
    #  the Free Software Foundation, either version 3 of the License, or
    #  (at your option) any later version.
    #
    #  SmartHome.py is distributed in the hope that it will be useful,
    #  but WITHOUT ANY WARRANTY; without even the implied warranty of
    #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    #  GNU General Public License for more details.
    #
    #  You should have received a copy of the GNU General Public License
    #  along with SmartHome.py (NG). If not, see <http://www.gnu.org/licenses/>.
    #
    #########################################################################
    import logging
    import time
    from lib.model.smartplugin import SmartPlugin
    # Modbus
    from pymodbus.constants import Endian
    from pymodbus.payload import BinaryPayloadDecoder
    from pymodbus.client.sync import ModbusTcpClient as ModbusClient
    
    class SMAModbus(SmartPlugin):
         ALLOW_MULTIINSTANCE = True
         PLUGIN_VERSION = '1.3.0'
    
         def __init__(self, sh, port = 502, host = '', cycle = 300):
              self.logger = logging.getLogger(__name__)
              self.logger.debug("starting monitoring service")
              self._sh = sh
              self._port = int(port)
              self._cycle = int(cycle)
              self._host = host
              self._items = {}
    
         def run(self):
              self.alive = True
              self._sh.scheduler.add('SMAModbus', self.update_status, cycle=self._cycle)
    
         def stop(self):
              self.alive = False
    
         def parse_item(self, item):
              if self.has_iattr(item.conf, 'register'):
                   modbus_register = self.get_iattr_value(item.conf, 'register')
                   self._items[modbus_register]=item
                   self.logger.debug("item: {0} added with modbus_register: {1}".format(item,modbus_register))
                   return self.update_item
              else:
                   return None
    
         def parse_logic(self, logic):
              pass
    
    
         def update_item(self, item, caller=None, source=None, dest=None):
                              if caller != 'SMAModbus':
                                   self.logger.info("update item: {0}".format(item.id()))
    
         def update_status(self):
              for read_parameter in self._items:
                   client = ModbusClient(self._host, self._port)
                   client.connect()
                   result = client.read_holding_registers((int(read_parameter)), 2, unit=3)
                   decoder = BinaryPayloadDecoder.fromRegisters(result.registers, byteorder=Endian.Big)
                   decoded = {
                       'value': decoder.decode_32bit_uint(),
                   }
                   valueend = decoded.get("value")
                   self.logger.debug("value is {0} key is {1} self._item is {2}".format(valueend, read_parameter, self._items[read_parameter]))
                   if read_parameter in self._items:
    #                    self. logger.debug("update item {0} with {1}".format(self._items[read_parameter], value))
                        item = self._items[read_parameter]
                        item (valueend, 'register')
                   client.close()
              return


    plugin.yaml

    Code:
    SMAModbus1:
        class_name: SMAModbus
        class_path: plugins.smamb
        instance: sb3000tl
        host: 192.168.1.16
    #    port: 502      #optional
    #    cycle: 150     #optional
    
    SMAModbus2:
        class_name: SMAModbus
        class_path: plugins.smamb
        instance: sb5000tl
        host: 192.168.1.17
    #    port: 502      #optional
    #    cycle: 300     #optional
    item.conf
    Code:
    [SB3000TL]
         [[leistung]]
            type = num
            visu_acl = ro
            register@sb3000tl = 30775
    [SB5000TL]
         [[seriennummer]]
            type = num
            visu_acl = ro
            register@sb5000tl = 30057
    Gruß
    Klaus
    Zuletzt geändert von klab; 12.04.2021, 10:13.

    #2
    Wollte gerade mal dein Plugin testen...
    Code:
    2017-11-30  15:45:13 ERROR    Main         Plugin SMAModbus exception: No module named 'pymodbus'
    Traceback (most recent call last):
      File "/usr/local/smarthome/lib/plugin.py", line 90, in __init__
        plugin_thread = PluginWrapper(smarthome, plugin, classname, classpath, args, instance)
      File "/usr/local/smarthome/lib/plugin.py", line 127, in __init__
        exec("import {0}".format(classpath))
      File "<string>", line 1, in <module>
      File "/usr/local/smarthome/plugins/smamb/__init__.py", line 30, in <module>
        from pymodbus.constants import Endian
    ImportError: No module named 'pymodbus'
    Muss da noch ein Paket installiert werden?
    cu Yfkt5A
    DALI(ABB DG/S1.1), KODI RaspberryPi4, QNAP TS-509, Zehnder ComfoAir 200 L Luxe
    DELL T20 mit Proxmox - VM´s: SmartHomeNG/smartVISU, TVHeadend, jellyfin

    Kommentar


      #3
      Hallo Yfkt5A,
      genau, installiere:

      Code:
       
       pip3 install pymodbus==1.3.1

      Gruß
      Zuletzt geändert von klab; 21.01.2018, 20:27.

      Kommentar


        #4
        Danke für die schnelle Rückmeldung... hab gerade gesehen das das auch oben schon dabei gestanden wäre... wer lesen kann...

        Das Plugin scheint sich nun zu verbinden, aber findet keine "registers"
        Code:
        2017-12-04  10:17:10 ERROR    SMAModbus    Method SMAModbus exception: 'ModbusIOException' object has no attribute 'registers'
        Traceback (most recent call last):
          File "/usr/local/smarthome/lib/scheduler.py", line 404, in _task
            obj()
          File "/usr/local/smarthome/plugins/smamb/__init__.py", line 77, in update_status
            decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Big)
        AttributeError: 'ModbusIOException' object has no attribute 'registers'
        Obwohl der Wechselrichtung in der SunSpec gelistet ist.

        Gibts noch was was ich falsch gemacht haben könnte?

        PS: reicht es eigentlich den TCP-Server zu aktivieren oder muss auch der UDP aktiviert werden?
        cu Yfkt5A
        DALI(ABB DG/S1.1), KODI RaspberryPi4, QNAP TS-509, Zehnder ComfoAir 200 L Luxe
        DELL T20 mit Proxmox - VM´s: SmartHomeNG/smartVISU, TVHeadend, jellyfin

        Kommentar


          #5
          ich habe dasselbe Problem,
          ich hatte das verwandte solaredge Plugin in Gebrauch, seit der Umstellung auf 1.3 funktioniert das bei mir nicht mehr.
          Code:
          solaredge
          2017-12-05  12:26:16 ERROR    Solaredge    Solaredge: something went wrong in the refresh function: 'ModbusIOException' object has no attribute 'registers'
          2017-12-05  12:26:37 INFO     CP Server Thread-11 192.168.178.46 - - [05/Dec/2017:12:26:37] "GET /main.html HTTP/1.1" 200 4750 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"
          2017-12-05  12:26:46 INFO     Solaredge    Solaredge: connecting to 192.168.178.14:502
          2017-12-05  12:26:46 DEBUG    Solaredge    Solaredge: Read parameter 'I_AC_Power' with register '40083': Value is 'None'
          2017-12-05  12:26:46 ERROR    Solaredge    Solaredge: something went wrong in the refresh function: 'ModbusIOException' object has no attribute 'registers'
          bin dann auf SMAModbus gewechselt

          Code:
          SMAmodbus
          2017-12-05  12:29:23 ERROR    SMAModbus    Method SMAModbus exception: 'ModbusIOException' object has no attribute 'registers'
          Traceback (most recent call last):
            File "/usr/local/smarthome/lib/scheduler.py", line 404, in _task
              obj()
            File "/usr/local/smarthome/plugins/smamb/__init__.py", line 77, in update_status
              decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Big)
          AttributeError: 'ModbusIOException' object has no attribute 'registers'
          evtl findest du ja im solaredge Thread ne Lösung, falls du auch auf 1.3 bist und klab nicht wäre das ja ein Ansatz.
          zur Anlage: ich habe TCP und UPD eingeschaltet.

          Kommentar


            #6
            Hallo,
            bei mir läuft auch die aktuelle Version SmartHomeNG 1.3.v1.3_Hotfix_2.
            Komischerweise läuft es auf zwei Rechner aber auf einem dritten konnte ich den Fehler nachstellen. :-(

            Ich bin auf der Suche.

            Gruß
            Klaus

            Kommentar


              #7
              Hallo,
              es liegt wohl an der pymodbus Version (1.3.2).

              Als kurzfristiger workaround funktioniert bei mir folgendes:

              Code:
              pip3 uninstall pymodbus
              pip3 install pymodbus==1.3.1
              Gruß
              Klaus

              Zuletzt geändert von klab; 08.12.2017, 17:51.

              Kommentar


                #8
                Gerade mal bei mir getestet:
                Code:
                2017-12-11  15:38:48 INFO     SMAModbus    update item: sb3000tl.seriennummer
                Scheint zu funktionieren... Danke


                Edit: die Anbindung für 2 Wechselrichter ist (noch) nicht vorgesehen, oder?
                Wir haben hier nämlich Zwei... wie krieg ich das gebacken?
                Zuletzt geändert von Yfkt5A; 11.12.2017, 15:55.
                cu Yfkt5A
                DALI(ABB DG/S1.1), KODI RaspberryPi4, QNAP TS-509, Zehnder ComfoAir 200 L Luxe
                DELL T20 mit Proxmox - VM´s: SmartHomeNG/smartVISU, TVHeadend, jellyfin

                Kommentar


                  #9
                  Hallo Yfkt5A,
                  das Plugin ist auf Multiinstance umgestellt. (siehe Beitrag #1)

                  Nächste Baustelle: Ändern der Wirkleistungsbegrenzung (Register 40016).

                  Bei Interesse bitte melden.

                  Gruß
                  Klaus
                  Zuletzt geändert von klab; 30.12.2017, 00:52.

                  Kommentar


                    #10
                    Danke funktioniert...

                    Hab bei mir noch gleich ein paar evals bei den Items hinzugefügt um die Werte umzurechnen:
                    Code:
                    stpXXX:
                    
                    
                        status:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30201
                    
                        isolationswiderstand:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30225
                            eval: (value/1000) #Umrechnung in kOhm
                    
                        netzrelais_status:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30217
                    
                        ac_arbeit_total:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30529
                            eval: (value/1000000) #Umrechnung in MWh
                    
                        ac_arbeit_tag:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30535
                            eval: (value/1000) #Umrechnung in kWh
                    
                        zeit_betrieb:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30541
                            eval: (value/3600) #Umrechnung in h
                    
                        zeit_einspeise:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30543
                            eval: (value/3600) #Umrechnung in h
                    
                        netzzuschaltungen:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30599
                    
                        dc_strom:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30769
                    
                        dc_spannung:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30771
                            eval: (value/100) #Umrechnung in V
                    
                        dc_leistung:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30773
                    
                        ac_leistung:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30775
                    
                        ac_spannung:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30783
                            eval: (value/100) #Umrechnung in V
                    
                        ac_strom:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30797
                    
                        netzfrequenz:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30803
                            eval: (value/100) #Umrechnung in Hz
                    
                        ethernet_speed:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30925
                    
                        ethernet_status:
                            type: num
                            visu_acl: ro
                            register@stpXXX: 30929
                    Wie kann ich die Werte auf z.B. 2 Nachkommastellen runden?

                    @klab: mich würde interessieren wie du deine Anlage visualisiert hast... mir fehlt da noch die Idee, zeige im Moment einfach nur die Werte an
                    cu Yfkt5A
                    DALI(ABB DG/S1.1), KODI RaspberryPi4, QNAP TS-509, Zehnder ComfoAir 200 L Luxe
                    DELL T20 mit Proxmox - VM´s: SmartHomeNG/smartVISU, TVHeadend, jellyfin

                    Kommentar


                      #11
                      Hallo Yfkt5A,
                      zum runden / wertanpassung / anzeige als text nutze ich eval

                      z.B.

                      item.conf
                      Code:
                      [sb3000tl]
                           [[zeit_einspeise]]
                              type = num
                              visu_acl = ro
                              register@sb3000tl = 30543
                              [[[wertanpassung]]]
                                 type = num
                                 visu_acl = ro
                                 eval = round ((sh.sb3000tl.zeit_einspeise()/86400), 0)
                                 eval_trigger = sb3000tl.zeit_einspeise
                      oder
                      Code:
                      [sb3000tl]
                           [[relais]]
                              type = num
                              visu_acl = ro
                              register@sb3000tl = 30217
                              [[[relais_text]]]
                                  type = str
                                  visu_acl = ro
                                  eval = 'geschlossen' if (sh.sb3000tl.relais() == 51) else 'offen'
                                  eval_trigger = sb3000tl.relais
                      Die Vorlage für smartVISU habe ich hier aus dem Forum.


                      FireShot Capture 5 - zuHause [smartVISU] - http___192.168.1.16_smartvisu_index.php_page=ehz.png

                      Gruß
                      Angehängte Dateien

                      Kommentar


                        #12
                        Habe das Problem das einige Items bei abends abgeschaltetem WR auf Max Wert des Wertebereichs stehen? Hat das sonst noch jemand? Einfache Lösung dürfte sein die Werte über einen eval zu Nullen wenn der Wert außerhalb was erwartbarem liegt. Aber schon komisch wenn das nur bei mir auftritt.

                        Kommentar


                          #13
                          Hallo android,
                          mein Wechselrichter hat das gleiche Verhalten.

                          Habe das auch über eval gelöst.
                          Code:
                          ​
                          ​​​[sb3000tl]
                              [[dc_ampere]]
                                  type = num
                                  visu_acl = ro
                                  register@sb3000tl = 30769
                                  [[[wertanpassung]]]
                                      type = num
                                      visu_acl = ro
                                      eval = 0 if (sh.sb3000tl.dc_ampere() == 2147483648) else value/1000
                                      eval_trigger = sb3000tl.dc_ampere
                          Gruß
                          klab
                          Zuletzt geändert von klab; 15.03.2018, 20:40.

                          Kommentar


                            #14
                            Hallo,

                            vielen Dank für das Plugin. Bei mir läuft es zur Zeit mit einem SMA STP5000TL-20. Ich habe gerade auf NG umgestellt und die Abfrage über Bluetooth nicht mehr hinbekommen. Ich habe mir die Registernummern zusammen gegoogelt und erhalte auch die passende Werte.

                            Bei mir ist es auch so, dass ich abends die Max Werte bei der Leistung, Spannung und dem Strom der einzelnen Strings erhalte. Könnte man das Plugin nicht veranlassen nach Sonnenuntergang keine Werte mehr abzufragen. Ähnlich war es auch beim SMA Plugin mit der Bluetooth Abfrage. Ich habe leider keine Ahnung wie das dort programmiert wurde, außer dass bei den Items ein PLUGIN_ACTIVE in Abhängigkeit vom Sonnenstand gesetzt wurde. Eventuell ist dann ja auch schon zu spät, weil die Max-Werte schon gelesen worden sind.

                            Bye
                            Eiko

                            Kommentar


                              #15
                              Hallo,

                              vielen Dank für dieses Plugin. Weiß jemand ob es auch mit einem STP 6000TL-20 549 funktioniert.
                              Ich habe diese PV-Anlage erst vor 2 Tagen installieren lassen und suche schon mal nach einer geeigneten Schnittstelle für SH.
                              Gruß
                              ElektroRudi

                              ............kann,.muß aber net....

                              Kommentar

                              Lädt...
                              X