Groups behaviour of template sensors

how would I append this for an already defined group i have? group.motion.sensors…

I don’t follow, what do you mean?

meant this:

- platform: template
  sensors:
    motion_detected:
      friendly_name: "Motion detected by any sensor"
          value_template: >
            {% set group = [ states.sensor.guest_motion, states.sensor.kitchen_motion, states.sensor.lounge_motion, states.sensor.office_motion ] %}
            {% set output = group | selectattr('state', 'equalto', True) | list %}
            {{ output | length == group | length }}

set group = [etc] needs the separate entities, creating a list, but Id like to use a group here I already have. Group.motion_sensors. If I could use that group in this template sensor, I would not have to change the logic of the sensor, because the motion sensors wouldn’t be hard coded?

using the variable Last motion right now, but this could be a valid alternative.

I don’t think there is a way because of how jinja works. It’s really annoying but the looping scope causes issues when trying to access a groups objects directly and to have the functionality seen above.

The problem is here:

We need a list, we cannot use for loop because that is iterating through the list.

states.group.mygroup.attributes.entity_id returns a tuple of strings. In order to use the selectattr() filter, we need to have an actual object. Well it is not possible to get the tuple of strings into a tuple of objects in jinja without using a for loop.

So your only option is to hard code the objects in the value_template.

i see, thanks. So it is possible with a for loop? That might be another option to try then?
bw, if I fill out my individual sensor entities here, the value remains False, while waving actively :wink:

yep, you can use a for loop but that template won’t behave properly with a for loop because of the scope limitations of jinja. It’s pretty much a catch-22.

too bad really.
Well, will keep using this then, works fine:

automation:
# Update Last Motion variable
  - alias: "Update Last Motion"
    id: 'Update Last Motion'
    initial_state: 'on'
    trigger:
      platform: state
      entity_id:
        - sensor.corridor_motion_sensor
        - sensor.auditorium_motion_sensor
        - sensor.dining_table_motion_sensor
        - sensor.master_bedroom_motion_sensor
        - sensor.dorm_motion_sensor
        - sensor.frontdoor_motion_sensor
        - sensor.control_room_motion_sensor
        - sensor.attic_motion_sensor
      to: 'on'
    action:
      service: variable.set_variable
      data:
        variable: last_motion
        attributes_template: >
          {
                "history_1": "{{ variable.state }}",
                "history_2": "{{ variable.attributes.history_1 }}",
                "history_3": "{{ variable.attributes.history_2 }}",
                "history_4": "{{ variable.attributes.history_3 }}",
                "history_5": "{{ variable.attributes.history_4 }}"
          }
      data_template:
        value: "{{ trigger.to_state.attributes.friendly_name }}"

A you see, this also needs the sensors to be hardcoded, hence my desire to try differently.
and as mentioned, if I use these sensors in the template motion_detected, nothing happens and the value remains False…having changed to selectattr(‘state’, ‘equalto’, ‘on’) since my sensors have that state

check what @dale3h has come up with:

{{ dict((states|selectattr('entity_id', 'in', state_attr('group.entrypoints', 'entity_id'))|list)|groupby('state'))['open']|map(attribute='name')|list|join(', ') }}

changed into:

{{ dict((states|selectattr('entity_id', 'in', state_attr('group.philips_motion_sensors', 'entity_id'))|list)|groupby('state'))['on']|map(attribute='name')|list|join(', ') }}

or

      {{ dict((states|selectattr('entity_id', 'in', state_attr('group.all_lights_only', 'entity_id'))
      |list)|groupby('state'))['on']|map(attribute='name')|list|join(', ') }}

so cool.

I did not know that ‘in’ was an option for selectattr. Nore did I think about using it against the state object… so with that being the case, this is what the jinja would look like instead of hard coding the motion devices.

- platform: template
  sensors:
    motion_detected:
      friendly_name: "Motion detected by any sensor"
          value_template: >
            {% set group = states | selectattr('entity_id', 'in', state_attr('group.motion', 'entity_id')) | list %}
            {% set output = group | selectattr('state', 'equalto', True) | list %}
            {{ output | length == group | length }}

Thanks @dale3h, makes this easier.

1 Like

keeps giving False…

btw the @dale3h template acts a bit unexpectedly in the frontend:

while showing this correctly in the dev-tools:

it shows only this in the frontend:

4654

same goes for the motion sensors… only one showing, and with reasonable amount of lag, so it skips sensors on my walk to the espresso machine :wink:

The example above is to see if all motion sensors are tripping. Translating that to ‘everyone being home’ requires True to change to ‘Home’ or ‘home’ (not sure which one).

- platform: template
  sensors:
    everyone_home:
      friendly_name: "Sensor that tells me if Everyone is home"
          value_template: >
            {% set all_people = states | selectattr('entity_id', 'in', state_attr('group.family', 'entity_id')) | list %}
            {% set home_people = all_people | selectattr('state', 'equalto', 'home') | list %}
            {{ all_people | length == home_people | length }}

Sure, but I have changed that accordingly, as in the template shown here.

Neither work

Sorry, Typo, the second line needs to use all_people object to filter the list.

- platform: template
  sensors:
    everyone_home:
      friendly_name: "Sensor that tells me if Everyone is home"
          value_template: >
            {% set all_people = states | selectattr('entity_id', 'in', state_attr('group.family', 'entity_id')) | list %}
            {% set home_people = all_people | selectattr('state', 'equalto', 'home') | list %}
            {{ all_people | length == home_people | length }}

Here’s my Test with lights:

{% set b_states = states | selectattr('entity_id', 'in', state_attr('group.basement', 'entity_id')) | list %}
{% set b_on = b_states | selectattr('state', 'equalto', 'on') | list %}
{{ b_states | length }} Basement lights
{{ b_on | length }} Basement lights are on
{{ b_states | length == b_on | length }}

Everything Off:


1 Item On:


Everything On:

1 Like

wait a minute, this is to say All are home, not anyone…? in that case, the false is correct :wink:

I’d need it to check if, and if, who is home…

cross posted:

got it:

now list the items that are on…

1 Like

should just be using the filters that @dale3h used in the example you posted.

for name:

{{ home_people | map(attribute='name') | list | join(', ') }} 

{{ lights_on | map(attribute='name') | list | join(', ') }} 

for entity_id:

{{ home_people | map(attribute='entity_id') | list | join(', ') }}

{{ lights_on | map(attribute='entity_id') | list | join(', ') }} 
2 Likes

ok will check.
Would you know how to get that list to show from top to bottom in the frontend? right now it fills up the sensor line, obscuring the name of the sensor, since it populate that line going left…

51

o yes, wow.

only the first in the list. hmm, how to give that a dash?

btw, besides being a great online checker tool, this might be even more useful for an Offline warning tool:

{{ dict((states|selectattr('entity_id', 'in', state_attr('group.critical_hubs', 'entity_id'))|list)|groupby('state'))['offline']|map(attribute='name')|list|join(', ') }}

Simple, just add it before the code!

 - {{ lights_on | map(attribute='name') | list | join('\n - ') }}
1 Like

right. duh. feeling soo tired.

Lol, We’ve all been there before…