SunSpec / modbus TCP problem

Hi, I am trying to directly read an inverter with Solaredge inverter and meter via Modbus TCP. It communicates with SunSpec protocol, I saw that there is integration, but it has problems with scaling and the author has not responded for a long time. SunSpec for each quantity gives you two Modbus address the value and scale (which keeps changing). I would like to access the inverter directly and not use extensions that depend on the developer and solaredge. I have tried to do it myself, but the continuous scale changes lead to incorrect values, especially in the variations. I have modified the code so that it only calculates when the scale has not changed recently, but I keep getting absurd values 2/3 times a day. Sometimes they look like Modbus read errors, but sometimes they look like calculation errors.
Here is the code that goes to read the modbus data:

- name: "SolarEdge"
  type: tcp
  host: "192.168.1.9" # Sostituisci con l'indirizzo IP del tuo inverter
  port: 1502 # Porta predefinita per Modbus TCP
  sensors:
    - name: "Scala_W_pensiline_L"
      address: 40084
      input_type: holding
      data_type: int16
      unit_of_measurement: ""
      scale: 1
      state_class: measurement
      scan_interval: 30

    - name: "Pensiline_Potenza_L"
      address: 40083 # Registro SunSpec per la potenza AC
      input_type: holding
      data_type: int16
      scale: 1
      unit_of_measurement: "W"
      device_class: power
      state_class: measurement
      scan_interval: 30

Here the one that calculates the derived values

sensor:
      pensiline_potenza:
        unique_id: "id_pensiline_potenza"
        friendly_name: "Pensiline Potenza"
        unit_of_measurement: "kW"
        device_class: power
        value_template: >-
          {% set s1 = states('sensor.Pensiline_Potenza_L') %}
          {% set s2 = states('sensor.Scala_W_pensiline_L') %}
          {% set scale_last_change = as_timestamp(states.sensor.Scala_W_pensiline_L.last_changed) %}
          {% set now_ts = as_timestamp(now()) %}
          {% if (now_ts - scale_last_change) < 5 %}
            {{ none }}
          {% else %}
            {% if s1 not in ['unknown', 'unavailable', None] and s2 not in ['unknown', 'unavailable', None] %}
              {{ (s1 |float (0) * 10**(s2 |float (0))) / 1000 | round(2) }}
            {% else %}
              {{ none }}
            {% endif %}
          {% endif %}

Do you have any suggestions to eliminate these error? It would be fine for me to simply eliminate them when absurd. Many thanks

I wrote an integration for SolarEdge, which I recommend instead of trying to read modbus values directly:

The problem with modbus sensors is that the scale value on the inverter can change between reads, which gives you bad values. The only way to match scales and values is to read them at the same in a single read, which modbus integration can not do.

Many thanks for your reply, I was just trying to read the values at the same time, are you sure you can’t? I was trying like this:

- name: "Correnti_Complete"
  address: 40191 # Primo registro della serie (corrente Fase A)
  input_type: holding
  count: 4 # Legge 4 registri consecutivi (40191, 40192, 40193, 40194)
  data_type: custom
  structure: ">hhh h" # 3 valori int16 + 1 valore int16 (scala)
  scan_interval: 10

Can it work? Work in progress, now I’ve no time to test.

Well, my experience is it was easier creating a custom integration instead of trying to get core modbus to work with all the quirks of SolarEdge inverters. So I recommend my integration because I’ve already done all the hard work.

If you want to keep trying modbus then I would recommend looking through my code to find all the methods and tests I’ve had to use to keep the data clean.

many thanks, you are very kind!

I have this issue as well. I think the issue is with the smart meter not the invertor.

I am using this - GitHub - nmakel/solaredge_modbus: SolarEdge Modbus data collection library

I was on an old version (0.67?) which was the latest when I first started using it. Updated to the current latest and still the same.

I have a SE-MTR-3Y-400V-A. The values for consumption and export are no longer valid and often wildly wrong eg consumption or export of 30kW on a system with only 8kW of panels and no possible way for consumption to be that high. As you said the scale seems to change randomly eg sometimes it will move the decimal point so 300.00 becomes 30000. But there are often other random values which I can’t put down to scaling, they are just totally wrong.

The Solaredge app always reflects the expected values and used to match the script output.

As far as I can tell it first started around Feb 2025 after previously working 100% reliably for over 2 years. I have a ticket open with Solaredge and as expected they are less than helpful. Very frustrating. I can’t work out if it’s a modbus/code issue or hardware failure.