mkaiser / Sungrow-SHx-Inverter-Modbus-Home-Assistant

Sungrow SH Integration for Home Assistant for SH3K6, SH4K6, SH5K-20, SH5K-V13, SH3K6-30, SH4K6-30, SH5K-30, SH3.RS, SH3.6RS, SH4.0RS, SH5.0RS, SH6.0RS, SH5.0RT, SH6.0RT, SH8.0RT, SH10RT, SH5.0RT-20, SH6.0RT-20, SH8.0RT-20, SH10RT-20, SH5.0RT-V112, SH6.0RT-V112, SH8.0RT-V112, SH10RT-V112, SH5.0RT-V122, SH6.0RT-V122, SH8.0RT-V122, SH10RT-V122, SH4.6R
376 stars 95 forks source link

Eliminate "meter active power" template sensors #371

Open Gnarfoz opened 1 month ago

Gnarfoz commented 1 month ago

There are a bunch of template sensors providing a layer of indirection for the "meter active power" sensors apparently intended to cover the case where the "raw" sensors report 0x7FFFFFFF (when grid power is down).

It should be possible to remove them and turn the "raw" sensors into the normal ones. The Modbus integration provides the nan_value option (https://www.home-assistant.io/integrations/modbus/#nan_value). If the value of the Modbus sensor matches this value, the sensor will go to unavailable state. Basically, this provides a way to say "this value also means unavailable".

Caveat: the documentation says the following:

Please note that the hex to int conversion for nan_value does currently not obey home-assistants Modbus encoding using the data_type, structure, or swap arguments.

I'm not sure if that means you'd have to provide the value as 0xFFFF7FFFF. I don't think so since it says 'hex to int conversion' and clearly, 0x7FFFFFFF is hex, not int.

Dwelling on that... why do the template sensors even convert to int? They're comparing against a hex value...?(states('sensor.meter_active_power_raw')|int != 0x7FFFFFFF)

mkaiser commented 1 month ago

hi,

I did not know the nan_value before. quickly browsing our code: 0x7FFFFFFF is the only "magic unavailable number" here, right?

From the documentation I don't understand how to set the NaN value. Is there an example I missed?

Dwelling on that... why do the template sensors even convert to int? They're comparing against a hex value...?(states('sensor.meter_active_power_raw')|int != 0x7FFFFFFF)

states('sensor.meter_active_power_raw') provides a string. Before comparing this string with a number, we need to convert it to a number: |int. Then we can compare it to 0x7FFFFFFF or 2147483647 (converted to decimal)

If you would be so kind to test the NaN-stuff I am happy to integrate it, but I am lacking time to do this by myself :/

Gnarfoz commented 1 month ago

nan_value was added in August 2023, so it's a bit newer than when you started this thing. Thanks for pointing out that the sensor value is a string, now the casting makes sense. 👍

As for using it, I think it would turn this:

      - name: Meter active power
        unique_id: sg_meter_active_power
        unit_of_measurement: W
        device_class: power
        state_class: measurement
        availability: >-
          {{ 
          not is_state('sensor.meter_active_power_raw', 'unavailable')
          and states('sensor.meter_active_power_raw')|int != 0x7FFFFFFF
          }}
        state: "{{ states('sensor.meter_active_power_raw') }}"

      - name: Meter active power raw
        unique_id: sg_meter_active_power_raw
        device_address: !secret sungrow_modbus_slave
        address: 5600 # reg 5601
        input_type: input
        data_type: int32
        swap: word
        precision: 0
        unit_of_measurement: W
        device_class: power
        state_class: measurement
        scale: 1
        scan_interval: 10

into this:

      - name: Meter active power
        unique_id: sg_meter_active_power
        device_address: !secret sungrow_modbus_slave
        address: 5600 # reg 5601
        input_type: input
        data_type: int32
        swap: word
        nan_value: 0x7FFFFFFF
        precision: 0
        unit_of_measurement: W
        device_class: power
        state_class: measurement
        scale: 1
        scan_interval: 10

The template sensor becomes superfluous and the "raw" sensor becomes the real / only one (which also means there's no longer a reason to call it "raw").

I will give it a try locally and see how it goes. I'll have to kill power to my house, won't I? 😂

Gnarfoz commented 1 month ago

This will probably take a while, but it'll give me a reason to actually set up and test backup mode.

mkaiser commented 1 month ago

Code is a lot cleaner this way - I like it. Maybe some of the guys who have the Backup set up (discord) could help?