Enphase Envoy with Lovelace Dashboard

Hello HA community.

Since I’m a new Enphase user, I was tired to switch between HA and the Enphase app to check my data. So I decided to integrate as close as I can the features I was using in the app, inside HA.

This guide wouldn’t have been possible without the help of @del13r, everything started thanks to him. (Enphase Envoy on 2024.4, Enphase Envoy - D7 firmware with JWT - A Different Approach)

I also wanted to simplify the sensors part, so I wrote all of them in the configuration.conf, avoiding tutorials to create them through the UI.

To know:

  • I created more sensors for W / kW / Rounded convertions.
  • Maybe some thing could be done in a simplier way for the same result (like the sensors above), please let me know how to improve them :slight_smile:
  • I manage to create an input to switch the apex-charts days, but I won’t be able to do so for other data.
  • the Importing card is dynamic and switch between Importing/Exporting as long as the icon.

Result:

Enphase App:

HA:

First, you’ll need HACS, with these plugins:

* vertical-stack-in-card
* config-template-card
* mushroom-entity-card
* vertical-stack
* custom:apexcharts-card
* card-mod
* numberbox-card
* power-flow-card-plus

Here is the configuration.conf file:

# Envoy sensors
input_number:
  days_back:
    initial: 0
    min: 0
    max: 365
    step: 1

