Updating number of people at home

I have the below template which I’m using to keep a count of the number of people at home at any one time in order to trigger home and away mode automations:

sensor:
  - platform: template
    sensors:
      number_people_home:
        entity_id:
          - sensor.time
        friendly_name: Number of People Home
        value_template: >
          {{ states.person|selectattr('state','equalto','home')|list|length }}

I’m using the sensor.time as the entity in order to trigger the template to update once a minute. This works but there is up to a minutes delay before the count gets changed. I’m just wondering how to do this better so it gets triggered quicker (I couldn’t see a unix time sensor which would allow me to count seconds) or another way I can accomplish the same thing?

2 Likes

Add the persons/device_trackers to the entity_id’s and it will update on every state change.
BTW, what kind of presence detection are you using that updates so fast, and why?

1 Like

I was hoping, purely from the point of view of limiting the number of places to update when people get added and removed to not have to list the entity id’s and just count the persons list instead but guess thats the way it has to go.

I’m using either the ping platform for mobile phones or BLE beacons on keyrings for guests/house sitters. I find in the logs that when someone arrives home, the device tracker spots it fairly quickly and the log updates, but the number_people_home template doesn’t update the number of people home until the top of the next minute. That means it can take up to a minute for automations triggered by someone arriving home to trigger after the time it takes the device tracker to spot it so that starts to feel a little slow. Its the arriving home part that is annoying, the leaving home doesn’t trigger for a few minutes because of the consider_home setting which is fine but its the arriving that I’d like to speed up.

If you have door sensor, maybe use it instead of sensor.time ?
I guess people would go thru the door, so update of this sensor would trigger update of the template.

Thats not a bad idea, I might look at that in the future.

Since making this change, something a little strange has happened with my home automation, it starts like this:

- alias: Home Mode
  trigger:
  - entity_id: sensor.number_people_home
    platform: numeric_state
    above: 0

Now in my mind and from checking on the docs, this should fire when sensor.number_people_home rises above 0. However this is also firing when the number drops from 3 to 2, 2 to 1 etc. My understanding of these triggers is that it should only be firing when the number change crosses through the defined threshold value

Fixed the above with the below, although I don’t truly understand why its started happening now:

condition:
  - condition: template
    value_template: >
      {{ trigger.to_state.state|int > trigger.from_state.state|int }}

The number of people home sensor is an altered version based on this thread:

I think you may need to take a close look at the states of your person entities and sensor.number_people_home. The numeric_state trigger will only (normally) fire when the numeric value of the entity (in this case with above: 0) changes from zero or below to above zero. it will not fire when the value changes between values above zero.

I say “normally” because it behaves slightly different when the entity changes for the first time. If the numeric value is above zero it will fire. (I.e., for that first state change it doesn’t have to have been a value of zero or below.) After that it remembers it has fired and will only fire again when the value changes to zero or below and then back to above zero.

Another “abnormal” situation is when the entity changes to a state that cannot be interpreted as a number. It will then “forget” that it has already fired and go back to the scenario mentioned above. Meaning if, say, the entity goes from “3” to “unknown” or “unavailable” and then to “2”, the trigger will fire. I suspect something like this is happening to you.

FWIW, I still use this exact method and it works perfectly. I use it with device_tracker entities instead of person entities, but I don’t think that should matter. Also, I specifically list all the device_tracker entity IDs in the entity_id option of the template sensor, just as @VDRainer suggested you should do.

I agree you shouldn’t have to do that, but that’s the way it works right now.

BTW, you fix of adding that condition is not really a fix. That just means it will run whenever the value increases, so I’m guessing it’s running when the value goes from 0 to 1, then from 1 to 2, then again from 2 to 3, etc.

Thats interesting, so the question is, do you get these abnormal triggers or are you saying these abnormal states only exist with the person entities?

BTW, you fix of adding that condition is not really a fix. That just means it will run whenever the value increases, so I’m guessing it’s running when the value goes from 0 to 1, then from 1 to 2, then again from 2 to 3, etc.

With it removed, the home mode automation triggers with a drop from 3 to 2 etc which this prevents. I know what you mean, certainly I want it to act when going from 0 to 1, but it should as you say, fire when going from 1 to 2 etc. I’m finding its not so it seems in that case, the automations trigger of above: 0 is not being fulfilled.

I’m saying you need to fully understand what your person entities are doing first, before you fix any problems caused by them. Otherwise you’re just guessing.

For those who need this count but relying on a group of persons:

sensor:
  - platform: template
    sensors:
      number_cool_persons_at_home:
        entity_id:
          - group.cool_persons
        friendly_name: 'The coolest guys at home'
        value_template: >
          {{ expand(states.group.cool_persons)|selectattr('state','equalto','home')|list|length }}

This could also be applicable on groups of lights, switches, etc, by just changing the groups and the 'home' to the desired state, such as, 'on' or 'off'.

EDIT: See this first: Updating number of people at home

2 Likes

This won’t work. It should work, starting with release 0.110, if you remove the entity_id option. But even so, it probably still doesn’t work due to a bug reported in Issue #35872. And it still may not work because of how you have the template written.

The problem is that a template sensor needs to know which entities to monitor for changes. You’ve told it (via the entity_id option) to update only when group.cool_persons changes. However, that only changes (by default) when the people in the group go from all not home to at least one home and vice versa. It doesn’t change when it goes from one person home to two people home, etc.

So, if you remove the entity_id option, it will attempt to extract the entities in the group and monitor them. However, the bug prevents that from working in all cases. Also, the method used to determine a group is expanded (i.e., a regular expression) may not work given how you have written the template.

So, bottom line, once the bug is fixed, then this should work:

sensor:
  - platform: template
    sensors:
      number_cool_persons_at_home:
        friendly_name: 'The coolest guys at home'
        value_template: >
          {{ expand('group.cool_persons')|selectattr('state','equalto','home')|list|length }}

@123 would you agree?

2 Likes

Yes, latter on I figured that the entity_id needs to refresh timely, otherwise the sensor will not be updated.

Since a few days ago, this is running flawlessly:

imagem

sensor:
  - platform: template
    sensors:
      number_cool_persons_at_home:
        entity_id: sensor.time
        friendly_name: 'The coolest guys at home'
        value_template: >
          {{ expand(states.group.cool_persons)|selectattr('state','equalto','home')|list|length }}

2 Likes

Yes; excellent explanation of the issue (as usual). :+1:

The PR that fixes the bug is making progress but I get the impression it may not make the cut for inclusion in 0.111. Hopefully it will be in 0.112.

The use of sensor.time effectively makes it polling-based instead of event-based. Every minute, Home Assistant evaluates the Template Sensor which represents more overhead than the alternative. In addition, the arrival of a second person is not reported until the next polling cycle which, worst case, can be about a minute later.

To be fair, the “overhead” I mentioned isn’t a huge burden. Behind the scenes, there are already things being monitored on a periodic basis. It’s just that when given the option of choosing between polling and event-based systems, event-based involves far less needless chatter.

1 Like

OK, that seems to be the next approach for this kind of sensors. But, until that said bug is corrected, the event-based seems to me that will wait until a more reliable solution, based on B/C. :wink:

Thanks to both for shining some additional light into this topic!

A simple alternative (until the PR is merged) is to specify the entities directly within the template, rather than use a group or sensor.time. This Template Sensor will be evaluated the moment any of the three person entities changes state.

sensor:
  - platform: template
    sensors:
      number_cool_persons_at_home:
        friendly_name: 'The coolest guys at home'
        value_template: >
          {{ [states.person.first, states.person.second, states.person.third]
             | selectattr('state', '==', 'home') | list | count }}

Anybody know how to add another list with another filter? I tried several things but failed. I want to also check if input_boolean.guestmode is ‘on’. So it would count as +1. Meaning total number of people at home plus 1 if guest mode is on.

sensor:
  - platform: template
    sensors:
      number_cool_persons_at_home:
        friendly_name: 'The coolest guys at home with guests'
        value_template: > 
          {% set count = [states.person.first, states.person.second, states.person.third] | selectattr('state', '==', 'home') | list | count %}
          {% if is_state('input_boolean.guestmode', 'on') %}
            {{ count + 1 }} 
          {% else %}
            {{ count }}
          {% endif %}
1 Like

Thanks a lot @FrancSon I was trying all sorts of additions. + etc. Guess that didn’t work :wink: