Update (ish) but not using python (rather using a jinja template):
I found a project in Italian that does exactly what I wanted to do, so I ported it to English: GitHub - mavenius/Power-Control-HomeAssistant: Progetto per gestire in modo automatico gli assorbimenti degli elettrodomestici per evitare distacchi di corrente
# priority-ordered list of entities to control (first is lowest priority and will be turned off first)
{% set list_entities =
[
'switch.yeti_battery_charger_relay',
'switch.converter_relay',
'switch.water_heater_relay',
'switch.fireplace_relay',
'climate.boys_bedroom_heater_thermostat',
'climate.master_bedroom_heater_thermostat',
'switch.dryer_relay',
'switch.clam_lights_relay',
'switch.side_deck_relay',
'switch.mini_fridge_relay',
'switch.dishwasher_relay',
'switch.microwave_relay',
'switch.washer_relay'
]
%}
##############################################################
# FROM THIS POINT DO NOT MODIFY
##############################################################
{% macro dict_device() %}
{% set output = namespace(sensor_power_off=[], general_entity_on=[]) %}
{
{%- for entity_on in list_entities if has_value(entity_on) -%}
{%- set output.general_entity_on = output.general_entity_on + [entity_on] -%}
{# retrieve all device entities #}
{%- set entities_devices = entity_on | device_id | device_entities -%}
{# Return entity_id of power sensor if there is one associated to the given device #}
{% set list_sensor_power = expand(entities_devices) | selectattr('state', 'is_number') | selectattr('domain', 'eq', 'sensor') | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', 'power') | map(attribute='entity_id') | list %}
{% set sensor_power = list_sensor_power[0] if list_sensor_power | count == 1 else 'unknown' %}
"{{ state_attr(entity_on, 'friendly_name') }}":
{
"entity" : "{{ entity_on }}",
"state" : "{{ states(entity_on) }}",
"sensor_power" : "{{ sensor_power }}",
"power" : "{{ states(sensor_power) if sensor_power != 'unknown' else 'unknown' }}",
"real_active" : "{{ 'on' if (not is_state(entity_on, 'off') and sensor_power == 'unknown') or sensor_power != 'unknown' and states(sensor_power) | int(0) > 15 else 'off' }}"
}
{%- if not loop.last %},{% endif %}
{% endfor -%}
}
{% endmacro %}
What is happening here is that list_entities
is the priority-ordered list of entities that we care about (mostly switches, but also climate objects that can be turned on or off.) In the dict_device
macro, it grabs the device Ids for each of the entities in the list, then gets the devices for those Ids. It then gets a power sensor associated with the corresponding device and pulls the current consumption from that.
Downstream, a few automations trigger off of this data plus some limits and present high-level usage so switches can be turned off in order to get below the limit(s) but that is beyond the scope of this thread. Feel free to see the linked github project for those details if you’re interested.