Modbus Register für Fronius Symo 20.0-3-M

Moin aus dem sonnigen Norden,

ich würde gerne beim Symo 20.0-3-M die Spannung / Stromstärke / Leistung vom MPPT1 und MPPT2 via Modbus TCP auswerten. Leider sind die Werte nicht korrekt. Für mich ist das absolutes Neuland. Vielleicht hat jemand einen Tipp, was ich ändern sollte.

modbus:
  - name: "Symo Gen24 10.0 Plus"
    type: tcp
    host: "10.0.9.51"  # IP-Adresse des Symo Gen24 10.0 Plus Wechselrichters
    port: 502
    delay: 5
    timeout: 5
    sensors:
      - name: "Symo Gen24 10.0 Plus Einspeiselimit"
        slave: 1
        address: 40290  # Register für die Einspeiselimitierung
        input_type: holding
        unit_of_measurement: "%"
        data_type: uint16  # oder float, je nach Gerät und Modbus-Dokumentation
        scan_interval: 10
  - name: "Fronius Symo 20.0-3-M"
    type: tcp
    host: "10.0.9.52"  # IP-Adresse des Fronius Wechselrichters
    port: 502
    delay: 5
    timeout: 5
    sensors:
      - name: "Symo20 DC Strom MPPT1"
        slave: 1
        address: 40263  # Adresse für DC Strom (2_DCA) bei float
        input_type: holding
        unit_of_measurement: "A"
        data_type: int16
        scan_interval: 10

      - name: "Symo20 DC Spannung MPPT1"
        slave: 1
        address: 40264  # Adresse für DC Spannung (2_DCV)
        input_type: holding
        unit_of_measurement: "V"
        data_type: int16
        scan_interval: 10

      - name: "Symo20 DC Leistung MPPT1"
        slave: 1
        address: 40265  # Adresse für DC Leistung (2_DCW)
        input_type: holding
        unit_of_measurement: "W"
        data_type: int16
        scan_interval: 10

      - name: "Symo20 DC Strom MPPT2"
        slave: 1
        address: 40266  # Adresse für DC Strom des zweiten Eingangs, falls vorhanden
        input_type: holding
        unit_of_measurement: "A"
        data_type: int16
        scan_interval: 10

      - name: "Symo20 DC Spannung MPPT2"
        slave: 1
        address: 40267  # Adresse für DC Spannung des zweiten Eingangs, falls vorhanden
        input_type: holding
        unit_of_measurement: "V"
        data_type: int16
        scan_interval: 10

      - name: "Symo20 DC Leistung MPPT2"
        slave: 1
        address: 40268  # Adresse für DC Leistung des zweiten Eingangs, falls vorhanden
        input_type: holding
        unit_of_measurement: "W"
        data_type: int16
        scan_interval: 10
        
      - name: "Symo 20 Einspeiselimit"
        slave: 1
        address: 40290  # Register für die Einspeiselimitierung (anpassen, falls erforderlich)
        input_type: holding
        unit_of_measurement: "%"
        data_type: uint16  # Ändere dies ggf. in float, wenn erforderlich
        scan_interval: 10

Sind die Datentypen korrekt? Prüfe die mal mit der Docu

Ich habe sie auf uint16 geändert, allerdings sind scheinbar die Register falsch. Wie gesagt, für mich ist das absolutes Neuland. Ich habe bislang das hier gefunden:
MPPT

Verstehe ich das richtig, dass die Startadresse 40253 ist, dann kommen noch 40 dazu für den 2_DCA? Also müsste das Register dann 40293 sein für die Stromstärke? Das habe ich versucht, allerdings nur 0-Werte erhalten

Es wundert mich etwas das du so ganz ohne die üblichen “Scaling Faktoren” auskommst.

