Guidance with Groups of Binary Sensors

Kinda makes more sense to use a Binary Sensor if it will be a Binary Sensor ?

1 Like

Can’t argue with that … but changing it to a Template Binary Sensor doesn’t explain why it originally failed when it was defined as a Template Sensor.

I carried out an experiment and was able to replicate the error message Literoya received. The answer is actually quite simple. Although both Template Sensor and Template Binary Sensor support the device_class option, they don’t share the same types of device_class.

The available types for a sensor are listed here:

What you won’t find in that list is window. That’s a type of device_class only valid for binary_sensors.

That’s why switching from Template Sensor to Template Binary Sensor eliminated the error message. A window device_class is valid for binary_sensors, not sensors.

1 Like

I offer you yet another way to achieve the same thing.

In this version, you specify the binary_sensors you wish to monitor (windows) within the value_template. You don’t need a group and you don’t need to list the binary_sensors in entity_id.

  - platform: template
        friendly_name: 'Window Status'
        device_class: window
        value_template: >
          {% set sensors = [states.binary_sensor.living_room_window,
                            states.binary_sensor.bens_window] %}
          {{ sensors | selectattr('state','eq','on') | list | count > 0 }}

So i am trying to do as much as i can looking at what others are doing since i am a newbie. However what am i doing wrong i have what he has but i am getting an error. in my groups file this is everything i have at this point. Please, what am i missing?


Error loading /config/configuration.yaml: expected '<document start>', but found '<block sequence start>'
  in "/config/groups.yaml", line 2, column 3

  - platform: template
        friendly_name: "Window Status"
        device_class: windows
        value_template: "{{ expand('') | selectattr('state','eq','on') | list | count > 0 }}"

It’s not formatted properly. Compare the first example in the documentation to what you posted above. Look at how each line is indented.

# Example configuration.yaml entry
  - platform: template
        friendly_name: "Sun is up"
        value_template: >-
          {{ state_attr('sun.sun', 'elevation')|float > 0 }}

Got it thanks!

also… home assistant is case sensitive and entity_id’s never have capitals in them. You’re using capitals all over the place.

1 Like

Thank you! Very nice way to group (with OR) binary sensors.

How can the status of all those sensors be grouped in a way the individual sensors don’t need to be in the config, but instead the template includes all binary_sensors automatically? This would be based on this automation, but than inside a template. I can’t get my head around this how to do this.

EDIT: I mean something like this, which doesn’t seem to be working, as it reads unavailable, while all my sensors are online.

        friendly_name: "Lekkage sensors"
        value_template: >-          
          {% if is_state.entity_id.startswith('binary_sensor.','unavailable') %}
            Sensor offline
          {% else %}
            Sensors online
          {% endif %}

Currently, that is not possible.

On startup, Home Assistant inspects the Template Sensor’s template and attempts to identify it’s entities. For each identifiable entity it creates a “listener”. The listener is responsible for detecting the entity’s state changes. If it cannot find any entities, no listeners are created. The result is the Template Sensor’s template is evaluated once on startup and never again (until the next restart). The only way to ensure Home Assistant can create listeners is to include the desired entities within the template, or separately in the entity_id option (which supercedes the template).

The automation you linked to works with events, not entity states, and is not applicable to Template Sensors.

1 Like

Ok, thanks for point out! :+1:

you could create an automatic group with the conditions you like, and then listen to the expanded group. I do something like that with my batteries

    alias: Group battery sensors low create
      service: group.set
        object_id: battery_sensors_low
        entities: >-
          {%- for s in states.sensor
            if ('battery_level' in s.entity_id or
                'motion_sensor_battery' in s.entity_id)
             and s.state|int < states('input_number.battery_alert_level')|int %}
            {{s.entity_id}}{% if not loop.last %}, {% endif %}
          {%- endfor %}

call this script using an automation which can be triggered at startup and other triggers.

or use template sensors like this;

        friendly_name: Low level batteries
        value_template: >
          {%- set ns = namespace(below=[]) %}
          {%- for s in states.sensor
            if ('battery_level' in s.entity_id or 'motion_sensor_battery' in s.entity_id)
                and s.state|int < states('input_number.battery_alert_level')|int
                and s.state != 'unknown' %}
              {%- set ns.below = ns.below + [s] %}
          {%- endfor %}
          List: >
            {%- set ns = namespace(below=[]) %}
            {%- for s in states.sensor
             if ('battery_level' in s.entity_id or 'motion_sensor_battery' in s.entity_id)
                  and s.state|int < states('input_number.battery_alert_level')|int
                  and s.state != 'unknown' %}
                {%- set ns.below = ns.below + [ + ': (' + s.state + '%)'] %}
            {%- endfor %}

            {% set count_below = ns.below|count|int %}
            {% set list = ns.below %}
            {%- if count_below == 0 %} All batteries are fine
            {%- elif count_below == 1 %}
              {{list[0]}} is low!
            {%- elif count_below == 2 %}
              {{list|join(' and ') }} are low!
            {%- else %}
              {{list[:-1]|join(', ')}}, and {{list[-1]}} are low!
            {%- endif %}

  - platform: template
        friendly_name: Battery alert
        device_class: safety
        value_template: >
          {{states('sensor.low_level_batteries')|int > 0}}
          Count: >
           {{states('sensor.low_level_batteries')|int }}
          List: >
1 Like

There is work underway to improve Home Assistant’s ability to identify entities in a template. In some future release, listeners for each binary_sensor will be created for the following:


expand (‘group.my_binary_sensors’)

1 Like

Wow, thanks. I need to sit down for this one and try this out.

That sounds great! Thanks for the heads up.

What are the identifiable entities in sensor.low_level_batteries?

The reason why I ask is because I tried to use this in a Template Sensor in 0.114 (as an experiment) and it was reported in the log to have no identifiable entities.

{{ states.light | selectattr('state', 'eq', 'on') | list | count }}

In other words, states.light was not assigned any listeners so, by extension, nor would any for states.sensor.

if I do that, is counts the entities nicely in my setup, currently on 114.1

as does

replacing the last line of the value_template to use this:

{{ns.below|map(attribute = 'entity_id')|join(',')}}

shows that even better: (sorry but it wont fit on a single screenshot…)

It has always worked in the Template Editor and only because you are refreshing the template manually.

It won’t work in a Template Sensor because no listeners will be created for states.light. This ability is currently being developed but doesn’t yet exist in any release version.

      # This one doesn't listen to anything and is flagged in the log
        friendly_name: 114 States
        value_template: >
          {{ states.light | selectattr('state','eq', 'on') | list | length }}

Sorry, I misunderstood your question, thought the template itselfdidnt work in your setup, even in the template editor.

You’re right, that’s why I also use some automations in this setting:

  - alias: Update sensor battery alert
      platform: time_pattern
      minutes: '/15'
      seconds: 00
      - service: homeassistant.update_entity
          - sensor.low_level_batteries
          - sensor.count_low_level_batteries
          - sensor.low_level_batteries_group
      - service: automation.trigger
        entity_id: automation.create_battery_low_group

  - alias: Update battery low group
      platform: state
      entity_id: input_number.battery_alert_level
      service: automation.trigger
      entity_id: automation.create_battery_low_group

  - alias:  Alert when batteries are below alert level
      platform: state
      entity_id: binary_sensor.battery_alert
      to: 'on'
      service: notify.system
        title: Battery alert
        message: >

depending on the needs of the poster, he might be able to use the group’s all: functionality to his advantage, and automate based on the state of that group, instead of all individual entities.

If these need to be available to use {{trigger.to_state.state}} for now there’s no other option than to list them in the trigger: platform: state as individual entities.

I’d hope using that group as a triggering entity would someday have the option to trigger on all containing entities in that group.

Originally (back in version 0.110) the new functionality was simply to assign listeners to all members of a group when used with expand. So if the following template were used in a Template Sensor, Home Assistant would listen to all entities within the group (and not only the group itself):

{{ expand('group.my_sensors') | etc }}

Unfortunately, it didn’t work. Changes were made in 0.114 but those also failed to make it work.

There’s a completely separate initiative underway to fundamentally change the way Home Assistant assigns listeners to a Template Sensor. It’s goal is not only to handle expand correctly, it will also support states.light, states.sensor, etc. In theory, it should be able to handle something tricky like this:

{{ expand(states.binary_sensor, states.sensor) | etc }}