Problems with trigger.to_state.state

I am trying to create an automation to change the value of an input number based on the difference between two values.

Currently, the automation looks like this:

- id: "50"
  alias: Automatizare TRV living procentaj
  description: ""
  trigger:
    - platform: template
      value_template: >
        {{(state_attr('climate.termostat_living','temperature') | float - states('sensor.multisensor_living_temperature_air') | float) | round (2)}}
  action:
    - service: input_number.set_value
      entity_id: input_number.trv_living
      data:
        value: >
          {% if trigger.to_state.state | float > 1 %} 
            255
          {% elif 0.5 < trigger.to_state.state | float <= 1 %} 
            155
          {% elif 0 < trigger.to_state.state | float <= 0.5 %} 
            100
          {% elif -0.2 < trigger.to_state.state | float <= 0 %} 
            30
          {% elif trigger.to_state.state | float <= -0.2 %} 
            0
          {% endif %}
  mode: restart

However, the value of the input number only changes to 30, regardless of what the trigger.to_state.state value is.

Putting a similar code in supervisor>templates appears to work as expected:

{% set trigger={'to_state':{'state': (state_attr('climate.termostat_living','temperature') | float - states('sensor.multisensor_living_temperature_air') | float) | round (2)}} %}
{% if trigger.to_state.state | float > 1 %} 
255
{% elif 0.5 < trigger.to_state.state | float <= 1 %} 
155
{% elif 0 < trigger.to_state.state | float <= 0.5 %} 
100
{% elif -0.2 < trigger.to_state.state | float <= 0 %} 
30
{% elif trigger.to_state.state | float <= -0.2 %} 
0
{% endif %}

If i change the state trigger to a string, such as {% set trigger={‘to_state’:{‘state’: ‘a’}} %} the input_number output changes to 30.

So, this leads me to expect that the automation is somehow interpreting the trigger.to_state.state value to be a string, even if I formatted it to float ? Any ideas?

Thanks

State is always a string, but | float works correctly. Try to simplifying your action, using high-to-low-sequence.

{% if trigger.to_state.state | float > 1 %}
255
{% elif trigger.to_state.state | float > 0.5 %}
155
{% elif trigger.to_state.state | float > 0 %}
100
{% elif trigger.to_state.state | float > -0.2 %}
30
{% else %}
0
{% endif %}

I tried simpliyfing the action as you have mentioned (thanks for that btw!), but i still get 30 as output :frowning:

- id: "50"
  alias: Automatizare TRV living procentaj
  description: ""
  trigger:
    - platform: template
      value_template: >
        {{(state_attr('climate.termostat_living','temperature') | float - states('sensor.multisensor_living_temperature_air') | float) | round (2)}}
  action:
    - service: input_number.set_value
      entity_id: input_number.trv_living
      data:
        value: >
          {% if trigger.to_state.state | float > 1 %}
            255
          {% elif trigger.to_state.state | float > 0.5 %}
            155
          {% elif trigger.to_state.state | float > 0 %}
            100
          {% elif trigger.to_state.state | float > -0.2 %}
            30
          {% else %}
            0
          {% endif %}
  mode: restart

Just for sanity check, in developer mode> templates, the following code outputs 1.4 currently:

{% set trigger={‘to_state’:{‘state’: (state_attr(‘climate.termostat_living’,‘temperature’) | float - states(‘sensor.multisensor_living_temperature_air’) | float) | round (2)}} %}
{{trigger.to_state.state}}

It should also work when using

{% set trigger={"to_state":{"state":"1.4"}} %}

for testing purposes, but did you check (by notify or any other type of output), what the real value of trigger.to_state.state is at the time of automation execution?

Ok, getting closer but even more questions pop-up.

I changed the automation to:

- id: "50"
  alias: Automatizare TRV living procentaj
  description: ""
  trigger:
    - platform: template
      value_template: >
        {{(state_attr('climate.termostat_living','temperature') | float - states('sensor.multisensor_living_temperature_air') | float) | round (2)}}
  action:
    - service: notify.persistent_notification
      data:
        message: "{{ trigger.to_state.state }}"
    - service: input_number.set_value
      entity_id: input_number.trv_living
      data:
        value: >
          {% if trigger.to_state.state | float > 1 %}
            255
          {% elif trigger.to_state.state | float > 0.5 %}
            155
          {% elif trigger.to_state.state | float > 0 %}
            100
          {% elif trigger.to_state.state | float > -0.2 %}
            30
          {% else %}
            0
          {% endif %}
  mode: restart

However, when triggering the automation I get a persistent notification saying ‘heat’ ?? What? :laughing: Heat is the thermostat mode, but I don’t see how it can reach that value based on the trigger conditions??

Your automation will never trigger.

From the docs

Template triggers work by evaluating a template on every state change for all of the recognized entities. The trigger will fire if the state change caused the template to render ‘true’.

That’s what I thought too, but it is actually smarter than that:

For the template trigger

trigger.to_state New state object of entity that caused template to change.

Automation trigger variables - Home Assistant

I dont think that is correct. The automation triggers, however the output value is always 30. If i change the value of the input number manually to 255, then i change one of the parameters in the trigger, for example the climate setpoint, then the automation triggers (i can see last execution time changing) and the input number is changing to 30…

I think i get it…

so because my trigger template is based on the difference between two values…in case only one of them changes then only the value that changed is considered the new state of trigger.to_state.state ?

Given that climate.termostat_living has the state ‘heat’ and attributes ‘temperature’ (temp setpoint), then I guess that the automation considers that the value of trigger.to_state.state should be heat, even if the value of the attributes change?

Is this correct? Can i use something else instead of trigger.to_state.state ?

What I am trying to do is to change the value of an input number to predetermined values 0/30/100/155/255 based on the difference between two values (TRV setpoint) and ambient temperature. The input number controls how much the TRV valve should open.

Correct.

Also correct.

The way around this would be to set a variable to your template value so you can use it later.

Previously the action looked like this and it worked:

    - service: input_number.set_value
      entity_id: input_number.trv_baie_stanga
      data:
        value: >
          {% if state_attr('climate.termostat_baie_stanga', 'temperature')|float - states('sensor.multisensor_baie_temperature_air')|float  > 1 %}
            255
          {% elif state_attr('climate.termostat_baie_stanga', 'temperature')|float - states('sensor.multisensor_baie_temperature_air')|float  > 0.5 %}
            155
          {% elif state_attr('climate.termostat_baie_stanga', 'temperature')|float - states('sensor.multisensor_baie_temperature_air')|float  > 0 %}
            100
          {% elif state_attr('climate.termostat_baie_stanga', 'temperature')|float - states('sensor.multisensor_baie_temperature_air')|float  > -0.2 %}
            30
          {% else %}
            0
          {% endif %}

I tried compacting the action using trigger.to_state.state instead of

state_attr(‘climate.termostat_baie_stanga’, ‘temperature’)|float - states(‘sensor.multisensor_baie_temperature_air’)|float

but it now appears that trigger.to_state.state is not the way to go if i understand correctly.

Yep, because you are re-evaluating the template, not relying on the trigger object state. You can simplify it a bit:

    - service: input_number.set_value
      entity_id: input_number.trv_baie_stanga
      data:
        value: >
          {% set temp_diff = state_attr('climate.termostat_baie_stanga', 'temperature')|float - states('sensor.multisensor_baie_temperature_air')|float %}
          {% if temp_diff > 1 %}
            255
          {% elif temp_diff  > 0.5 %}
            155
          {% elif temp_diff > 0 %}
            100
          {% elif temp_diff > -0.2 %}
            30
          {% else %}
            0
          {% endif %}
        ```

If you were using the same attribute of both sensors in the trigger template it would be possible to use the trigger state object, but one attribute and one state? Messy. Much easier to use your action template.

2 Likes

Thanks a lot Tom!

1 Like