Get battery Energy sensors for new Enphase battery

I have just gotten an Enphase Battery 5P and System controller 3 and the Enphase Envoy integration is great, I’ve been able to do a lot.

However I have not been able to configure the Energy dashboard for the battery following the instructions * Energy dashboard.

I found some comment (somewhere) that since I don’t have a combiner there are not battery CTs and therefore “Envoy Lifetime battery energy charged” and “Envoy Lifetime battery energy discharged” entities do not exist.

To create sensors for the Energy dashboard I would like to take the “Envoy Available battery energy” sensor that reports 0 Whr at empty and 5000 Whr at full. When that sensor increases, add the increase to the “energy charged” sensor and when it decreases add the decrease to the “energy discharged” sensor. This value always seems to change in 50 Whr steps.

I have mostly been focused around a Utility meter helper but I haven’t been able to figure out any logic that would work to achieve this

I think the other option is to have an automation that looks at this ‘available energy’ and uses the difference from the last state to increment the appropriate sensor. Again no working ideas yet.

Does any one have any ideas or recommendations on how to achieve this?

I found some comment (somewhere) that since I don’t have a combiner there are not battery CTs and therefore “Envoy Lifetime battery energy charged” and “Envoy Lifetime battery energy discharged” entities do not exist.

The “Envoy Lifetime battery energy charged” and “Envoy Lifetime battery energy discharged” entities are only available when a “Storage CT” is installed. Not sure if that is related to a combiner or not or just an installation option to choose.

To create sensors for the Energy dashboard I would like to take the “Envoy Available battery energy” sensor that reports 0 Whr at empty and 5000 Whr at full

See for an “example how to” Envoy Battery not showing up to setup in Energy dashboard (charge/discharge). · Issue #121988 · home-assistant/core · GitHub.

An alternative is to use Riemann Integrator helper with the battery power entities.The mentioned on using the “avaialble battery energy” issue also has an examples for integrating the battery power into energy, read down form Envoy Battery not showing up to setup in Energy dashboard (charge/discharge). · Issue #121988 · home-assistant/core · GitHub

A good description how to do this integrate production and consumption power to energy is Enphase Envoy on 2024.4. You can do this similarly using battery power.

EDIT 6-OCT-2024:
linked “example how to” had an error. Last version : Enphase Envoy with Energy Dashboard - #814 by catsmanac

@catsmanac Thanks for the link it is good to see… however I just got it working (ish) 4 hours ago! Typical.

My method is reasonably similar but I skip the helper function and just do it all in one spot. See my code below. I don’t have any correction factor… I’ll have to see how much difference I see.

Do you spot any issue with the way that I have done it that yours solves? (other than the correction factor)
Resetting the value to zero if there is an unknown value or something I think is something the total_increasing class can handle but I’m unsure.

template:
  - trigger:
      - platform: state
        entity_id: sensor.envoy___SN___available_battery_energy
    sensor:
      - name: "battery_energy_in"
        state_class: total_increasing
        icon: mdi:transmission-tower
        unit_of_measurement: Wh
        device_class: energy
        state: >
          {% set delta = trigger.to_state.state | int - trigger.from_state.state | int %}
          {% if states('sensor.battery_energy_in') is not number %} {{ 0 | int }}
          {% elif delta > 0 %} {{states('sensor.battery_energy_in') | int + delta | int}}
          {% else %} {{ states('sensor.battery_energy_in') | int }}
          {% endif %}
      - name: "battery_energy_out"
        state_class: total_increasing
        icon: mdi:transmission-tower
        unit_of_measurement: Wh
        device_class: energy
        state: >
          {% set delta = trigger.from_state.state | int - trigger.to_state.state | int %}
          {% if states('sensor.battery_energy_out') | int is not number %} {{ 0 | int }}
          {% elif delta > 0 %} {{ states('sensor.battery_energy_out') | int + delta | int }}
          {% else %} {{ states('sensor.battery_energy_out') | int }}
          {% endif %}

