Do different things depending on where the command to switch something came from

Following Problem:
My AC sucks at controlling itself when the target temperature is reached so I created an automation that switches between cooling and fan mode depending on the difference between target and actual temperature. That works perfectly fine. But sometimes I want to run the AC just in fan mode independend of the temperature so I have to disable that automation.
I first created a second automation that disabled the first one when the AC went from off to fan mode and vice versa but that doesnt react when I manually switch the AC to fan mode when it is already running.

So my question:
Is there a way to distinguish where a command was issued? As in: can an automation see if the last change to the AC mode was triggered by another automation or a manual command?

@koying if I get it correct that lets me see if the current run of the automation was triggered by user or automation. But I need to see the last thing that changed the state of the AC, independent of the current automation run…

My automation changes the AC state depending on temperature and runs everytime the temperature changes. And I need that automation to be able to see if the last(!) change of the ac settings was triggered by a user or an(other) automation…

I didn’t try it myself, but from that thread (that your read, right :wink: ), I understand that context.user_id is not none means that the state was changed through the UI, so not through an automation.

image

Just try it.

@koying ok I tried it and it didnt work. But that makes sense: The trigger for the automation is the temperature change, but I dont care what triggered that - I need to know what triggered the last change of the AC setting which is not a trigger for this automation but a result of it… Not sure if that’s understandable…

Maybe it helps if i go into more detail :wink:

I only want the AC to change from “fan” to “cool” when the current mode is “fan” and that was not set manually by any means.

There are at least three scenarios I can think of:

  1. I started the AC in fan mode - then I dont want this automation to do anything
  2. I started the AC in cool mode - then I want it to switch between fan and cooling depending on temperature
  3. I started the AC in cool mode but then later switched it to fan mode - in that case I want the automation to stop automatic switching

I will post the current version of the automation (with the added template) here, maybe that helps a little bit…

alias: Klimasteuerung Wohnzimmer
description: ""
trigger:
  - platform: state
    entity_id:
      - climate.wohnzimmer
    attribute: current_temperature
  - platform: state
    entity_id:
      - climate.wohnzimmer
    attribute: temperature
condition:
  - condition: or
    conditions:
      - condition: state
        entity_id: climate.wohnzimmer
        state: fan_only
      - condition: state
        entity_id: climate.wohnzimmer
        state: cool
action:
  - if:
      - condition: template
        value_template: >-
          {{ state_attr("climate.wohnzimmer", "current_temperature") >
          state_attr("climate.wohnzimmer", "temperature")}}
      - condition: template
        value_template: "{{ trigger.to_state.context.user_id is not none }}"
    then:
      - service: climate.set_hvac_mode
        data:
          hvac_mode: cool
        target:
          entity_id: climate.wohnzimmer
    else:
      - if:
          - condition: template
            value_template: >-
              {{ state_attr("climate.wohnzimmer", "current_temperature") <
              state_attr("climate.wohnzimmer", "temperature")}}
        then:
          - service: climate.set_hvac_mode
            data:
              hvac_mode: fan_only
            target:
              entity_id: climate.wohnzimmer
mode: single

Maybe position an input_boolean helper based upon who/what changed the AC mode last.

OK I think I got it working… so far it survived all my tests :wink:

I added an input_boolean helper and two triggers to the automation, one for entering fan mode, one for leaving it. When it enters fan mode i check if there is a user_id and set the helper if that’s the case. When it leaves fan mode for whatever reason it disables the helper.

Then I just check the helper before switching to cooling mode…

Tons of if-conditions and I am not sure if there would have been a more elegant solution, but at least it seems to work for now :wink:

alias: Klimasteuerung Wohnzimmer
description: ""
trigger:
  - platform: state
    entity_id:
      - climate.wohnzimmer
    attribute: current_temperature
  - platform: state
    entity_id:
      - climate.wohnzimmer
    attribute: temperature
  - platform: state
    entity_id:
      - climate.wohnzimmer
    id: to_fan
    to: fan_only
  - platform: state
    entity_id:
      - climate.wohnzimmer
    id: from_fan
    from: fan_only
condition:
  - condition: or
    conditions:
      - condition: state
        entity_id: climate.wohnzimmer
        state: fan_only
      - condition: state
        entity_id: climate.wohnzimmer
        state: cool
action:
  - if:
      - condition: trigger
        id: from_fan
    then:
      - service: input_boolean.turn_off
        data: {}
        target:
          entity_id: input_boolean.wohnzimmer_klima_fan_only
  - if:
      - condition: trigger
        id: to_fan
    then:
      - if:
          - condition: template
            value_template: "{{ trigger.to_state.context.user_id is not none }}"
        then:
          - service: input_boolean.turn_on
            data: {}
            target:
              entity_id: input_boolean.wohnzimmer_klima_fan_only
    else:
      - if:
          - condition: state
            entity_id: input_boolean.wohnzimmer_klima_fan_only
            state: "off"
        then:
          - if:
              - condition: template
                value_template: >-
                  {{ state_attr("climate.wohnzimmer", "current_temperature") >
                  state_attr("climate.wohnzimmer", "temperature")}}
            then:
              - service: climate.set_hvac_mode
                data:
                  hvac_mode: cool
                target:
                  entity_id: climate.wohnzimmer
            else:
              - if:
                  - condition: template
                    value_template: >-
                      {{ state_attr("climate.wohnzimmer", "current_temperature")
                      < state_attr("climate.wohnzimmer", "temperature")}}
                then:
                  - service: climate.set_hvac_mode
                    data:
                      hvac_mode: fan_only
                    target:
                      entity_id: climate.wohnzimmer
mode: queued
max: 10

It’s inelegant because you want to pack everything in a single automation :wink:
Create a separate one for the input_boolean handling.

IMHO, if you’re using an if in an automation, you’re doing it wrong :wink:
Same goes for loop’s and wait’s btw.

The reason I want it all in one automation is that I need this for every room independently - and the list of automations is already very long. So I try to keep things that logically belong together in one automation.

Also I wouldnt condemn “if” use in general… sometimes it is just needed to make automations possible unless you want to create an extra automation for every possible outcome.

You can, but then the automation becomes unreadable. Your choice :wink:

Nah. If tests are indeed needed, choose, or plain condition is always better