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
325 stars 83 forks source link

Battery Charge / Discharge #37

Closed Louisbertelsmann closed 1 year ago

Louisbertelsmann commented 1 year ago

Would it be possible to have separate entitys for charging and discharging of the battery? Or one entity that's negative when the battery is discharging and positive when the battery is charging. I don't really know much about templating in Home Assistant, but figured it could be done using the Binary Sensors relying on Running State.

Louisbertelsmann commented 1 year ago

Already got it.

mkaiser commented 1 year ago

hi Louis,

good timing, I was just about to code something. Can you share and spare us some work?

Martin

Louisbertelsmann commented 1 year ago

This template uses the binary sensors uses the binary sensors for Battery Charging and Battery Discharging and the sensor Battery Power. - name: "Battery Charging and Discharging Power" # Positive if charging and negative if discharging unit_of_measurement: W device_class: power state: > {% if is_state('binary_sensor.battery_charging', 'on') %} {{ (states('sensor.battery_power') | float * 1 | float) |int }} {% elif is_state('binary_sensor.battery_discharging', 'on') %} {{ (states('sensor.battery_power') | float * -1 | float) |int }} {% else %} {{ (states('sensor.battery_power') | float * 1 | float) |int }} {% endif %}

Louisbertelsmann commented 1 year ago

This is my first time creating a template in Home Assistant. I hope it's reliable and works with every inverter.

elektrinis commented 1 year ago

I would love to have a single entity with battery power, either positive (charging) or negative (discharging). Those flags charging/discharging are not very useful in my case.

Louisbertelsmann commented 1 year ago

That‘s exactly what my template does. It‘s positive if the battery is charging and negative if it‘s discharging.

elektrinis commented 1 year ago

Would love to see this in the integration!

Louisbertelsmann commented 1 year ago

If you want to, you can already add it to your configuration.

mkaiser commented 1 year ago

I just re-discovered a post from bjeanes in this integration's home assistant community thread:

https://community.home-assistant.io/t/sungrow-sh10-rt-modbus-integration/361356/29

There is some more "exception handling" involved, when the sensor did not yet delivered some valid data:

inverter_battery_power: unique_id: inverter_battery_power

    friendly_name: Inverter battery power
    value_template: >-
      {% set current = states('sensor.inverter_battery_current') %}
      {% set power = states('sensor.inverter_battery_power_raw') %}
      {% if 'unavailable' in [current, power] %}
        unavailable
      {% elif current|float < 0.0 and power|float > 0.0 %}
        {{ -1 * power | float }}
      {% else %}
        {{ power | float }}
      {% endif %}
    unit_of_measurement: W
    device_class: power

one thing still bothers me about the naming.

When you look at the new sensor "Battery Charging and Discharging Power", it is a bit ambiguous, in which direction the energy flows. It is very subjective if the battery charging is interpreted as "good / positive value" or "bad / negative value" (or the other way round with discharging)

I did not come up with a better name, yet to describe this template sensor for the battery charge, so thinking loud here....

The grid sensor for "export power", is a bit more distingt: If it is positive, you are exporting power, if negative you can deviate that you are importing power.

Maybe rename the sensor based on your suggestion to "Battery Charging Power", # Positive if charging and negative if discharging

and add a second sensor "Battery Discharging Power" # Positive if discharging and negative if charging

The "Export Power" would get the mirrored "Import Power"

What do you think?

Louisbertelsmann commented 1 year ago

That‘s a good idea. I‘m gonna do that today. I‘m gonna post the code in this Issue.

Louisbertelsmann commented 1 year ago

Done. Hope it works for you. ` - name: "Battery Charging Power" # Positive if Charging and negative if Discharging unit_of_measurement: W device_class: power state: > {% if is_state('binary_sensor.battery_charging', 'on') %} {{ (states('sensor.battery_power') | float 1 | float) |int }} {% elif is_state('binary_sensor.battery_discharging', 'on') %} {{ (states('sensor.battery_power') | float -1 | float) |int }} {% else %} {{ (states('sensor.battery_power') | float * 1 | float) |int }} {% endif %}

- name: "Battery Discharging Power" # Positive if Discharging and negative if Charging
  unit_of_measurement: W
  device_class: power
  state: >
    {% if is_state('binary_sensor.battery_charging', 'on') %}
      {{ (states('sensor.battery_power') | float * -1 | float) |int }}
    {% elif is_state('binary_sensor.battery_discharging', 'on') %}
      {{ (states('sensor.battery_power') | float * 1 | float) |int }}
    {% else %}
      {{ (states('sensor.battery_power') | float * 1 | float) |int }}
    {% endif %} 

`

mkaiser commented 1 year ago

made a testing branch for that, because there is no sun and I am in a rush

https://github.com/mkaiser/Sungrow-SHx-Inverter-Modbus-Home-Assistant/tree/testing

Can you test? I also adapted the PV Info dashboard

Grüße aus Bielefeld!

Louisbertelsmann commented 1 year ago

I'm gonna test it today.

Grüße aus der Nähe von Minden.

Louisbertelsmann commented 1 year ago

grafik grafik Schreibe ich mal auf Deutsch weiter. Wie du auf den Bildern siehst, funktioniert es soweit ganz gut. Deine Ergänzung, dass es als "Unavailable" angezeigt wird, wenn etwas nicht passt, finde ich sehr gut. Auch mit dem Power Flow Card Addon funktioniert es super.

