Passive Zones not detecting people in them?

The template editor will show the count at the end. Did you copy the entire template?

Yep - there is no number at the end.

If i remove the - (so {{ ns.count }}) I get 0 outputted at the end (which I think it should be 2?)

EDIT: Yes, it seems down to the dash - without it I get a value (and can flip the < to get 2)

lol, dude the 0 is at the end, the - just removes the whitespace.

image

Anyways use this template, probably order of operation.

      {%- set zone = 'zone.my_city' %}
      {%- set radius = state_attr(zone, 'radius') / 1000 %}
      {%- set ns = namespace(count=0) %}
      {%- for person in states.person if person.attributes.latitude is defined and person.attributes.longitude is defined %}
        {%- set ns.count = ns.count + (0 if distance(zone, person.entity_id) > radius else 1) %}
      {%- endfor %}
      {{- ns.count }}
1 Like

oh, oops… learn something new every day!

Anyway - that rejigged code seems to have done the trick!

Thank you so much for your help :slight_smile:

I found this some months ago and I use it to define whether or not we are in our “home region” - if we are then automations run, if we’re not the house goes to sleep. I just spent some time trying to figure out why the region count was 0…and then I remembered than there was some dumb limitation that if you were home then you couldn’t be counted in a passive zone. Time wasted. :frowning:

But, because it bothered me (a lot) and because when we ar ein home we are in region I’ve tweaked it to include the home count - that way when someone goes from “in region” to “home” the count doesn’t change…

- sensor:
  - unique_id: wellington_region_presence_count
    name: Wellington Region Presence Count
    state: >
      {%- set zone = 'zone.wellington_region' %}
      {%- set radius = state_attr(zone, 'radius') / 1000 %}
      {%- set ns = namespace(count=0) %}
      {%- set home = states('zone.home') | int %}
      {%- for person in states.person if person.attributes.latitude is defined and person.attributes.longitude is defined %}
        {%- set ns.count = ns.count + 0 if distance(zone, person.entity_id) > radius else 1 %}
      {%- endfor %}
      {{- ns.count + home}}

Now the number only changes if someone literally leaves the region…

I know it’s an old thread but thought it might be useful…and…in my case I no longer need to test if anyone is “home” OR if anyone is “in region” as the updated “in region” now does it all!

1 Like

Thought I’d share a slightly different approach - I removed the need for a new zone and just set a radius from my home. I was looking for a sensor I could use to know we were a distance from home to set the house in to away mode.

