How to "count" how many power plug are on? HASS strategy on lowering power needs

Hi, I have the following appliances

4 A/C
Electric Pump
Electric Water heater
Electric oven
Electric washer
Electric dryer.

So basically 9 high consuming appliances

I am trying to accomplish that up to 5 concurrent appliances can be on simultaneously, when someone tries to turn on the 6th+ appliances either I get an error notification or better the appliance does not turn on (or even better it turns off some of the A/C temporarily).

Why? Because having extra available power in Italy is very expensive, trying to lower it in my home.

All power sockets are smart (Sonoff’s and Zwave Neo Coolcam switch.
Additionally I have Efergy Hub with current power consumption.

Any hints on the HASS strategy to follow?

If these sockets measure energy consumption you can create a template sensor that counts total consumption for all 9 devices and triggers an automation to notify you or switch off something if the total consumption exceeds a certain threshold.

If they do not measure consumption then create a template sensor that uses an if/then/else to count the number of ‘on’ switches. And use that to trigger an automation above a treshold of the count of switches.

Counting with templating is a bitch because of jinja’s scope ability. Using a template sensor may not work because of this. You could use the counter component:

Use an automation to count and increment the number of devices that are on. Then build an automation when things turn on. Check the counter, if the counter is greater than your limit, shut off what was just turned on:

- alias: turn off if over count
  trigger:
    platform: state
    entity_id: light.light1, light.light2, light.light3
    from: off
    to: on
  condition:
    condition: template
    value_template: "{{ states('counter.mycounter') | int >= 6 }}"
  action:
    - service: homeassistant.turn_off
      data_template:
        entity_id: "{{ trigger.entity_id }}"

If you have, or define, a group that contains these entities (in my example below I call it group.electrics), and they are all binary entities (i.e., their states are either ‘on’ or ‘off’), then you can use a template like this to get a count of the entities in that group that are on (just learned this recently! :slight_smile:):

{{ states|selectattr('entity_id','in',state_attr('group.electrics','entity_id'))|selectattr('state','eq','on')|list|count }}

Then you could have an automation like @petro suggests, but use this as the condition’s value_template instead:

condition:
  condition: template
  value_template: >
    {{ states|selectattr('entity_id','in',state_attr('group.electrics','entity_id'))
             |selectattr('state','eq','on')|list|count > 5 }}

This way you don’t need the counter or the automation that maintains it.

But as @metbril suggested, if you can use actual power consumption as a gauge, that would be better.

3 Likes

whato do you mean by that (jinja??)?

Claudio, just put this python script in the python_scripts folder and amend it to list your devices.
Also add the corresponding automation. (its in the file as well)

https://hastebin.com/otifeqilet.cs

Not mine, I pulled from some thread a while back.

It creates a sensor called sensor.lights_on

Jinja is the language that is used in templates within HA, see https://www.home-assistant.io/docs/configuration/templating/

This looks like a job for Appdaemon though, except that is just another learning curve :slight_smile:

I don’t think suggesting custom python scripts and appdaemon to novice users will make them understand what they are doing with their config.

I prefer to suggest solutions that are obtained through regular configuration.

You make a good point. The template I suggested, although clearly not trivial, I think at least, is pretty simple to use. However, it probably does require some explanation. Once you understand the pieces, it actually is pretty straightforward.

{{ states|selectattr('entity_id','in',state_attr('group.electrics','entity_id'))
         |selectattr('state','eq','on')|list|count }}

First, states is all the entity state objects in the system. (Basically each state object contains information about a given entity - its entity_id, its current value - i.e., its “state” - its other attributes, such as friendly_name, etc.)

That collection of state objects is then “filtered” (that’s what the | symbol means) down by a function that selects objects by their attributes. In this case, I use selectattr('entity_id','in',XXX), which only accepts state objects whose entity_id is in a list of entity_id’s.

The list is the XXX part, which in this case is state_attr('group.electrics','entity_id'). That is a function that provides the list of entity_id's that the group group.electrics contains.

So, putting these two together, we’re filtering the list of all state objects down to just the state objects that correspond to the entities defined by group.electrics.

Next we use the selectattr filter again, but this time we’re selecting state objects whose state attribute is eq (i.e, equal to) on.

Next we turn that collection into a proper list using the |list filter. So, at this point we have a list of state objects that correspond to entities that are defined by group.electrics that also happen to be currently on. Lastly we use the |count filter to get a count of the objects in the resulting list. I.e., the number of power switches that are on.

5 Likes

@metbril I neither agree nor disagree with your comment, but this is open and I’m sharing what’s out there. People should decide on their own their way.

1 Like

nice, saved this as a LiFo template for later use.:wink:
Cool.

Ive made this whats_on.py (helped by @petro) , using existing Groups, which makes it just a bit easier to use and understand:

switchEntities = 'group.iungo_switch_switches_template'
lightEntities = 'group.all_lights_only'
applianceEntities = 'group.iungo_switch_appliances_template'

filteredLightEntities = [ entity_id for entity_id in lightEntities if ' ' not in entity_id ]

def CountMyEntities(hass, entity_list, entity_state):
    cnt = 0

#  using a full list:  for entity_id in entity_list:
#  using groups in a [list] :  for group_entity in entity_list:
#                                 for entity_id in hass.states.get(group_entity).attributes['entity_id']:
    for entity_id in hass.states.get(entity_list).attributes['entity_id']:
        state = hass.states.get(entity_id)
        if state.state == entity_state:
            cnt = cnt + 1
    return cnt

switchesOn = CountMyEntities(hass, switchEntities, 'on')
appliancesOn = CountMyEntities(hass, applianceEntities, 'on')
lightsOn = CountMyEntities(hass, lightEntities, 'on') #if needed, use filteredLightEntities

totalOn = switchesOn + lightsOn + appliancesOn
whichIcon = "mdi:lightbulb-on-outline" if totalOn else "mdi:lightbulb-outline" # will evaluate "off" if totalOn == 0.
status = 'on' if totalOn else 'off' # will evaluate "off" if totalOn == 0.

hass.states.set('input_boolean.whats_on', status, { 
    'friendly_name': "What's On?",
    'icon': whichIcon,
    'lights_on': lightsOn,
    'switches_on': switchesOn,
    'appliances_on': appliancesOn,
    'total_on': totalOn,
    'extra_data_template':'{total_on} on'
})  

run the python automatically, or you could trigger it at startup, or at group change, you get the idea:

# Call Summary per 30 seconds

  automation:
    - alias: 'Setup Summary_whatson'
      id: 'Setup Summary_whatson'
      initial_state: 'on'
      trigger:
        platform: time
        seconds: 30
      action:
        - service: python_script.summary
        - service: python_script.whats_on

Thank you. much better than what I had. but Im getting “Traceback (most recent call last):
File “whats_on.py”, line 19, in
switchesOn = CountMyEntities(hass, switchEntities, ‘on’)
NameError: name ‘hass’ is not defined”

further expanding on the whatson.py im using this for all entity groups (lights here as an example):

##########################################################################################
# Lights:
# Badges images: /config/www/lights
##########################################################################################

lights_on = []
#show only lights, not light groups
#excluded = ['light.custom_group_for_group','light.custom_group_for_lights_2']

#total_lights_on = hass.states.get('input_boolean.whats_on').attributes.get('lights_on')
state = hass.states.get('automation.sense_lights_change')

if state:
    total_on = hass.states.get('input_boolean.whats_on').attributes.get('lights_on')
    for entity_id in hass.states.get(lightEntities).attributes['entity_id']:
        dt = state.last_updated + datetime.timedelta(hours=2)
        time = '%02d:%02d' % (dt.hour, dt.minute)

        if hass.states.get(entity_id).state is 'on': #and entity_id not in excluded
            lights_on.append(hass.states.get(entity_id).attributes['friendly_name'])

    if len(lights_on) > 0:
        picture = '/local/lights/hue_pl.png'
        message = ', '.join(lights_on)
        sensor_message = 'Lights on: ' + message
        lights_desc = '=- Lights on: {} -- {} since {}'.format(total_on, message,time)
        uom = 'Lights'

        if len(lights_on) == 1:
            uom = 'Light'
    else:
        picture = '/local/lights/bulboff.png'
        message= ''
        sensor_message= 'No lights on'
        uom = 'Lights'

    sensor_lights_desc = '{}'.format(sensor_message)

    hass.states.set('sensor.lights_badge', total_on, {
#        'custom_ui_state_card': 'state-card-value_only',
        'text': sensor_message,
        'unit_of_measurement': uom,
        'friendly_name': time,
        'entity_picture': picture
         })

giving me this in the frontend:

39

more_info on that:

50

whatson:

04

I use the same info (and then some) in a bigger Summary.py (text-only) (built on and inspired by @mviezzer here: Summary card and badges for people, devices and status (with python script and custom card)), showing a full summary of the Home (whats an assistant for
?)

16

and per sensor, some graphical embellishments are always cool:

34

Have fun!

1 Like

@Mariusthvdb got the whats_on working. really nice. thank you

Thanks a lot, will try this.

Now the count is solved, what is needed to do is, when counter above threshold, turn off the A/C (the only appliance you can turn off without big trouble like oven or washer).

Ideally it should turn off before those a/c in which the room is below certain C degree, and if all are above certain C degree the one with the highest difference with the room temperature (I have a smart temperature measurement in each room with Xiaomi sensor).
Then even more ideally turning them on/off circularly.

Does the above make sense? Is it very difficult to implement?

If anyone wonder why I go this route is because asking for a bigger load will cost me around 100 euros per month, like 1200 per year.

In winter time I have no need for this amount of available power, but it charges in the Sumner when I do need the additional power for 3 months only (A/C)

So basically pay 1200 euros for 3 months of additional power


Jinja is the language that templating is written in. For example counting in a loop is not possible in jinja, the only way to get around that is to use jinja filters like @pnbruckner suggested. That method is what I use but people tend to not understand it. Personally, if i was doing this, I would use that method because it’s a simple on/off without even dealing with a counter.

take it modularly:

create a template for a single switch: If temp below X, turn off ac.
see if it works.
then create for all swiches and put in 1 bigger automation, triggered by the individual entities (switches)

if that works, throw in a condition of the count number (if you still need that)

shouldn’t be to difficult :wink:

try understanding the difference between trigger (the one event that sets off the automation) and condition (the circumstances under which the automation holds)

Doing so makes all automations possible and logical.

And, always comeback here for help!

I will try to make it easier, otherwise I will never make it. Let’s start for automating only the 4 A/C and only at night (no use of other heacy appliances at night), and since I use a low consumption state (the 4 AC are inverter type) I just need to worry that NOT 3 or 4 are concurrently ON (1 or 2 are fine).

I would say to make 2 automations (my presence detectyion still is not working well), I will just manually call AUTOMATION 3 PEOPLE HOME AT NIGHT or AUTOMATION 4 PEOPLE HOME AT NIGHT

AUTOMATION 3 PEOPLE HOME AT NIGHT
I will need to rotate the ON/OFF (every, what 15 minutes?) between the 3 machine
If we call the 3 machine A, B and C
ON A,B (OFF C)
ON A,C (OFF B)
ON B,C (OFF A)
and then again
ON A,B (OFF C)
this for the whole night

AUTOMATION 4 PEOPLE HOME AT NIGHT
then I will need to rotate 4 A/C), let’s call them A, B, C, D
ON ABC (D off)
ON ABD (C off)
ON ACD (B off)
ON BCD (A off)
then again
ON ABC (D off)

does it make sense?

How to program this 
 complicated in yaml?