WTH, why do I need a complex template the get the number of persons home

I actually like this! Thanks!

And that’s an easy and trivial out of the box solution :slight_smile: Using it since the beginning for many automations

You can assign multiple devices trackers to a person in HASS now. I do not recall when this was added, but I use it right now. :slight_smile:

I moved to this over from a bayesian sensor to person and haven’t had any issues, it even simplified my implementation.

Yes, thanks, I’m aware that is possible and has been for a while. And I guess it works ok for many people. But it doesn’t have all the features of my custom integration, nor do I believe it works as well as mine. If anyone is interested: https://github.com/pnbruckner/ha-composite-tracker

Yes, you can, but only device trackers, no binary sensor or anything else. If you want to include other entities than device trackers you either need to use @pnbruckner custom integration or create some kind of workaround to push the state from the binary sensor to a device teacker like e.g. the device _tracker.see service or an MQTT device tracker.

@Burningstone Correct! I failed to mention that, but showed an example in another thread.

@pnbruckner I’m a big proponent of what works for you! So I hope no one thinks my intention is that I’m being critical of custom components or anything I have posted is remotely viewed as a criticism.

For me I love the challenge of making something work with in the constraints of the system. There have been many times where I could have more easily written a custom component, push data to MQTT and have my own program process it, used node-red, or used appdaemon, etc… But my goal was always to make every attempt to solve the problem in HASS. This has lead me down some interesting paths, up to and including investigating the code to really understand what is happening and running debug sessions.

I like a good puzzle… :slight_smile: Call me crazy, but it is really one of the major things that drives me. :slight_smile:

No problem. Staying within what I think is the intended scope of this topic, I was simply explaining why I wouldn’t want any new feature that came out of this to depend solely upon the existing person integration.

Maybe I should start a new WTH topic asking why the person integration can’t do what my custom integration can. (I did offer it as a starting point to the person integration, since it existed well before that was started, but I don’t think it was looked at.)

1 Like

I also wonder why we don’t have a device_tracker template. :slight_smile:

1 Like

Do you have a WTH on this currently I can upvote? I forgot about this until you mentioned it. I also have gone looking for this and was surprised it didn’t exist

Done!

I’m not sure if this warrants a new WTH post or not, but personally, I wish this post was titled:

“WTH, why do I need a complex template to get the number of entities with some attribute value?”

For example, in order to count the number of plant sensors reporting low moisture, I have to do this:

dehydrated_plants:
  friendly_name: "Plants needing water"
  entity_id: sensor.date
  value_template: >-
    {% set ns = namespace(count = 0) %}
    {% for plant in states.plant if 'moisture low' in plant.attributes.problem %}
      {% set ns.count = ns.count+1 %}
    {% endfor %}
    {{ns.count}}

I posted about this here.

This is a serious “WTH” to me, and is not limited to persons, or device trackers.

Post pseudo-code to demonstrate how you envision it would achieve the same result but with less code.

I’ve voted for this, as it would be nice to have something better than “zoning…” as the state for a zone, and not need to use a template at all, but a template to get the number of people at home can actually be relatively simple like this:

{{ states.person | selectattr("state","equalto","home") | list | count}}

that template is only complicated because you have to check to see if ‘moisture low’ is in plant.attributes.problem. If we mad a built in test called ‘contains’, that would shorten the template to

{{ states.plant | selectattr('attributes.problem', 'contains', 'moisture low') | list | count }}
2 Likes

Sure, I’ll take a stab at it.

I realize HA is limited by what JINJA allows, so the solutions I see are either a new count sensor:

sensor:
- platform: count
  name: "Dehydrated Plants"
  items_template: {{ states.plant }}  # Required
  filter_template: {{ 'moisture low' in item.attribute }}  # Optional

# Or more generic "math" or "aggregate" sensor
sensor:
- platform: math
  name: "Dehydrated Plants"
  operation: count # sum, concat, avg, min, max, etc
  items_template: {{ states.plant }}  # Required
  filter_template: {{ 'moisture low' in item.attribute }}  # Optional

Or create a new JINJA test called “contains”

dehydrated_plants:
  friendly_name: "Plants needing water"
  entity_id: sensor.date
  value_template: >-
    {{ states.plant | map(attribute='attributes') | map(attribute='problem') | select('contains','moisture low, conductivity low') | list | count }}

EDIT Or what Petro said. His template syntax is much prettier too.

Ha, jinx :wink:

1 Like

Ansible has that.

I recall trying to solve this in Jinja2 and every tantalizing lead led me to … an Ansible example!

https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html#test-if-a-list-contains-a-value

So if any developer wants kudos, please add a contains test.

I also want a new select attr that casts…

{{ states | select_attr_cast('state', 'int', '<', 47) }} 

Yes, that’s a sonvagun I encountered recently where I wanted to select all entities whose state value (a number) is less than a threshold. Sounds simple until one realizes state value are strings and have to be cast to integer before performing the test.

If I use this it gets all values below a threshold but I lose visibility of which entities have these values.

{{ states.sensor 
   | selectattr('attributes.device_class', 'eq', 'temperature')
   | map(attribute='state')
   | map('int')
   | select('lt', 24)
   | list
   }}

I believe iterating through the entities with a for-loop is the only way to get what I want (list of entity_ids).

{% set ns = namespace(t=[]) %}
{% for s in states.sensor 
            | selectattr('attributes.device_class', 'eq', 'temperature') 
            if s.state|int < 24 %}
  {% set ns.t = ns.t + [s.entity_id] %}
{% endfor %}
{{ ns.t }}

The more I think about it, the more I wonder if making map/filter/reduce operations for collections would have more universal value?

Something like this:

sensor:
- platform: aggregator
  type: filter
  name: "Sensors That Count Things"
  collection: {{ states.sensor }} 
  operation: {{ 'counter_' in item.entity_id  }}
  # returns [<sensor.counter_foo ...>, <sensor.counter_bar ...>]

- platform: aggregator
  type: map
  name: "Current Counter Sensor Values"
  collection: {{ states.sensor.sensors_that_count_things }} 
  operation: {{ item.state }}
  # returns [10, 0, 27, 5] (those sensor's states)

- platform: aggregator
  type: reduce
  name: "Sum of all counter sensors"
  collection: {{ states.sensor.sensors_that_count_things }} 
  operation: {{ prev + item.state }}
  # returns "42" (the sum of those states)

- platform: aggregator
  type: map
  name: "New Sensor Counts"
  collection: {{ states.sensor.sensors_that_count_things }} 
  operation: {{ item.state + 1 }}
  # returns [11, 1, 34, 6] (original states incremented by one)

Kinda funky. But would effectively allow users to create their own jinja “select” tests (like “contains”) on the fly