Was hast du am Wechselrichter bei Modbus eingestellt ? int+ sf?`

Falls ja wäre der Strom vom MPPT1 wohl eher auf Adresse
40272 und dessen Scaling Faktor auf 40255

Sprich den für dich realistischen Wert bekommst du dann mittels Template in der form
40262 * 10 ** 40255 (auf deutsch) Grundwert * 10 hoch Skalierungsfaktor.

oder als beispiel
der Wert an Adress 40262 ist 62480, der an Addresse 40255 ist -4
==> 62480*10^-4 = 5.2186 A

Ohaaaa, das ist ja nicht mal so einfach.

Woher nimmst du die Adresse 40272 und den dazu gehörigen Scaling Faktor 40255?

Den Rest glaube ich soweit verstanden zu haben.

Und noch eine Frage dazu. Würde es hilfreich sein, auf “float” umzustellen? Wäre das einfacher?

Die Registernummern sind halt andere, das mit den scaling_factoren ist immer so bei Fronius, darum wirst du nicht umhin kommen.
Hab den Offset jetzt grad nicht im Kopf.

Wobei du schreibst oben Symo 20 und hast ein Dokument bzw. YAML vom Gen24 10 … .das könnte beim 20er natürlich anders sein hab ich jetzt nicht geschaut, glaub es aber kaum denn auch Fronius folgt der sunssf Spezifikation.

Das eine bezieht sich auf den Gen24 10.0 (wollte dort die Drosselung auslesen), die weiteren Werte auf den Symo 20.0. Ich versuche mich da mal weiter reinzulesen.

Ist 10^-4 nichts anderes als das Komma 4 Stellen nach links zu schieben? Müsste das Ergebnis bei 6248010^-4 nicht 6,2480 sein?

Zuletzt habe ich das mit scale: 0.0001 umgesetzt. Allerdings sind die Werte = die Register falsch. Hat jemand die richtigen für MPPT1 und MPPT2 jeweils für DC Spannung, Strom und Leistung bei einem Symo 20?

:crayon:by HarryP: Zusammenführung Doppelpost (bei Änderungen oder hinzufügen von Inhalten bitte die „Bearbeitungsfunktion“ anstatt „Antworten“ zu nutzen)

Ja

Ja hatte ich auch bis ich im Fronius dokument dann über folgenden Hinweis gestolpert bin.

A_SF = auto scaled on A, AphA, AphV, AphC und ja normalerweise sind SFs laut SunSpac statisch, aber wie oft bestätigt sich das es Ausnahmen von der Regel gibt. Deshalb rechne ich dann eher weniger gern im Kopf und baue eine scale ein wenn ich den Wert ohnehin aus einem Register entnehmen kann der im Register steht ist logischerweise in jedem Fall der Richtige.
Beim Schreiben in das Register müsste ich sonst auch wiederum dran denken das ich den Wert den ich schreiben will skalieren muss.

Sollte du deine PM nicht gelesen haben, im Fronius Dokument 42.0410.2649.pdf, betitelt ‘Fronius GEN24 Modbus TCP & RTU’ findest du den Link http://www.fronius.com/QR-link/0024 und bekommst ne ZIP mit den diversen Exceltapeten aller Register und aller WR.
Die Register der SYMOs sind aber immer identisch was halt auch der SunSpec konform ist. (Und wie schon gesagt Fronius zählt Register von 1-x, Home Assistant von 0-x, du musst also in Home Assistant immer 1s abziehen.

1 „Gefällt mir“

Ich wollte mich einmal bedanken für die tolle Hilfe. Es läuft jetzt soweit alles, war allerdings ein sehr weiter Weg für mich.

Feststellen musste ich, dass es in der Statistik / Diagrammen immer Spitzen gab, die wohl von einer Umstellung des Scale Factors kamen. Die Werte waren um den Faktor 10 oder sogar 100 verschoben (z.B. ca. 60.000W). Ich habe nun noch eine Bedingung reingeschrieben, die unrealistische Werte rausfiltern soll. Das Ergebnis teile ich gerne für andere, die vielleicht das gleiche Problem hatten:

modbus:
        
  - name: "Fronius Symo 20.0-3-M"
    type: tcp
    host: "10.0.9.52"  # IP-Adresse des Fronius Symo 20 Wechselrichters
    port: 502
    delay: 5
    timeout: 5
    sensors:
      - name: "Symo20 DCA_SF"
        slave: 1
        address: 40255  # Skalierungsfaktor für Strom
        input_type: holding
        unit_of_measurement: ""
        data_type: int16
        scan_interval: 10

      - name: "Symo20 DCV_SF"
        slave: 1
        address: 40256  # Skalierungsfaktor für Spannung
        input_type: holding
        unit_of_measurement: ""
        data_type: int16
        scan_interval: 10

      - name: "Symo20 DCW_SF"
        slave: 1
        address: 40257  # Skalierungsfaktor für Leistung
        input_type: holding
        unit_of_measurement: ""
        data_type: int16
        scan_interval: 10    

      - name: "Symo20 DC Strom MPPT1 RAW"
        slave: 1
        address: 40272  # 40272 Adresse für DC Strom (2_DCA) 
        input_type: holding
        unit_of_measurement: "A"
        data_type: uint16
        scan_interval: 10

      - name: "Symo20 DC Spannung MPPT1 RAW"
        slave: 1
        address: 40273  # 40273 Adresse für DC Spannung (2_DCV)
        input_type: holding
        unit_of_measurement: "V"
        data_type: uint16
        scan_interval: 10

      - name: "Symo20 DC Leistung MPPT1 RAW"
        slave: 1
        address: 40274  # 40274 Adresse für DC Leistung (2_DCW)
        input_type: holding
        unit_of_measurement: "W"
        data_type: uint16
        scan_interval: 10

      - name: "Symo20 DC Strom MPPT2 RAW"
        slave: 1
        address: 40292  # 40292 Adresse für DC Strom des zweiten Eingangs
        input_type: holding
        unit_of_measurement: "A"
        data_type: uint16
        scan_interval: 10


      - name: "Symo20 DC Spannung MPPT2 RAW"
        slave: 1
        address: 40293  # 40293 Adresse für DC Spannung des zweiten Eingangs
        input_type: holding
        unit_of_measurement: "V"
        data_type: uint16
        scan_interval: 10

      - name: "Symo20 DC Leistung MPPT2 RAW"
        slave: 1
        address: 40294  # 40294 Adresse für DC Leistung des zweiten Eingangs
        input_type: holding
        unit_of_measurement: "W"
        data_type: uint16
        scan_interval: 10
template:
  - sensor:
      - name: "Symo20 DC Strom MPPT1"
        unique_id: symo20_dc_strom_mppt1
        unit_of_measurement: "A"
        state_class: measurement
        device_class: current
        state: >
          {% set raw_value = states('sensor.symo20_dc_strom_mppt1_raw') | float(0) %}
          {% set scale_factor = states('sensor.symo20_dca_sf') | float(0) %}
          {% set current = raw_value * (10 ** scale_factor) %}
          {% if current > 30 or current < 0 %}
            unavailable
          {% else %}
            {{ current }}
          {% endif %}

      - name: "Symo20 DC Spannung MPPT1"
        unique_id: symo20_dc_spannung_mppt1
        unit_of_measurement: "V"
        state_class: measurement
        device_class: voltage
        state: >
          {% set raw_value = states('sensor.symo20_dc_spannung_mppt1_raw') | float(0) %}
          {% set scale_factor = states('sensor.symo20_dcv_sf') | float(0) %}
          {% set voltage = raw_value * (10 ** scale_factor) %}
          {% if voltage > 1000 or voltage < 0 %}
            unavailable
          {% else %}
            {{ voltage }}
          {% endif %}

      - name: "Symo20 DC Leistung MPPT1"
        unique_id: symo20_dc_leistung_mppt1
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power
        state: >
          {% set raw_value = states('sensor.symo20_dc_leistung_mppt1_raw') | float(0) %}
          {% set scale_factor = states('sensor.symo20_dcw_sf') | float(0) %}
          {% set power = raw_value * (10 ** scale_factor) %}
          {% if power > 20000 or power < 0 %}
            unavailable
          {% else %}
            {{ power }}
          {% endif %}

      - name: "Symo20 DC Strom MPPT2"
        unique_id: symo20_dc_strom_mppt2
        unit_of_measurement: "A"
        state_class: measurement
        device_class: current
        state: >
          {% set raw_value = states('sensor.symo20_dc_strom_mppt2_raw') | float(0) %}
          {% set scale_factor = states('sensor.symo20_dca_sf') | float(0) %}
          {% set current = raw_value * (10 ** scale_factor) %}
          {% if current > 30 or current < 0 %}
            unavailable
          {% else %}
            {{ current }}
          {% endif %}

      - name: "Symo20 DC Spannung MPPT2"
        unique_id: symo20_dc_spannung_mppt2
        unit_of_measurement: "V"
        state_class: measurement
        device_class: voltage
        state: >
          {% set raw_value = states('sensor.symo20_dc_spannung_mppt2_raw') | float(0) %}
          {% set scale_factor = states('sensor.symo20_dcv_sf') | float(0) %}
          {% set voltage = raw_value * (10 ** scale_factor) %}
          {% if voltage > 1000 or voltage < 0 %}
            unavailable
          {% else %}
            {{ voltage }}
          {% endif %}

      - name: "Symo20 DC Leistung MPPT2"
        unique_id: symo20_dc_leistung_mppt2
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power
        state: >
          {% set raw_value = states('sensor.symo20_dc_leistung_mppt2_raw') | float(0) %}
          {% set scale_factor = states('sensor.symo20_dcw_sf') | float(0) %}
          {% set power = raw_value * (10 ** scale_factor) %}
          {% if power > 20000 or power < 0 %}
            unavailable
          {% else %}
            {{ power }}
          {% endif %}

Ich hab mich heute mit dem gleichen Thema befasst, der Thread passt gerade perfekt :slight_smile: Ich bin noch recht neu in HAS, ich habe mich an der Modbus Geschichte vorher mit IP Symcon versucht.
Ich hab mir dein Lösung einfach mal kopiert, das war dann auch gleichzeitig mein erster Versuch mit Templates.
Aber irgendwas funktioniert noch nicht richtig. Aus dem Template raus müssten jetzt doch eigentlich Sensor Entitäten angelegt werden, die erscheinen aber nicht. Ich sehe nur die “Raw” Entitäten, die kommen ja aber aus der Modbus Konfiguration. Was könnte hier schief laufen? YAML Konfiguration ist erfolgreich geprüft und HAS neu gestartet.

Viele Grüße

Wenn du die Lösung kopiert hast
dann hast du 2 Abschnitte kopiert.
Die mit
modbus:
[ … ]
und auch die mit
template:
[ … ]
und in letzterer wird auch aus den raw Werten mit dem jeweiligen scaling factor dann der lesbare Wert.

oder?

Du könntest eine fixen scale_factor auch direkt in den modbus sensoren eintragen, allerdings hat das 2 Nachteile.

  1. kann ein scale faktor auch dynamisch sein, und im modbus kannst du nur statische Skalierungsfaktoren eingeben.
  2. kann es ja sein das du ein Register auch mal beschreiben willst, da ist es natürlich schön wenn man den echten Registerwert unskaliert kennt, und damit arbeitetn, da muss man dann beim Schreiben von Registern nicht erneut dran dran denken das man vor dem Schreiben wiederum skalieren müsste

Update:

Es liegt wohl daran wie ich das template in die configuration.yaml eingebunden habe. Wenn ich das komplette template hier direkt einfüge funktionert es. Es scheint also an dem !include_dir_merge zu liegen. Ich habe jetzt die template yaml direkt mit !include eingebunden und jetzt funktioniert es.

Genau, ich habe modbus und template in die configuration ergänzt:

modbus: !include modbus.yaml
template: !include_dir_merge_named templates/

Dann modbus.yaml erstellt mit ein paar Anpassungen der Namen auf Symo08

  - name: "Fronius Symo 8.0-3-M"
    type: tcp
    host: "192.168.0.5"  # IP-Adresse des Fronius Symo 20 Wechselrichters
    port: 502
    delay: 5
    timeout: 5
    sensors:
      - name: "Symo08 DCA_SF"
        slave: 1
        address: 40255  # Skalierungsfaktor für Strom
        input_type: holding
        unit_of_measurement: ""
        data_type: int16
        scan_interval: 10

      - name: "Symo08 DCV_SF"
        slave: 1
        address: 40256  # Skalierungsfaktor für Spannung
        input_type: holding
        unit_of_measurement: ""
        data_type: int16
        scan_interval: 10

      - name: "Symo08 DCW_SF"
        slave: 1
        address: 40257  # Skalierungsfaktor für Leistung
        input_type: holding
        unit_of_measurement: ""
        data_type: int16
        scan_interval: 10    

      - name: "Symo08 DC Strom MPPT1 RAW"
        slave: 1
        address: 40272  # 40272 Adresse für DC Strom (2_DCA) 
        input_type: holding
        unit_of_measurement: "A"
        data_type: uint16
        scan_interval: 10

      - name: "Symo08 DC Spannung MPPT1 RAW"
        slave: 1
        address: 40273  # 40273 Adresse für DC Spannung (2_DCV)
        input_type: holding
        unit_of_measurement: "V"
        data_type: uint16
        scan_interval: 10

      - name: "Symo08 DC Leistung MPPT1 RAW"
        slave: 1
        address: 40274  # 40274 Adresse für DC Leistung (2_DCW)
        input_type: holding
        unit_of_measurement: "W"
        data_type: uint16
        scan_interval: 10

      - name: "Symo08 DC Strom MPPT2 RAW"
        slave: 1
        address: 40292  # 40292 Adresse für DC Strom des zweiten Eingangs
        input_type: holding
        unit_of_measurement: "A"
        data_type: uint16
        scan_interval: 10


      - name: "Symo08 DC Spannung MPPT2 RAW"
        slave: 1
        address: 40293  # 40293 Adresse für DC Spannung des zweiten Eingangs
        input_type: holding
        unit_of_measurement: "V"
        data_type: uint16
        scan_interval: 10

      - name: "Symo08 DC Leistung MPPT2 RAW"
        slave: 1
        address: 40294  # 40294 Adresse für DC Leistung des zweiten Eingangs
        input_type: holding
        unit_of_measurement: "W"
        data_type: uint16
        scan_interval: 10

Dann eine template_fronius.yaml im Ordner /templates erstellt. Hier habe ich auch Namen angepasst und statt “unavailable” schreibe ich “0” auf die states bei der Skalierung.

  - sensor:
      - name: "Symo08 DC Strom MPPT1"
        unique_id: symo08_dc_strom_mppt1
        unit_of_measurement: "A"
        state_class: measurement
        device_class: current
        state: >
          {% set raw_value = states('sensor.symo08_dc_strom_mppt1_raw') | float(0) %}
          {% set scale_factor = states('sensor.symo08_dca_sf') | float(0) %}
          {% set current = raw_value * (10 ** scale_factor) %}
          {% if current > 30 or current < 0 %}
            0
          {% else %}
            {{ current }}
          {% endif %}

      - name: "Symo08 DC Spannung MPPT1"
        unique_id: symo08_dc_spannung_mppt1
        unit_of_measurement: "V"
        state_class: measurement
        device_class: voltage
        state: >
          {% set raw_value = states('sensor.symo08_dc_spannung_mppt1_raw') | float(0) %}
          {% set scale_factor = states('sensor.symo08_dcv_sf') | float(0) %}
          {% set voltage = raw_value * (10 ** scale_factor) %}
          {% if voltage > 1000 or voltage < 0 %}
            0
          {% else %}
            {{ voltage }}
          {% endif %}

      - name: "Symo08 DC Leistung MPPT1"
        unique_id: symo08_dc_leistung_mppt1
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power
        state: >
          {% set raw_value = states('sensor.symo08_dc_leistung_mppt1_raw') | float(0) %}
          {% set scale_factor = states('sensor.symo08_dcw_sf') | float(0) %}
          {% set power = raw_value * (10 ** scale_factor) %}
          {% if power > 20000 or power < 0 %}
            0
          {% else %}
            {{ power }}
          {% endif %}

      - name: "Symo08 DC Strom MPPT2"
        unique_id: symo08_dc_strom_mppt2
        unit_of_measurement: "A"
        state_class: measurement
        device_class: current
        state: >
          {% set raw_value = states('sensor.symo08_dc_strom_mppt2_raw') | float(0) %}
          {% set scale_factor = states('sensor.symo08_dca_sf') | float(0) %}
          {% set current = raw_value * (10 ** scale_factor) %}
          {% if current > 30 or current < 0 %}
            0
          {% else %}
            {{ current }}
          {% endif %}

      - name: "Symo08 DC Spannung MPPT2"
        unique_id: symo08_dc_spannung_mppt2
        unit_of_measurement: "V"
        state_class: measurement
        device_class: voltage
        state: >
          {% set raw_value = states('sensor.symo08_dc_spannung_mppt2_raw') | float(0) %}
          {% set scale_factor = states('sensor.symo08_dcv_sf') | float(0) %}
          {% set voltage = raw_value * (10 ** scale_factor) %}
          {% if voltage > 1000 or voltage < 0 %}
            0
          {% else %}
            {{ voltage }}
          {% endif %}

      - name: "Symo08 DC Leistung MPPT2"
        unique_id: symo08_dc_leistung_mppt2
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power
        state: >
          {% set raw_value = states('sensor.symo08_dc_leistung_mppt2_raw') | float(0) %}
          {% set scale_factor = states('sensor.symo08_dcw_sf') | float(0) %}
          {% set power = raw_value * (10 ** scale_factor) %}
          {% if power > 20000 or power < 0 %}
            0
          {% else %}
            {{ power }}
          {% endif %}

Es werden aber nur folgende Entitäten erstellt:

Also ich hab gerade mal Teile des Templates geprüft im Template Editor. Vom Prinzip funktioniert es, es werden tatsächlich nur die Sensoren aus dem Template nicht angelegt.

:crayon:by HarryP: Zusammenführung Doppelpost (bei Änderungen oder hinzufügen von Inhalten bitte die „Bearbeitungsfunktion“ anstatt „Antworten“ zu nutzen)

Guten Morgen,

habt ihr schon eine Lösung für die Peaks wenn die Scale-Faktoren umgestellt werden? Ich habe teilweise für einen kurzen Moment 60.000W Erzeugung. Diese Spitzen würde ich ja super gerne raushaben wollen. Ich habe schon versucht mit einem Filter zu arbeiten, aber damit habe ich es nur geschafft, solche unrealistischen Werte rauszubekommen. Wenn durch die Skalierung nach Sonnenuntergang ein Wert von z.B. 600W errechnet wird, dann würde dieser tatsächlich auftauchen…

Hier zwei Beispiele:


Moin zusammen,

bislang hat ja noch niemand verraten, dass es auch einfacher geht. Deswegen wollte ich das mal kurz loswerden.

Durch Zufall bin ich auf die Sunspec Integration gestoßen und konnte dort alle drei Wechselrichter einrichten und bekomme korrekte Werte gezeigt.