Sensor data collection via modbus, calculated new data with an issue

Hi,

I am reasonably new to home assistant and because I face an issue I just signed in to this community. I hope someone can help.

I configured in configuration.yaml a TCP modbus connection and I poll data from an inverter (Fronius symo Gen24) at intervals of 60 sec:

  • string power ā†’ uint16
  • associated scale factor
    The actual string power is then calculated by:
template:
  - sensor:
      - name: "String West"
        unit_of_measurement: "W"
        device_class: power
        state: >
          {{ (((states.sensor.power_string_1.state) | float) * 10
          ** (states.sensor.dcw_sf.state | int)) | round(0)}}
        unique_id: "String_West"

It usually does work ok but sometimes when the scale fact changes HA stores 2 values for the same time stamp:

time in mm:ss Register DCW_SF P calculated
12:55:45 6411 -1 641
56:45 6097 -1 610
57:45 53665 -2 61 calculated on previous value
57:45 53665 -2 537 correct
58:45 6040 -1 5366 calculated on previous value
58:45 6040 -1 604 correct
59:45 6408 -1 641

When you visualize the data in e.g. Grafana there are those incorrect peaks.
Any idea why HA does not calculate the data correctly?
Any ideas how to overcome this issue?

Thanks
tom555

Here is the corresponding visualization in HA.

Is seems so that HA get the value of the scale factor first and does the calculation with the old register value. Then few moments later the new register value is available and HA does the next calculation where both values are ok and the calculation OK.

Is there any option to sort of delay the calculation or to discard the first one?

Hello, I have the same problem. Have you found any solution?

Yes, I use the REST API for this and it works with no issues. I can post the code later on.

I think what also worked for me was the following check.
The value of the scale fact always came first few ms before the power value.

- sensor:
      - name: "String West"
        unit_of_measurement: "W"
        device_class: power
        state: >
          {% if as_timestamp(states.sensor.power_string_1.last_changed) - as_timestamp(states.sensor.dcw_sf.last_changed) > 0 %}
          {{ (((states.sensor.power_string_1.state) | float) * 10
          ** (states.sensor.dcw_sf.state | int)) | round(0)}}
          {% endif %}
        unique_id: "String_West"

As already mentioned I now use the REST API:

rest:
  - scan_interval: 15
    method: GET
    resource: http://192.168.178.xx/solar_api/v1/GetInverterRealtimeData.cgi?Scope=Device&DataCollection=CommonInverterData
    sensor:
      - name: "P String West"
        value_template: "{{ (value_json.Body.Data.IDC.Value | float * value_json.Body.Data.UDC.Value | float) | round(0) }}"
        unit_of_measurement: "W"
        device_class: power
        unique_id: "p_string_west"
      - name: "P String Ost"
        value_template: "{{ (value_json.Body.Data.IDC_2.Value | float * value_json.Body.Data.UDC_2.Value | float) | round(0) }}"
        unit_of_measurement: "W"
        device_class: power  
        unique_id: "p_string_ost"
      - name: "P Generator"
        value_template: "{{ (value_json.Body.Data.IDC.Value | float * value_json.Body.Data.UDC.Value | float) | round(0) +  (value_json.Body.Data.IDC_2.Value | float * value_json.Body.Data.UDC_2.Value | float) | round(0) }}"
        unit_of_measurement: "W"
        device_class: power  
        unique_id: "p_generator"

I also check the isolation resistance via modbus. Here I had a simile issue but this code works:

modbus:
  - name: fronius_modbus
    type: tcp
    host: 192.168.178.xx  # use the IP address of your Inverter
    port: 502
    retries: 3
    sensors:
      - name: "Ris_SF"
        slave: 1
        address: 40236
        data_type: int16
        scan_interval: 60
        unique_id: "uniqueid_40236"
      - name: "Ris"
        slave: 1
        address: 40235
        data_type: uint16
        scan_interval: 60
        unique_id: "uniqueid_40235"   

template:
  - sensor:
      - name: "Riso"
        unit_of_measurement: "Mohm"
        state: >
          {% if states.sensor.ris_sf.state | float >= 0 and as_timestamp(states.sensor.ris.last_changed) - as_timestamp(states.sensor.ris_sf.last_changed) > 0 and (((states.sensor.ris.state | float)  | float) * 10 ** (states.sensor.ris_sf.state | int) / 1000000) < 90 %}
          {{ (((states.sensor.ris.state | float)  | float) * 10 ** (states.sensor.ris_sf.state | int) / 1000000) | round(1) }}
          {% endif %}
        unique_id: "Generator_Riso" 

Hi :wave:!

Iā€™d be interested if there is any upside to using the rest integration than to use the Fronius core integration.

Certain values are not available via the REST API, e.g. isolation resistance.

And you cannot modify parameters via REST. Under certain condition I write certain values to some registers, for instance, when I want to reduce the max. battery discharge power.

1 Like