The helper function is primarily to cover longer outages of HA as it remembers the last value before the outage. Although it will be incorrect when the battery both charges and discharges during the outage. Without it, a new calculation will only be done when the second good value after the outage comes in. Both methods may provide incorrect results, so either can be used. The second driver is the choice is between showing a little gap in the data or a continued line over the outage, for both valid reasons exist.

Part of the goal of the correction factor is to build awareness that the calculated values will probably be off from the Enphase App, which is clearly achieved :wink: .

The Energy dashboard will handle the reset to zero fine and account for it. But as this will happen with each HA restart my personal preference is for keeping current value rather then reset to 0, but there are valid reason to show it as a reset to zero as well. That is the power of HA, one can customize to personal preference without requiring everyone to do the same.

Makes sense.
I celebrated too soon however and my unknow state code doesn’t work as required.

{% if states('sensor.battery_energy_in') is not number %} {{ 0 | int }}
The code above works to set the number to zero if it is uninitialized however it never gets out of that if to update the value.

I need to have the code below for the update to work but it doesn’t seem to handle when the value is unknown.
{% if states('sensor.battery_energy_in') | int is not number %} {{ 0 | int }}

It looks like testing if the state is a number or not doesn’t fly.
Currently I’m attempting to use the code below. It seems to work in the testing I have done but I’m not sure about other cases.
{% if states('sensor.battery_energy_in') == 'unknown' %} {{ 0 | int }}

Full code I’m now using is below. One thing I forgot to mention is that I don’t think there is a way to do these kind of triggered sensors in the GUI. I tried for ages and couldn’t figure it out until I saw someone mention this.

template:
  - trigger:
      - platform: state
        entity_id: sensor.envoy___sn___available_battery_energy
    sensor:
      - name: "battery_energy_in"
        state_class: total_increasing
        icon: mdi:transmission-tower
        unit_of_measurement: Wh
        device_class: energy
        state: >
          {% set delta = trigger.to_state.state | int - trigger.from_state.state | int %}
          {% if states('sensor.battery_energy_in') == 'unknown' %} {{ 0 | int }}
          {% elif delta > 0 %} {{states('sensor.battery_energy_in') | int + delta | int}}
          {% else %} {{ states('sensor.battery_energy_in') | int }}
          {% endif %}
      - name: "battery_energy_out"
        state_class: total_increasing
        icon: mdi:transmission-tower
        unit_of_measurement: Wh
        device_class: energy
        state: >
          {% set delta = trigger.from_state.state | int - trigger.to_state.state | int %}
          {% if states('sensor.battery_energy_out') == 'unknown' %} {{ 0 | int }}
          {% elif delta > 0 %} {{ states('sensor.battery_energy_out') | int + delta | int }}
          {% else %} {{ states('sensor.battery_energy_out') | int }}
          {% endif %}

An bug fix to handle the ‘unavailable’ state as well as ‘unknown’

template:
  - trigger:
      - platform: state
        entity_id: sensor.envoy__sn__available_battery_energy
    sensor:
      - name: "battery_energy_in"
        state_class: total_increasing
        icon: mdi:transmission-tower
        unit_of_measurement: Wh
        device_class: energy
        state: >
          {% set delta = trigger.to_state.state | int - trigger.from_state.state | int %}
          {% if states('sensor.battery_energy_in') == 'unknown' or states('sensor.battery_energy_in') == 'unavailable' %} {{ 0 | int }}
          {% elif delta > 0 %} {{states('sensor.battery_energy_in') | int + delta | int}}
          {% else %} {{ states('sensor.battery_energy_in') | int }}
          {% endif %}
      - name: "battery_energy_out"
        state_class: total_increasing
        icon: mdi:transmission-tower
        unit_of_measurement: Wh
        device_class: energy
        state: >
          {% set delta = trigger.from_state.state | int - trigger.to_state.state | int %}
          {% if states('sensor.battery_energy_out') == 'unknown' or states('sensor.battery_energy_out') == 'unavailable' %} {{ 0 | int }}
          {% elif delta > 0 %} {{ states('sensor.battery_energy_out') | int + delta | int }}
          {% else %} {{ states('sensor.battery_energy_out') | int }}
          {% endif %}