An automated pie chart of all power consumers in my home

I created a pie chart that shows the current power usage of all devices in my home. It automatically includes all power meters I have, so no painfully keeping a list of device ids up-to-date any more. I thought I share with you all how I did it. There may be other ways and there may be better ways. This is just how I did it.

Let’s start with the end result. When you hover the mouse over one of the parts of the chart, it’ll show you that part’s name plus current usage.
image

Here’s the yaml for the card. I’ll explain some of the details later on.

type: custom:auto-entities
card:
  type: custom:apexcharts-card
  chart_type: pie
  header:
    show: false
  apex_config:
    legend:
      show: false
  update_interval: 30sec
sort:
  method: name
entities:
  - entity: sensor.utilities_unmetered_power
filter:
  template: >
    {{ states.sensor  | rejectattr('attributes.device_class', 'undefined')  |
    selectattr('attributes.device_class', 'eq', 'power')  |
    rejectattr('attributes.unit_of_measurement', 'undefined')  |
    selectattr('attributes.unit_of_measurement', 'in', ['W', 'kW'])  |
    rejectattr('entity_id', 'in', area_entities('energie'))  |
    map(attribute='entity_id')  | list() }}

As you can see I’ve used some custom HACS components for this. If you want to use my code you’ll need these components installed. The instructions how to install them can be found with each repository.

The chart automatically includes all entities that have a device_class: power and have a unit_of_measurement of either ‘W’ of ‘kW’. However not all ‘power’ entities in HA are consumer entities. Some are totals like for example my whole-home energy meter and solar panel’s entities. Such entities I want to exclude from the chart (and other lists of consumers), so I put all of these into an ‘area’ called ‘energie’ (should actually better have used ‘utilities’, but I realized this only after I had already created several automations). Now when I find an entity is incorrectly included as a consumer, all I have to do is move that entity (or the device as a whole) into the ‘energie’ area and it will be excluded from all consumer lists and thus from this chart too.

Because it’s nearly impossible to have metering on all devices in my home and I still want to the chart to show the full 100% of all power used in my home, I created one additional template sensor that has the total of unmetered Watts as its value: sensor.utilities_unmetered_power. This one sensor I always add by default to the graph. It is a template helper with below template. The template again uses the same mechanism of selecting all power sensors, plus it uses one additional sensor.envoy_121831009724_current_power_consumption that has the total power used by my home (i.e. 100%) as measured by my solar installation integration (enphase) (*).

{% set usage = float(states('sensor.envoy_121831009724_current_power_consumption')) %}
{% if state_attr('sensor.envoy_121831009724_current_power_consumption', 'unit_of_measurement') == 'kW' %}
{% set usage = usage * 1000 %}
{% endif %}
{% set sensors = states.sensor
      | rejectattr('attributes.device_class', 'undefined') 
      | selectattr('attributes.device_class', 'eq', 'power') 
      | rejectattr('attributes.unit_of_measurement', 'undefined') 
      | rejectattr('entity_id', 'in', area_entities('energie'))
      | rejectattr('state', 'in', ['unknown', 'unavailable']) %}
{% set watts = sensors
      | selectattr('attributes.unit_of_measurement', 'eq', 'W')
      | map(attribute='state')
      | map('float')
      | list()%}
{% set kilowatts = sensors
      | selectattr('attributes.unit_of_measurement', 'eq', 'kW')
      | map(attribute='state')
      | map('float')
      | list()%}
{{ max(usage - (watts|sum + 1000.0 * kilowatts|sum), 0) }}

Please note that each power sensor in HA updates at its own interval. i.e. There will be temporary fluctuations where one sensor has updated while another hasn’t yet. There can thus be for example negative unmetered values. I added a max( …, 0) to the template such that the unmetered value can not go below 0 to suppress the effect of such temporary negative value on my chart. The unmetered value can therefor not be exact. It is just the difference between the total and the sum of all consumers at any one point in time.

(*) My solar integration gives me the total usage of my home. If yours doesn’t, you can still calculate total usage of your home by creating template sensor that adds the Watt (W) values for your solar to the grid-in, then subtracts the value for grid-out. f.e.:

template:
  - sensor:
      - name: power_used
        unique_id: "power_used"
        unit_of_measurement: W
        device_class: power
        state_class: measurement
        state: >
          {%- set src = 'sensor.electricity_meter_power_consumption' %}
          {%- set grid_in = (states(src) | float * 0.001 if is_state_attr(src, 'unit_of_measurement', 'kW') else states(src) | float * 1.0 if is_state_attr(src, 'unit_of_measurement', 'W') else 'unknown') %}
          {%- set src = 'sensor.electricity_meter_power_production' %}
          {%- set grid_out = (states(src) | float * 0.001 if is_state_attr(src, 'unit_of_measurement', 'kW') else states(src) | float * 1.0 if is_state_attr(src, 'unit_of_measurement', 'W') else 'unknown') %}
          {%- set src = 'sensor.envoy_121831009724_current_power_production' %}
          {%- set solar = (states(src) | float * 0.001 if is_state_attr(src, 'unit_of_measurement', 'kW') else states(src) | float * 1.0 if is_state_attr(src, 'unit_of_measurement', 'W') else 'unknown') %}
          {{ (solar + grid_in) - (grid_out) }}
        availability: >
          {{ has_value('sensor.electricity_meter_power_consumption') 
              and has_value('sensor.electricity_meter_power_production') 
              and has_value('sensor.envoy_121831009724_current_power_production') }}
4 Likes

This looks very interesting and exactly what I am looking for. Please forgive my ignorance but where should I put those code blocks? I haven’t ever customized a dashboard in HA so please bear with me

  • Edit the dashboard that you want to add the card to (in the latest HA version you click the pencil icon in the right top, in previous versions you had to click the three dots in the top, then select ‘edit dashboard’).

  • Click the blue “+ ADD CARD” button in the bottom.

  • Scroll down to the bottom of the available card types and select “Manual”.

  • In the “Card configuration” window, paste the text from the 1st text box into this card, overwriting the text “type: ‘’” that is in there by default.

  • In the simplest form, remove the line with - entity: sensor.utilities_unmetered_power. This sensor will only be available after you’ve also added the template helper from the 2nd text box.

Once you’ve managed to add the chart without the unmetered power sensor, let me know and I’ll add instructions for adding that sensor too.

1 Like

Thank you very much, that worked beautifully!

You got both the pie chart and the unmetered_power sensor working? Great!. If I may ask, did you use a whole-home energy meter (like my enphase solar system’s lifetime_energy sensor) or did you use the calculation of (grid-in + solar) - grid-out for the usage calculation?

I used a whole-home energy meter (Zemismart SPM-02).

Do you know whether it’s possible to have a similar chart with consumed energy (kWh), like in the default “Energy” dashboard, instead of instantaneous power (W)?

Yes, theoretically this should possible. However, energy readings (kWh) are stored differently in the long-term statistics table than power readings (W) and the apex-charts diagram can’t read such energy readings at the moment. Several requests have been made to add support for them, and from the check-in comments a version even seems to have been built into a dev stream, but it looks like the project has been abandoned since then as no new development has been done on it for some time already. So in practice it is not available in the released product and I have not been able to do this yet.

This is amazing, thanks a lot for sharing!

Instead of using an area, I actually used a label, and integrated it like: 'entity_id', 'in', label_entities('ignoreforcurrentpowerusage')

1 Like

I have my car charger in here which is in kW. However it isn’t converting this into W, so in terms of amount of the pi chart it thinks it’s 7W, not 7000.

That’s an issue in the apexcharts-card: I don’t have any sensors that report in kW, so I did not notice this. If you really want to have kW values automatically converted into W values in the chart, you can try creating an issue in github (https://github.com/RomRider/apexcharts-card/issues). See if you can have the developer agree with you and fix it for you.

As an alternative, since it’s only 1 sensor anyway, you can work around it by creating a helper template sensor that takes the value of the original sensor and converts it from kW into W (i.e. multiply by 1000). Plus hide the original sensor from the pie chart, f.e. by setting it’s area to the ‘energy’ area like I did in my examples.

The helper is easily created from ‘Settings’ → ‘Devices & services’ → ‘Helpers’. There click the blue button “+ CREATE HELPER” in the bottom. Select “Template”, “Template a sensor”. Then fill the fields as you like:

  • Name: enter a name for the converted sensor (can be exactly the same as the original sensor, the device id will be made unique)
  • State template: enter {{ states('sensor.your_original_sensor_name_here') | float * { 'W' : 1, 'kW' : 1000, 'MW' : 1000000 }[ state_attr('sensor.your_original_sensor_name_here', 'unit_of_measurement')] }}
  • Unit of measurement: select ‘W’
  • Device class: select ‘Power’
  • State class: select ‘Measurement’
  • Device: select the same device that has the original sensor to have the new sensor be included with that device. If you leave this empty the sensor will still be created as an entity and will work just as well, it is just not included with a device.
    Check that the Preview area in the bottom shows the value converted into W. If it doesn’t, correct the appropriate fields above, then click “SUBMIT”.
    In the ‘Success!’ window you can select an area for your new sensor, then click “FINISH”.

All that remains is to exclude the original sensor from the set of sensors to include in the pie chart. An example how to do that is already in my opening topic.

Please note that the template needs to be start with 2 {{ and end wit 2 }} characters. For me the text above only showed 1 { although I did type 2. Despite what is shown, it really needs to be 2 of them.