- sensor:
    - name: Home region count
      unique_id: <some unique id>
      icon: mdi:home
      state: >
        {%- set zone = 'zone.home' %}
        {# Distance in km #}
        {%- set radius = 7.75 %}
        {%- set ns = namespace(count=0) %}
        {%- for person in states.person if person.attributes.latitude is defined and person.attributes.longitude is defined %}
        {%-   if distance(zone, person.entity_id) < radius %}
        {%-     set ns.count = ns.count + 1 %}
        {%-   endif %}
        {%- endfor %}
        {{- ns.count }}

I get the passive zones thing and use them successfully but what about the situation where you need to know if anyone is in the passive zone?

The zone has to be passive because it can overlap Home zone and cause people to appear not home

So, zone.car is a dynamically created zone based on the car device_tracker.
(Clearly the car can be at home so the zones can overlap.)

Is there any way this automation can be made to work?

  - alias: Warn If Doors Unlocked When On Holiday
    id: warn_if_doors_unlocked_when_on_holiday
    trigger:
      - platform: state
        entity_id: sensor.car_door_lock_status
        to: unlocked

    condition:
      #=== Check holiday mode is on
      - condition: state
        entity_id: binary_sensor.holiday_mode
        state: 'on'

      #=== Check nobody is at the car
      - condition: numeric_state
        entity_id: zone.car
        below: 1

    action:

Make a trigger based template sensor for people entering and leaving the zone. enter → on, leave → off.

I was hoping I’d missed something and didn’t have to create more sensors especially as I would have to remember to add to the template for any other people I might want to track in this zone at a later date.

But more importantly I’m not sure that is useful because at HA start the sensor is unknown.

template:
  - trigger:
      - platform: zone
        entity_id: person.one
        zone: zone.car

      - platform: zone
        entity_id: person.two
        zone: zone.car

    sensor:
      - name: Car Zone Occupied
        unique_id: car_zone_occupied
        state: >
          {% if trigger.event == 'enter' %}
            {% set occupants = occupants + 1 %}
          {% else %}
            {% set occupants = occupants - 1 %}
          {% endif %}
          {{ occupants }}

just add a homeassistant start trigger if you want to calculate it at start. If you want counts, you should probably just use a counter with an automation instead of a template entity.

I’ve found my way here after falling afoul of the same limitation with passive zones. I humbly suggest that where the UI says “Passive Zones can be used in automations”, it actually means “Passive Zones can be used as triggers”.

Before I switch my “near home” passive zone to an active one[1], can someone explain the reason why passive zones don’t have a count? Can a person only be in a single zone or something? How does HA choose if a person is in two active zones? Undefined?

[1] I’ll probably use a proximity distance instead.

Because that’s just how they were built when zone count changes were made.

For active zones, yes.

IIRC it chooses the closest zone.

1 Like

I know this is an old-ish thread but it’s very helpful and I’d like to include a correction. I’m new to HA and maybe in the past there was a limitation that did not count people in a passive zone but it does not apply to the approach of this thread. The code provided @ChirpyTurnip is not accurate and it will result in an incorrect count. The are 2 issues:

  1. People that are home still have lat and lon defined and will be counted by the “for” loop
  2. Count of persons in the home zone will be added, even if they were already counted
    But the count will not be double, it will be off by 1 because of this line:
{%- set ns.count = ns.count + 0 if distance(zone, person.entity_id) > radius else 1 %}

As @petro specified, it should be:

{%- set ns.count = ns.count + (0 if distance(zone, person.entity_id) > radius else 1) %}

So, no need to count zone.home, just use the code provided by @petro

I added the missing brackets, but otherwise there is no difference that I can see?

I’m definitely not out count wise and I don’t think I have a little correction factor in my config somewhere…before and after adding the brackets I have exactly the same number of people being reporting in region / at home. If the code change was going to make a difference then I would have expected to be out now, but so far so good!

You’re doing well though if you’re already this deep down the rabbit hole! :slight_smile:

I have 2 trackable people in my HA setup and when I use your code, the passive zone count is 4 when we are both home or 2 when we are not but still in the passive zone. With Petro’s code it’s always 2. I’m not sure how you get the same count whether home or not as you can easily test for either method and see the double counting.

It beats me…I have four people I track - right now one is home (and it says one is home), two are at work (me too today unfortunately) but together these still say there are three in region, and my fourth person is very far away so they do not show up at all.

My code now matches petro’s I think:

- unique_id: "region_presence_count"
    name: "Region Presence Count"
    state: >
      {%- set zone = 'zone.home_region' %}
      {%- set radius = state_attr(zone, 'radius') / 1000 %}
      {%- set ns = namespace(count=0) %}
      {%- set home = states('zone.home') | int %}
      {%- for person in states.person if person.attributes.latitude is defined and person.attributes.longitude is defined %}
        {%- set ns.count = ns.count + (0 if distance(zone, person.entity_id) > radius else 1) %}
      {%- endfor %}
      {{- ns.count + home}}

But even though I have made the change to correct the brackets the behaviour is unchanged.

If this did make a material difference then any correction factor I might be applying elsewhere would result in an incorrect result for me now since the inputs have changed - but there are has been no change. My yaml is very modular and split across many files by functional area so that all the code for each ‘thing’ is generally fully independent.

I do not know why you might be getting odd results…did you leave it long enough between making changes to verify that it actually updated correctly? Were you using developer tools to force states? If you’re tracking users at home via Wifi are their phones using phone mac (versus random mac) and all they on fixed IP addresses so that they can get show up twice due to stale data?

There are many reasons why counting people can be problematic.