Some useful calculation templates?

Post Reply
tony.matthews1
Posts: 15
Joined: Sun Mar 19, 2023 4:37 pm

I've added some templates to my configuration.yaml to calculate various things I wanted to track / display. In case this is useful to anyone here, this is what I added:

Code: Select all


#Templates enable math operations against states/values to give us better data
template:
  - sensor:
      # calculate inverter efficiency % using the difference between power in and power out
      - name: "inverter_efficiency"
        unit_of_measurement: "%"
        state: >
          {% set power_out = states('sensor.inverter_power_out') | float(default=0) %}
          {% set power_in = states('sensor.inverter_power_in') | float(default=0) %}
          {% set efficiency = power_out / power_in * 100 if power_in > 0.0 else null %}
          {% set efficiency = 100 if efficiency > 100 else efficiency %}
          {{ efficiency | round(1) }}
      # calculate cell imbalance as % using the difference between min and max cell voltage
      - name: "battery_cell_imbalance"
        unit_of_measurement: "%"
        state: >
          {% set cell_high = states('sensor.bms_cell_mv_high') | float(default=0) %}
          {% set cell_low = states('sensor.bms_cell_mv_low') | float(default=0) %}
          {% set imbalance = (cell_high-cell_low) / (cell_high + cell_low) * 200 if cell_low > 0.0 else 0.0 %}
          {% set imbalance = 0.0 if cell_high < cell_low else imbalance %}
          {{ imbalance | round(2) }}
      # calculate the number of hours that the battery can power the current load for
      - name: "battery_duration"
        icon: "mdi:timer-play"
        unit_of_measurement: "h"
        state: >
          {% set min_soc = 4 * 2.56 * 0.12 %}
          {% set energy = states('sensor.bms_kwh_remaining') | float(default=0) %}
          {% set power = states('sensor.load_power') | float(default=0) %}
          {% set power = 0.1 if power < 0.1 else power %}
          {% set hours = ((energy - min_soc) / power) | int  %}
          {% set hours = 24 if hours > 24 else hours  %}
          {% set hours = 0 if hours < 0 else hours  %}
          {{ hours }}
      # calculate the amount of energy stored in the battery today
      - name: "battery_backfill"
        device_class: "energy"
        unit_of_measurement: "kWh"
        state: >
          {{( states('sensor.pv_energy_daily')|float(default=0)
            + states('sensor.grid_daily')|float(default=0)
            - states('sensor.load_daily')|float(default=0)
            - states('sensor.feedin_daily')|float(default=0)
            - states('sensor.losses_daily')|float(default=0)
            ) | round(3) }}
      # calculate power flowing into inverter from solar, battery and grid
      - name: "inverter_power_in"
        device_class: "power"
        unit_of_measurement: "kW"
        state: >
          {% set pv_power_in = states('sensor.pv_power_now') | float(default=0) %}
          {% set rpower = states('sensor.RPower') | float(default=0) %}
          {% set rpower_in = 0.0 if rpower > 0.0 else rpower * -1.0 %}
          {% set bat_power = states('sensor.InvBatPower') | float(default=0) %}
          {% set bat_power_in = 0.0 if bat_power < 0.0 else bat_power %}
          {% set power_in = pv_power_in + rpower_in + bat_power_in %}
          {{ power_in | round(3) }}
      # calculate power flowing out of inverter
      - name: "inverter_power_out"
        device_class: "power"
        unit_of_measurement: "kW"
        state: >
          {% set rpower = states('sensor.RPower') | float(default=0) %}
          {% set rpower_out = 0 if rpower < 0.0 else rpower %}
          {% set eps_power_out = states('sensor.EPS_RPower') | float(default=0) %}
          {% set bat_power = states('sensor.InvBatPower') | float(default=0) %}
          {% set bat_power_out = 0 if bat_power > 0.0 else bat_power * -1.0 %}
          {% set power_out = rpower_out + eps_power_out + bat_power_out %}
          {{ power_out | round(3) }}
      # calculate grid balance - difference between grid power imported and exported
      - name: "net_import_daily"
        device_class: "power"
        unit_of_measurement: "kWh"
        state: >
          {{( states('sensor.grid_daily') | float(default=0)
            - states('sensor.feedin_daily') | float(default=0)
            ) | round(3) }}
      # calculate grid dependency - difference between load power consumed and solar power generated
      - name: "grid_dependency_daily"
        device_class: "power"
        unit_of_measurement: "kWh"
        state: >
          {{( states('sensor.load_daily') | float(default=0)
            - states('sensor.pv_energy_daily') | float(default=0)
            ) | round(3) }}
      # calculate sytem losses. Clip range between -1kw and +1kw to remove sampling errors and spikes
      - name: "System Losses"
        device_class: "power"
        unit_of_measurement: "kW"
        state: >
          {% set power_in = states('sensor.inverter_power_in') | float(default=0) %}
          {% set power_out = states('sensor.inverter_power_out') | float(default=0) %}
          {% set losses = power_in - power_out %}
          {% set losses = -1.0 if losses < -1.0 else losses %}
          {% set losses = 1.0 if losses > 1.0 else losses %}
          {{ losses | round(3) }}
Last edited by tony.matthews1 on Fri Apr 14, 2023 8:13 am, edited 4 times in total.
H1-6.0-E hybrid inverter
6 x HV2600 v2 batteries
16 x JA Solar 405w panels
7 x Tigo TS4-A-O optimisers
tony.matthews1
Posts: 15
Joined: Sun Mar 19, 2023 4:37 pm

Note on the templates above. I renamed some of the entities so they work with both USB and LAN connections and for consistency with Nathan Marlor. The sensor name changes I made are:

1. Remove dash from PV1-Voltage, PV1-Current, PV1-Power, PV2-Voltage, PV2-Current, PV2-Power, Battery-SoC, Battery-Temp, Time Period etc -> PV1 Voltage, PV1 Current, PV1 Power, PV2 Voltage, PV2 Current, PV2 Power, Battery Soc, Battery Temp in both modbusLAN and modbusUSB. HA substitutes the space with underscore.

2. 31008 -> RPower

3. Added EPS RVolt, EPS RCurrent, EPS RPower, EPS RFreq as sensors 31010/11015, 31011/11016, 31012/11017, 31013/11020 respectively for modbusLAN and modbusUSB

4. CT2 -> CT2 Meter in modbusLAN

5. BatVolt -> InvBatVolt (31020), BatCurrent -> InvBatCurrent (31021/11035), Battery-Discharge-Power -> InvBatPower (31022 / 11008). InvBatCurrent was incorrectly called Temp in modbusUSB
Last edited by tony.matthews1 on Thu Apr 06, 2023 12:28 pm, edited 1 time in total.
H1-6.0-E hybrid inverter
6 x HV2600 v2 batteries
16 x JA Solar 405w panels
7 x Tigo TS4-A-O optimisers
tony.matthews1
Posts: 15
Joined: Sun Mar 19, 2023 4:37 pm

Following a discussion, here are a couple of statistics sensors that create rolling averages to remove some of the noise from the raw values.
The last 2 sensors convert inverter power in / out to kWh. These are used in the inverter efficiency calculation above.

Code: Select all

sensor:
  - name: battery_cell_imbalance_rolling
    platform: statistics
    entity_id: sensor.battery_cell_imbalance
    state_characteristic: mean
    sampling_size: 10
    precision: 2
  - name: inverter_efficiency_rolling
    platform: statistics
    entity_id: sensor.inverter_efficiency
    state_characteristic: mean
    sampling_size: 24
    precision: 1
  - name: inverter_in_daily
    method: left
    platform: integration
    source: sensor.inverter_power_in
    unit_time: h
    round: 2
  - name: inverter_out_daily
    method: left
    platform: integration
    source: sensor.inverter_power_out
    unit_time: h
    round: 2    
Add this along with the sensors in configuration.yaml that work out energy (kWh) from power (kW)

I use the rolling average sensors in my dashboard so the figures a bit more stable visually. Also note: I scan my battery cell mv sensors at 30 second intervals, not at the default 5 seconds. Adjust the sampling_size if you use different scan intervals.
H1-6.0-E hybrid inverter
6 x HV2600 v2 batteries
16 x JA Solar 405w panels
7 x Tigo TS4-A-O optimisers
chris01942
Posts: 15
Joined: Sun Nov 06, 2022 8:34 am

Hi Tony, can I ask regarding inverter efficiency power out / power in does this take into account DC charging of the battery because my inverter efficiency looks very low?

Thanks, Chris
tony.matthews1
Posts: 15
Joined: Sun Mar 19, 2023 4:37 pm

chris01942 wrote: Thu Apr 06, 2023 9:11 am Hi Tony, can I ask regarding inverter efficiency power out / power in does this take into account DC charging of the battery because my inverter efficiency looks very low?

Thanks, Chris
Yes it should - how low is your efficiency showing and did you pick up all the sensors correctly, as there are some sensor name changes in here compared to last code release?

The power into the inverter is calculated from a) PV (pv_power_now) b) grid (RPower) and c) battery (InvBatPower). These are signed depending on whether power is being taken into the inverter or produced by it, so the input calculations include inflows and ignore any outflows.

The power out is the reverse of the above (outflows, not inflows) but also including power supplied via EPS (using RPower, EPS_Power and InvBatPower).

Overall, my power efficiency varies between around 88% and 95% with the inverter being less efficient converting solar DC to AC and more efficient converter battery DC to AC, with lower efficiency at lower power levels to be expected as the inverter itself has its own base load power. I force charge to 100% each day between 2am and 5am and my energy efficiency for the day seems to be set by that and doesn't vary much from 93.6%.

If you don't want to change sensor names, reverse out the changes in my code using your current names and the naming notes above.

Happy to look at your figures - hope there isn't something I have missed?
H1-6.0-E hybrid inverter
6 x HV2600 v2 batteries
16 x JA Solar 405w panels
7 x Tigo TS4-A-O optimisers
Post Reply