Create a template where a state change is triggered by an attribute change

I would like to build a sensor template for my shelly controlled shutters.
In order to detect if the shutters are fully closed, fully opened, or in an intermediate state, I want to do the following logic (mockup):

CASE WHEN switch_up = 'on' THEN
  CASE WHEN power_up > 0 THEN
    state = 'Moving Up'
  ELSE
    state = 'Up'
  END
ELSE
  CASE WHEN switch_up = 'off' THEN
    state = 'Intermediate'
  END
END

To do so, I want to create a new entity within a template. The tricky thing here is that there is a slight delay for the power to go up after the button has been pressed.
Therefore, I want to trigger an update of the state only when the power goes above 0. For this, I have added the attribute movement. Only when movement has changed (either the shutters start to move or they stop to move), the state will be updated.

For the logic, this should mean:

  • When movement starts and the button is pressed, the shutters are moving
  • When the movement stops, and the button is still pressed, the endpoint is reached, state is Up
  • When the moving stops, and the button is no longer pressed, the shutters are in an intermediate state

The template I have set up looks like this:

- sensor:
    - name: shutters_living_room
      state: >
        {% if states('sensors.shutter_control_living_room_up') == 'on' %}
          {% if state_attr('sensors.shutters_living_room','movement') == 'Up' %}
              Moving Up
            {% else %}
              Up
            {% endif %}
          {% endif %}
        {% endif %}  
      attributes:
        movement: >
          {% if states('sensors_control.shutters_control_living_room_up_power') | float > 0 %}
            Up
          {% else %}
            None
          {% endif %}
      trigger:
        - platform: state
          entity_id: sensor.shutters_living_room
          attribute: movement
        - platform: homeassistant
          event: start

Problem: Then change of the sensor state is never being triggered. Seems like movement never changes, even though power is being drawn.

Any ideas why this doesn’t work? Are there possibly some issues with race conditions?

Your logic doesn’t make sense and you’re self referencing. Attributes on template sensors are resolve after state.

- sensor:
    - name: shutters_living_room
      state: >
        {% set on = is_state('sensors.shutter_control_living_room_up', 'on') %}
        {% set moving = states('sensors_control.shutters_control_living_room_up_power') | float > 0 %}
        {% if on and moving %}
          Moving Up
        {% elif on %}
          Up
        {% else %}
          Intermediate
        {% endif %}

You shouldn’t need anything else.

YOu may want to add an availability template to ensure | float doesn’t cause issues

- sensor:
    - name: shutters_living_room
      state: >
        {% set on = is_state('sensors.shutter_control_living_room_up', 'on') %}
        {% set moving = states('sensors_control.shutters_control_living_room_up_power') | float > 0 %}
        {% if on and moving %}
          Moving Up
        {% elif on %}
          Up
        {% else %}
          Intermediate
        {% endif %}
      availability: >
        {{ has_value('sensors.shutter_control_living_room_up') and states('sensors_control.shutters_control_living_room_up_power') | is_number }}

This doesn’t solve the issue that it is set to ‘Up’ for a brief moment until the power actually goes up and it goes into the moving state.

if you’re looking to use this as triggers, then just add a for to your trigger w/ a duration longer than a second. Then you don’t need to care about that brief moment.