mkaiser commented 1 year ago

the power flow card addon is really nice - thanks for the tip.

My configuration is

views:

  • theme: Backend-selected title: PV Power icon: mdi:solar-power badges: [] cards:
    • type: custom:power-flow-card kw_decimals: 2 entities: grid: sensor.import_power battery: sensor.battery_discharging_power battery_charge: sensor.battery_level solar: sensor.total_dc_power
Louisbertelsmann commented 1 year ago

grafik I've also added the Tesla Style Power Flow Card, because I think that it looks quite nice. I had to create some new templates. If you want to check it out, I've put them below.

- name: "Inverter loss"
      unit_of_measurement: W
      device_class: power
      state: >
        {{ states('sensor.total_dc_power')|int(default=0) - states('sensor.battery_charging_power')|int(default=0) - states('sensor.load_power')|int(default=0) - states('sensor.export_power')|int(default=0) }}

    - name: "Real load" # includes house power and inverter loss
      unit_of_measurement: W
      device_class: power
      state: >
        {{ states('sensor.load_power')|int(default=0) + states('sensor.inverter_loss')|int(default=0) }}

    - name: "Import Power" # only positive
      unit_of_measurement: W 
      device_class: power 
      state: > 
        {% if ((states('sensor.export_power')  |int(default=0)) < 0 ) %}
            {{ states('sensor.export_power')|int(default=0)|abs }}
        {% else %}
            0
        {% endif %}

    - name: "Grid to House" # only positive
      unit_of_measurement: W
      device_class: power
      state: >
        {% if states('sensor.import_power')|float(default=0) > states('sensor.real_load')|float(default=0) %}
            {{ states('sensor.load_power')|float(default=0) }}
        {% else %}
            {{ states('sensor.import_power')|float(default=0) }}
        {% endif %}

    - name: "Grid to Battery"
      unit_of_measurement: W
      device_class: power
      state: >
        {% if states('sensor.import_power')|int(default=0) > states('sensor.real_load')|int(default=0) %}
            {{ states('sensor.import_power')|int(default=0) - states('sensor.real_load')|int(default=0) }}
        {% else %}
            0
        {% endif %}

    - name: "Battery to House"
      unit_of_measurement: W
      device_class: power
      state: >
        {% if states('sensor.battery_charging_power')|int(default=0) < 0 %}
            {% if states('sensor.battery_charging_power')|int(default=0)|abs > states('sensor.real_load')|int(default=0) %}
                {{ states('sensor.real_load')|int(default=0) }}
            {% else %}
                {{ states('sensor.battery_charging_power')|int(default=0)|abs }}
            {% endif %}
        {% else %}
            0
        {% endif %}

    - name: "Battery to Grid"
      unit_of_measurement: W
      device_class: power
      state: >
        {% if states('sensor.battery_charging_power')|int(default=0) < 0 %}
            {% if states('sensor.battery_charging_power')|int(default=0)|abs > states('sensor.real_load')|int(default=0) %}
                {{ states('sensor.battery_charging_power')|int(default=0)|abs - states('sensor.real_load')|int(default=0) }}
            {% else %}
                0
            {% endif %}
        {% else %}
            0
        {% endif %}

    - name: "Solar to Grid"
      unit_of_measurement: W
      device_class: power
      state: >
        {% if states('sensor.export_power')|int(default=0) > states('sensor.battery_to_grid')|int(default=0) %}
            {{ states('sensor.export_power')|int(default=0) - states('sensor.battery_to_grid')|int(default=0) }}
        {% else %}
            0
        {% endif %}

    - name: "Solar to House"
      unit_of_measurement: W
      device_class: power
      state: >
        {% if states('sensor.total_dc_power')|int(default=0) > 0 and states('sensor.real_load')|int(default=0) > states('sensor.battery_to_house')|int(default=0) + states('sensor.import_power')|int(default=0) %}
            {% if states('sensor.total_dc_power')|int(default=0) > states('sensor.real_load')|int(default=0) - states('sensor.battery_to_house')|int(default=0) - states('sensor.grid_to_house')|int(default=0) %}
                {{ states('sensor.real_load')|int(default=0) - states('sensor.battery_to_house')|int(default=0) - states('sensor.grid_to_house')|int(default=0) }}
            {% else %}
                {{ states('sensor.total_dc_power')|int(default=0) }}
            {% endif %}
        {% else %}
            0
        {% endif %}

    - name: "Solar to Battery"
      unit_of_measurement: W
      device_class: power
      state: >
        {% if states('sensor.total_dc_power')|int(default=0) > 0 and states('sensor.battery_charging_power')|int(default=0) > 0 %}
            {% if states('sensor.battery_charging_power')|int(default=0) > states('sensor.grid_to_battery')|int(default=0) %}
                {% if states('sensor.total_dc_power')|int(default=0) - states('sensor.solar_to_house')|int(default=0) > states('sensor.battery_charging_power')|int(default=0) - states('sensor.grid_to_battery')|int(default=0) %}
                    {{ states('sensor.battery_charging_power')|int(default=0) - states('sensor.grid_to_battery')|int(default=0) }}
                {% else %}
                    {{ states('sensor.total_dc_power')|int(default=0) - states('sensor.solar_to_house')|int(default=0) - states('sensor.solar_to_grid')|int(default=0) }}
                {% endif %}
            {% else %}
                0
            {% endif %}
        {% else %}
            0
        {% endif %}