template:
  - sensor:
      name: Power Import
      state_class: measurement
      unit_of_measurement: W
      device_class: power
      icon: mdi:flash
      state: >
        {{ [ 0,
          states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_consumption') | float(0) * 1000
        -
          states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_production') | float(0) * 1000 ] | max | int(0)
        }}
  - sensor:
      name: Power Import kW
      state_class: measurement
      unit_of_measurement: kW
      device_class: power
      icon: mdi:flash
      state: >
        {% set production = states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_production') | float %}
        {% set consumption = states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_consumption') | float  %}
        {{ (consumption - production) | round(1) }}
  - sensor:
      name: Power Export
      state_class: measurement
      unit_of_measurement: W
      device_class: power
      icon: mdi:flash
      state: >
        {{ [ 0,
          states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_production') | float(0) * 1000
        -
          states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_consumption') | float(0) * 1000 ] | max | int(0)
        }}
  - sensor:
      name: Power Import Rounded
      state_class: measurement
      unit_of_measurement: kW
      device_class: power
      icon: mdi:flash
      state: >
        {% set production = states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_consumption') | round(1) %}
        {{ production }}
  - sensor:
      name: Power Export Rounded
      state_class: measurement
      unit_of_measurement: kW
      device_class: power
      icon: mdi:flash
      state: >
        {% set production = states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_production') | round(1) %}
        {% if production <= 0 %}
          0
        {% else %}
          {{ production }}
        {% endif %}
  - sensor:
      name: Net Power
      state_class: measurement
      unit_of_measurement: W
      device_class: power
      icon: mdi:transmission-tower
      state: >
        {% set production = states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_production') | float * 1000 %}
        {% set consumption = states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_consumption') | float * 1000 %}
        {{ (production - consumption) }}
  - sensor:
      name: Net Power kW
      state_class: measurement
      unit_of_measurement: kW
      device_class: power
      icon: mdi:transmission-tower
      state: >
        {% set production = states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_production') | float %}
        {% set consumption = states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_consumption') | float  %}
        {{ (production - consumption) | round(3) }}
  - sensor:
      name: Net Power Rounded kW
      state_class: measurement
      unit_of_measurement: kW
      device_class: power
      icon: mdi:transmission-tower
      state: >
        {% set production = states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_production') | float %}
        {% set consumption = states('sensor.envoy_YOURENPHASESERIALNUMBER_current_power_consumption') | float  %}
        {{ (consumption - production) | round(1) }}
  - sensor:
      unique_id: 1ec910ba-eef3-451a-976e-e69426e893a9
      name: Today Net Imported kWh
      state_class: measurement
      unit_of_measurement: kWh
      device_class: power
      icon: mdi:transmission-tower
      state: >
        {% set production = states('sensor.envoy_YOURENPHASESERIALNUMBER_energy_production_today') | float %}
        {% set consumption = states('sensor.envoy_YOURENPHASESERIALNUMBER_energy_consumption_today') | float  %}
        {{ (consumption - production) | round(3) }}
  - sensor:
      unique_id: ca3578ad-461f-46d8-a6c5-bc2bdf66c050
      name: Today Exported kWh
      state_class: measurement
      unit_of_measurement: kWh
      device_class: power
      icon: mdi:transmission-tower
      state: >
        {% set imported = states('sensor.today_imported_kwh') | float %}
        {% set net_imported = states('sensor.today_net_imported_kwh') | float %}
        {% set exported = (imported - net_imported) %}
        {% if exported < 0 %}
          0.0
        {% else %}
          {{ exported | round(1) }}
        {% endif %}
  - sensor:
      unique_id: b7e55380-4703-489a-bfbd-18ff94052804
      name: Grid dependence
      icon: mdi:transmission-tower
      state: >
        {% set imported = states('sensor.today_imported_kwh') | float %}
        {% set consumption = states('sensor.envoy_YOURENPHASESERIALNUMBER_energy_consumption_today') | float  %}
        {% if (imported / consumption) * 100 > 99.1 %}
          100
        {% else %}
          {{ ((imported / consumption) * 100) | round }}
        {% endif %}

utility_meter:
  today_imported_kwh:
    unique_id: 1f9bfbbb-0b40-4fa3-a5ec-e76064fb8e75
    source: sensor.energy_import
    cycle: daily

  today_exported_kwh_2:
    unique_id: 80baed49-cd79-43bd-840f-49205aeb181d
    source: sensor.energy_export
    cycle: daily

sensor:
  - platform: integration
    unique_id: d2a2b97d-8794-4d6b-8c81-d5727b683100
    name: Energy Export
    source: sensor.power_export
    unit_prefix: k
    unit_time: h
    method: right

  - platform: integration
    unique_id: db164481-da37-4c18-9769-39119a8c1eea
    name: Energy Import
    source: sensor.power_import
    unit_prefix: k
    unit_time: h
    method: right
# /Envoy sensors

And the Lovelace YAML:

type: grid
cards:
  - type: heading
    heading: Power
    heading_style: title
    icon: mdi:lightning-bolt
  - type: custom:vertical-stack-in-card
    card_mod:
      style: |
        ha-card {
          background: transparent;
          box-shadow: none;
          overflow: visible !important;
        }
    cards:
      - square: false
        type: grid
        columns: 3
        cards:
          - type: custom:vertical-stack-in-card
            card_mod:
              style: |
                ha-card {
                  background: transparent;
                  box-shadow: none;
                  overflow: visible !important;
                }
            cards:
              - square: false
                type: grid
                columns: 1
                cards:
                  - type: custom:config-template-card
                    entities:
                      - sensor.today_imported_kwh
                    card:
                      type: custom:mushroom-entity-card
                      entity: sensor.today_imported_kwh
                      name: Imported
                      icon_color: grey
                  - type: custom:config-template-card
                    entities:
                      - sensor.envoy_YOURENPHASESERIALNUMBER_energy_production_today
                    card:
                      type: custom:mushroom-entity-card
                      entity: sensor.envoy_YOURENPHASESERIALNUMBER_energy_production_today
                      name: Produced
                      icon_color: "#01b4de"
          - type: tile
            entity: sensor.envoy_YOURENPHASESERIALNUMBER_energy_consumption_today
            grid_options:
              columns: 6
              rows: 1
            vertical: true
            color: "#f37320"
            name: Consumed
          - type: custom:vertical-stack-in-card
            card_mod:
              style: |
                ha-card {
                  background: transparent;
                  box-shadow: none;
                  overflow: visible !important;
                }
            cards:
              - square: false
                type: grid
                columns: 1
                cards:
                  - type: custom:config-template-card
                    entities:
                      - sensor.today_exported_kwh_2
                    card:
                      type: custom:mushroom-entity-card
                      entity: sensor.today_exported_kwh_2
                      name: Exported
                      icon_color: grey
                  - type: custom:config-template-card
                    entities:
                      - sensor.today_net_imported_kwh
                    card:
                      type: custom:mushroom-entity-card
                      entity: sensor.today_net_imported_kwh
                      name: Net imported
                      icon_color: "#f37320"
  - type: vertical-stack
    cards:
      - type: custom:config-template-card
        variables:
          days: |
            '-'+-states['input_number.days_back'].state+'d'
        entities:
          - input_number.days_back
        card:
          type: custom:apexcharts-card
          span:
            start: day
            offset: ${days}
          apex_config:
            grid:
              show: true
              borderColor: rgba(123, 123, 123, 0.5)
            chart:
              height: 250px
          graph_span: 24h
          stacked: true
          series:
            - entity: sensor.envoy_YOURENPHASESERIALNUMBER_current_power_consumption
              transform: return x *-1 ;
              type: column
              name: Consumed
              color: "#F37320"
              group_by:
                func: avg
                duration: 15min
            - entity: sensor.envoy_YOURENPHASESERIALNUMBER_current_power_production
              type: column
              name: Produced
              color: "#01B4DE"
              group_by:
                func: avg
                duration: 15min
            - entity: sensor.net_power_kw
              transform: return x *-1 ;
              type: column
              name: Imported/Exported
              color: "#656569"
              group_by:
                func: avg
                duration: 15min
          card_mod:
            style: |
              .apexcharts-xaxis,
              .apexcharts-yaxis,
              .apexcharts-xaxis-tick,
              .apexcharts-gridline ~ line {
                opacity: 0.3
              }
      - type: custom:vertical-stack-in-card
        card_mod:
          style: |
            ha-card {
              background: transparent;
              box-shadow: none;
              overflow: visible !important;
            }
        cards:
          - square: false
            type: grid
            columns: 2
            cards:
              - type: custom:vertical-stack-in-card
                cards:
                  - square: false
                    type: grid
                    columns: 1
                    cards:
                      - entity: input_number.days_back
                        type: custom:numberbox-card
                        icon_plus: mdi:chevron-left
                        icon_minus: mdi:chevron-right
                        delay: 0
                        unit: Day
                        card_mod:
                          style: |
                            .padr,
                            .padl {
                              padding: 10px !important;
                            }
                            .cur-box {
                                flex-direction: row !important;
                            }
                            .cur-num {
                              display: flex;
                              font-size: var(--paper-font-body1_-_font-size) !important;
                              flex-direction: row-reverse;
                            }
                            .cur-unit {
                              font-size: var(--paper-font-body1_-_font-size) !important;
                              opacity: 1 !important;
                              margin-right: 5px;
                            }
                card_mod:
                  style: |
                    ha-card {
                      height: 100%;
                      display: flex;
                      align-items: center;
                      justify-content: center;
                    }
              - type: custom:vertical-stack-in-card
                cards:
                  - square: false
                    type: grid
                    columns: 1
                    cards:
                      - type: tile
                        entity: sensor.grid_dependence
                        color: grey
  - type: heading
    icon: mdi:lightning-bolt
    heading: Live Energy
    heading_style: title
  - type: custom:power-flow-card-plus
    min_flow_rate: 3
    display_zero_lines:
      mode: hide
    entities:
      battery:
        color:
          production: "#f37320"
          consumption: "#f37320"
      grid:
        color:
          production: "#01b4de"
          consumption: grey
        name: Importing
        icon: mdi:transmission-tower
        color_icon: consumption
        entity:
          consumption: sensor.power_import_kw
          production: sensor.power_export
      solar:
        entity: sensor.power_production_w
        icon: mdi:weather-sunny
        color: "#01b4de"
        color_value: true
        name: Producing
        kw_decimals: 3
        color_icon: true
      home:
        entity: sensor.power_consumption_w
        name: Consuming
        color_icon: battery
        color_value: battery
        secondary_info: {}
        circle_animation: false
        icon: mdi:home-outline
    card_mod:
      style: |
        #grid-home-flow circle,
        #solar-home-flow circle,
        #solar-grid-flow circle {
          stroke-opacity:0.3;
          stroke-width: 6 !important;
        }
        circle {
          stroke-width: 2 !important;
        }
  - type: custom:vertical-stack-in-card
    card_mod:
      style: |
        ha-card {
          background: transparent;
          box-shadow: none;
          overflow: visible !important;
        }
    cards:
      - square: false
        type: grid
        columns: 3
        cards:
          - type: custom:config-template-card
            variables:
              - states['sensor.net_power_rounded_kw']
            entities:
              - sensor.net_power_rounded_kw
            card:
              icon: >-
                ${vars[0].state >= '0' ? 'mdi:transmission-tower-import' :
                'mdi:transmission-tower-export'}
              type: custom:mushroom-entity-card
              entity: sensor.net_power_rounded_kw
              name: "${vars[0].state >= '0' ? 'Importing' : 'Exporting'}"
              icon_color: grey
          - type: custom:config-template-card
            entities:
              - sensor.power_export_rounded
            card:
              icon: mdi:white-balance-sunny
              type: custom:mushroom-entity-card
              entity: sensor.power_export_rounded
              name: Producing
              icon_color: "#01b4de"
          - type: custom:config-template-card
            entities:
              - sensor.power_import_rounded
            card:
              type: custom:mushroom-entity-card
              icon: mdi:home
              entity: sensor.power_import_rounded
              name: Consuming
              icon_color: "#f37320"
column_span: 1

Some issues (help is welcome):

  • The Imported kWh doesn’t match completely between the Enpahse App and the sensor sensor:power_import (@del13r do you know why?)
  • The Apex charts data is “squeezed” from 0:00, and this for a couple of hours, somebody know how to fix this? Here is a screenshot:
    screenshot-2024-11-18-16:25:56

If you have any suggestion or need any help, let me know, I’ll be happy to improve this guide

2 Likes

Hi, Are you accessing the data from the anaphase portal ? I am currently collecting the data this way but quite often I get a null response. You can connect directly to the gateway via a token but I’ve not managed to get this working

No, using the local data, connecting to my Gateway using the Enphase integration: