Template sensor does not update when it's unavailable

I’ve been trying to make this template trigger whenever I set its state to unavailable but it does not trigger.

{% if trigger.id == "availability" %} and {% elif trigger.idx == 3 %} doing same thing, but neither work.

States on and off works well. Tried removing availability section but it didn’t help.

Am I wrong somewhere or it can be a bug?

- trigger:
  - platform: homeassistant
    event: start
  - platform: state
    entity_id: binary_sensor.bath_motion_sensor
    from: "on"
    to: "off"
    for: "00:01:00"
  - platform: state
    entity_id: binary_sensor.bath_motion_sensor
    from: "off"
    to: "on"
  - platform: state
    entity_id: binary_sensor.bath_motion_sensor
    to: "unavailable"
    id: "availability"
  binary_sensor:
    - unique_id: bath_motion_sensor_template
      name: "Bath motion sensor"
      device_class: motion
      state: >
          {% if trigger.id == "availability" %}
            unavailable
          {% elif trigger.idx == 1 %}
            off
          {% elif trigger.idx == 2 %}
            on
          {% elif trigger.idx == 3 %}
            unavailable
          {% else %} 
            {% if is_state('binary_sensor.bath_motion_sensor', 'on') %}
              on
            {% else %}
              off
            {% endif %}
          {% endif %}
      icon: mdi:shower
      availability: >
          {% if states.binary_sensor.bath_motion_sensor and not is_state('binary_sensor.bath_motion_sensor', 'unavailable') %}
            True
          {% endif %}

Welcome to the community :slight_smile:
So I guess you’ve created a Trigger-Based Template Sensor?
Please take a look at the documentation for the state and for the availability:

The sensor is on if the template evaluates as True, yes, on, enable or a positive number. Any other value will render it as off. The actual appearance in the frontend (Open/Closed, Detected/Clear etc) depends on the sensor’s device_class value

So unavailable is not a valid state. A binary_sensor can only be on or off.
You set the availability via the availability key, which you’ve also done, but there’s an error there, see:

Defines a template to get the available state of the entity. If the template either fails to render or returns True, “1”, “true”, “yes”, “on”, “enable”, or a non-zero number, the entity will be available. If the template returns any other value, the entity will be unavailable. If not configured, the entity will always be available. Note that the string comparison not case sensitive; “TrUe” and “yEs” are allowed.

Your template will either result in True or nothing, so it will always be available.

This should do it for you:

- trigger:
  - platform: homeassistant
    event: start
  - platform: state
    entity_id: binary_sensor.bath_motion_sensor
    from: "on"
    to: "off"
    for: "00:01:00"
    id: 'sensoroff' # Added for better comprehensibility
  - platform: state
    entity_id: binary_sensor.bath_motion_sensor
    from: "off"
    to: "on"
    id: 'sensoron'  # Added for better comprehensibility
  - platform: state
    entity_id: binary_sensor.bath_motion_sensor
    to: "unavailable"
    id: "availability"
  binary_sensor:
    - unique_id: bath_motion_sensor_template
      name: "Bath motion sensor"
      device_class: motion
      state: >
          {% if trigger.id == "sensoroff" %}
            off
# This is not required, since the state would be set to on in the 'else' anyway
#          {% elif trigger.id == "sensoron" %}
#            on
          {% else %} 
            {% if is_state('binary_sensor.bath_motion_sensor', 'on') %}
              on
            {% else %}
              off
            {% endif %}
          {% endif %}
      icon: mdi:shower
      availability: >
# Try avoiding states.xxx.yyy since it causes problems on startup, see the warning here:
# https://www.home-assistant.io/docs/configuration/templating/#states
# Using 'False' here makes things easier since we can remove other negations / nots
          {% if states('binary_sensor.bath_motion_sensor') == 'unknown' or is_state('binary_sensor.bath_motion_sensor', 'unavailable') %}
            False
          {% endif %}
1 Like

Thanks @fedot. I’m Glad to be here!

Yes it’s a trigger-based template sensor. I used your example and it worked. But then I started experimenting and I’m completely confused right now. I’ve been testing various combinations of availability template and I don’t understand what is happening. Sometimes it sets unavailable state sometimes not. When testing I’m manually setting sensor to unavailable in Developer Tools. I’m giving some examples below that got me confused. Maybe you can check this in your environment if you experience same behaviour? My Home Assistant version is 2021.11.4

So this template is working fine now:

- trigger:
    - platform: homeassistant
      event: start
    - platform: state
      entity_id: binary_sensor.bath_motion_sensor
      from: "on"
      to: "off"
      for: "00:01:00"
      id: 'sensor_off' 
    - platform: state
      entity_id: binary_sensor.bath_motion_sensor
      from: "off"
      to: "on"
    - platform: state
      entity_id: binary_sensor.bath_motion_sensor
      from: "unavailable"
      to: "off"
    - platform: state
      entity_id: binary_sensor.bath_motion_sensor
      to: "unavailable"
  binary_sensor:
    - unique_id: bath_motion_sensor_template
      name: "Bath motion sensor"
      device_class: motion
      state: >
          {% if trigger.id == 'sensor_off' %}
              off
          {% elif is_state('binary_sensor.bath_motion_sensor', 'on') %}
              on
          {% else %}
              off
          {% endif %}
      icon: mdi:shower
      availability: >
          {% if states('binary_sensor.bath_motion_sensor') == 'unknown' or is_state('binary_sensor.bath_motion_sensor', 'unavailable') %}
            False
          {% endif %}

So here are some templates that got me confused(all changes done in availability key). By doesn’t work I mean it fails to set sensor unavailable state when entered manually in Developers Tools.

1.WORKS

availability: >
  {% if states('binary_sensor.bath_motion_sensor') == 'unknown' or is_state('binary_sensor.bath_motion_sensor', 'unavailable') %}
      False
  {% endif %}

2.DOESN’T WORK

availability: >
  {% if states('binary_sensor.bath_motion_sensor') == 'unknown' or is_state('binary_sensor.bath_motion_sensor', 'unavailable') %}
      false
  {% endif %}

3.DOESN’T WORK

availability: >
  {% if states('binary_sensor.bath_motion_sensor') != 'unknown' and not is_state('binary_sensor.bath_motion_sensor', 'unavailable') %}
      True
  {% endif %}

4.DOESN’T WORK

availability: >
  {% if states('binary_sensor.bath_motion_sensor') != 'unknown' and not is_state('binary_sensor.bath_motion_sensor', 'unavailable') %}
      true
  {% endif %}

.

I checked Logs but they are clear. I’m thinking it has to do something with triggers because I have some template binary sensors without any triggers and they work fine.

Works fine:


availability: >
  {% if states('binary_sensor.living_room_right_window') != 'unknown' and not is_state('binary_sensor.living_room_right_window', 'unavailable') %}
      true
  {% endif %}

Any idea why it’s acting like this?

To be honest I have no idea. I wouldn’t think too much about it, since you now have a working config :smiley:
In case you only need the template sensor for automations you can ditch it all together and just use a state trigger that triggers when your motion sensor is on for more than 1 minute.

You need to return true/false for all cases for availability. Remove your if statements.

{{ states('binary_sensor.bath_motion_sensor') == 'unknown' or is_state('binary_sensor.bath_motion_sensor', 'unavailable') }}

Also, simplify your check

{{ states('binary_sensor.bath_motion_sensor') not in ['unkown', 'unavailable'] }}

@fedot It’s not for automation, it’s for lovelace card. So when it’s on it will make icon coloured for 1 minute since last motion sensor reset. And without it my icon colour keeps changing every 5 seconds when motion is detected and cleared.

@petro I tested both of your examples.
First one only working other way around:

availability: "{{ states('binary_sensor.bath_motion_sensor') != 'unknown' and not is_state('binary_sensor.bath_motion_sensor', 'unavailable') }}"

Second works fine(there is a typo 'unkown').

Anyways I checked that it never works when states('binary_sensor.bath_motion_sensor') == 'unknown'. I added addional trigger for it:

- platform: template
    value_template: "{{ states('binary_sensor.bath_motion_sensor') == 'unknown' }}"

It triggers when state string doesn’t exist(unknown ). But how should I make it to trigger when it goes from unknown to off,on or unavailable? I tried this trigger without success:

- platform: state
    entity_id: binary_sensor.bath_motion_sensor
    from: "unknown"