Changing a template sensor only if an entity is changed by a user

I’ve got an existing template sensor like this:

- trigger:
    - platform: state
      entity_id: climate.heatpump
      to: cool
    - platform: state
      entity_id: climate.heatpump
      to: heat
  sensor:
    - name: "Heatpump Intent"
      unique_id: heatpump_intent
      state: >
        {% if is_state('climate.heatpump', 'cool') %}
          Cooling
        {% elif is_state('climate.heatpump', 'heat') %}
          Heating
        {% endif %}

However, I’d like it to only update its state if climate.heatpump is changed by an actual person (eg, don’t change to Cooling if Automation sets the heat pump to cool)

I took the suggestion here and tried to apply it to my sensor but it still changed the state when changed by automation:

{% if is_state('climate.heatpump', 'cool') and ('trigger.to_state.context.parent_id' not in states.automation | map(attribute='context.id') | list ) %}
  Cooling
{% elif is_state('climate.heatpump', 'heat') and ('trigger.to_state.context.parent_id' not in states.automation | map(attribute='context.id') | list ) %}
  Heating
{% endif %}```

I also gave this a go:

      {% if is_state('climate.heatpump', 'cool') and context.user_id %}
        Cooling
      {% elif is_state('climate.heatpump', 'heat') and context.user_id %}
        Heating
      {% endif %}

But that just gives me “‘context’ is undefined” in the template editor in Dev tools. Is it possible to do what I’m looking for?

Try this:

      state: >
        {% if trigger.to_state.context.id != none and trigger.to_state.context.parent_id != none and trigger.to_state.context.user_id == none %}
          {{ states('sensor.heatpump _intent') }}
        {% else %}
          {% if is_state('climate.heatpump', 'cool') %}
            Cooling
          {% elif is_state('climate.heatpump', 'heat') %}
            Heating
          {% endif %}
        {% endif %}

If those context templates resolve to true the change was made by an automation and the previous state is kept.

You could use this.state instead of states('sensor.heatpump _intent') but that can be tricky if the previous state does not already exist the first time you use it. This way is a lot easier.

Thanks for the help…I made a new test sensor with that code (updating the state name) and then set up a test Automation to change the modes over but unfortunately, it still updated with the change by the automation (it also correctly updates when I make the change)

Can you share your sensor?

It shouldn’t change if an automation changes the climate mode according to this:

06283b2a5eaebf0b308f62c6b2b764cbb14fb723

Did you manually trigger the automation or use an actual trigger?

Sorry for the late reply on this, the last week has been a bit busy.

Got a chance to play around with it again now. I was testing with an automation that would fire within the next minute. Just tried it again with the same results:


Here is the template sensor code:

- trigger:
    - platform: state
      entity_id: climate.heatpump
      to: cool
    - platform: state
      entity_id: climate.heatpump
      to: heat
  sensor:
    - name: "Heatpump Intent Test"
      unique_id: heatpump_intent_test
      state: >
        {% if trigger.to_state.context.id != none and trigger.to_state.context.parent_id != none and trigger.to_state.context.user_id == none %}
        {{ states('sensor.heatpump_intent_test') }}
        {% else %}
          {% if is_state('climate.heatpump', 'cool') %}
            Cooling
          {% elif is_state('climate.heatpump', 'heat') %}
          Heating
          {% endif %}
        {% endif %}

What results?

Please be more specific. I can’t tell what you want from the graphs.

Those context conditions are true when the changes are made by an automation. If you want the opposite to happen (as you seem to do) Just swap the actions (also watch your indentation):

      state: >
        {% if trigger.to_state.context.id != none and trigger.to_state.context.parent_id != none and trigger.to_state.context.user_id == none %}
          {% if is_state('climate.heatpump', 'cool') %}
            Cooling
          {% elif is_state('climate.heatpump', 'heat') %}
            Heating
          {% endif %}
        {% else %}
          {{ states('sensor.heatpump_intent_test') }}
        {% endif %}

By the same results I meant the same result as earlier in the thread where the template was switching no matter if the heatpump entry was changed by a user or automation.

Anyway, that new example you provided wasn’t quite right either but I remembered the grid matrix you posted further up and using that, I was able to figure out the conditions I needed. Going with this now changes the template sensor if a user manually changes it but if it’s changed by automation then it stays as it was:

- trigger:
    - platform: state
      entity_id: climate.heatpump
      to: cool
    - platform: state
      entity_id: climate.heatpump
      to: heat
  sensor:
    - name: "Heatpump Intent Test"
      unique_id: heatpump_intent_test
      state: >
        {% if trigger.to_state.context.parent_id == none and trigger.to_state.context.user_id != none %}
          {% if is_state('climate.heatpump', 'cool') %}
            Cooling
          {% elif is_state('climate.heatpump', 'heat') %}
            Heating
          {% endif %}
        {% else %}
          {{ states('sensor.heatpump_intent_test') }}
        {% endif %}

I also tidied up the indentation as you recommended :wink: Thanks for your help and putting me on the right track!

1 Like