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

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?

Since you have an energy meter, would it not be more accurate to just adjust the on devices when energy consumption hits a certain level. You need to decide the logic for what gets turned off and for how long etc.

Sure, but I already know that with 2 A/C is ok. With 3+ problems.

The logic I wrote in post, 2 ON together and every 15-20 minutes (I have to decide which the best interval) change the 2 that are ON

well if you really want an easy and fail save way how to count whatever you want, here’s a short Python_script, I’ve just edited for you to count family members in my group.family.

if you want, you can leave out all the other counters, otoh, you might find them useful, for counting your ac’s…:wink: just fill in the correct group, and adapt the wording in the script.

you throw this script in the folder /config/python_scripts and point your configuration to use python simply by adding:

python_script:

heres the script whats_on, creating an input_boolean (originally was called anything on, and if anything on the boolean switched on, of not switches off)

38

save this as whats_on.py:

familyEntities = 'group.family'
switchEntities = 'group.switches'
lightEntities = 'group.all_lights'
applianceEntities = 'group.appliances'

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
familyHome = CountMyEntities(hass, familyEntities, 'home')
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,
    'family_home': familyHome,
    'lights_on': lightsOn,
    'switches_on': switchesOn,
    'appliances_on': appliancesOn,
    'total_on': totalOn,
    'extra_data_template':'{total_on} on'
})

You then can play with the attributes of this input_boolean in your automations, or even template_sensors.

45

{% if states.input_boolean.whats_on.attributes.family_home <= 3 %} scenario 1
{% else %} scenario 2
{% endif %}

if you want a yaml template, and dont want to use Python, use this:

  {{ states|selectattr('entity_id','in',state_attr('group.family','entity_id'))
           |selectattr('state','eq','home')|list|count +
     (1 if is_state('input_boolean.guests','on') else 0) }}

or spit out the names of people home:

value_template: >
  {% if is_state('group.family', 'home') %}
    {{ dict((states|selectattr('entity_id', 'in', state_attr('group.family', 'entity_id'))
    |list)|groupby('state'))['home']|map(attribute='name')|list|join(', ') }}
  {%else%}
    Nobody home
  {%endif%}

have fun!

1 Like

Many thanks, will have a look at it, very interesting although a bit complicated for me, so I will use it in second phase

Right now I wish to start with the automation / script first (without counting, for night use)