How to detect what input performed an action?

Hey Everyone,

I’m trying to detect what input performed an action so that I can perform an automation or not.

Here is my situation: I have a TP-Link wall light switch that goes to a ceiling fan. I have an automation that detects if my Ecobee is running the air conditioning “cooling” then turns on the fan. When the air conditioning stops, the switch is turned off to stop the fan. Easy enough so far.

However, if I turn on the fan manually by pushing the wall switch or using the app, the “turn off” automation is ignored until I manually turn off the fan again. This way if I turn on the fan because I want it on indefinitely, the automation does not later override that action when the AC turns off.

The automation “turn off” pseudo-code would go like this:

  • State: Ecobee goes from cooling
  • Condition: An automation did not turn on the switch the last time the switch was turned on
  • Action: Turn off the switch

It’s getting that condition part that is stumping me. I’ve Googled but I’m likely not asking the right questions (I can’t be the first to do this).

What are some good ways to detect and store what input (manual input vs. automation) performed an action last on a device/entity?

Thanks for being awesome!

You would need to check and store the context of the trigger. Have a read of this and the post it links to:

Thank you for your reply!

I’ve read the post, but the attributes mentioned (id, parent_id, user_id) do not all correlate to what I see in my environment. I only see “id” as an automation attribute:

image

The fan switch itself has only one value (state on/off):

image

Am I looking in the wrong spots (automation and device information)?

Here is an expansion of the example:

Start states: Fan off; AC off

  1. Turn on the fan using the manual switch
  2. AC turns on: Automation is triggered to turn on the fan, but the fan state does not change
  3. AC turns off: Automation to turn off the fan is ignored
  4. Turn off the fan using the app interface

For this to work, do I need to take additional actions between steps 1 and 2 (detect and/or save a value indicating the manual switch was used), between steps 2 and 3 (detect and/or save a value indicating that no change was made during the automation), or during step 3 (check conditions already existing somewhere)?

Thanks again for your help!!

Yes. These are properties of the trigger object not attributes of the automation. If you wrote an automation to send you this message when it triggers you could view them:

data:
  message: > 
    context.id  is {{ trigger.to_state.context.id  }}

    parent_id is {{ trigger.to_state.context.parent_id  }}

    user_id is {{ trigger.to_state.context.user_id  }}

Ahh! Where do I find these? Would I need to set/read the values in step 1, 2, or 3 in the previous example?

Thanks again!!

2 and 3.

Ah, ok. All of my automations so far have used simple condition checks like state or sun or time. To check these various IDs, will I need to use “template” like this?

'{{ (trigger.to_state.context.id != none) 
    and (trigger.to_state.context.parent_id == none) 
    and (trigger.to_state.context.user_id == none) }}'

Also, suppose I leave the fan on for a few hours and steps 2 and 3 execute several times. How would I go about finding the original action that turned on the switch for each consecutive loop of 2 and 3? Or will putting the trigger template condition simply prevent the automation from leaving any trails, thus only the “trigger.to_state” values from step 1 would be visible for each execution of 2 and 3?

Thanks again for your help!!

Where would I store it?

An input boolean would do if you are only worried about two states (automated vs manual activation).

I’m much more of a n00b than you think. :slightly_smiling_face: I can set up Home Assistant, connect devices, set up dashboards, and create automations using the excellent user interface within the platform. I can copy/pasta some code sometimes, but beyond this, everything is magic. Until this thread, I did not know trigger.to_state.context existed.

Assuming that I know nothing beyond the automation user interface of “triggers”, “conditions”, and “actions”, can you explain like I’m n00b-ish one or more methods of how I would easily store and retrieve the value I need to put into the automation condition?

Thanks again for your help and patience! You’re awesome!!

Ok, I solved the issue with a completely different approach.

Instead of determining if a human turned the fan on, I use MQTT to store a value of “on” or “off” if the automation turned the fan on or off. I then use that flag to determine if the “off” automation can turn off the fan or not.

With the fan “on”, the automation will turn off the fan only if the flag is “on” and will ignore if the flag is “off”.

With the fan “off”, the automation will turn on the fan and set the flag to “on”. If the automation wants the fan off and it’s already off, the automation will still run the “off” actions to be sure the flag is “off”.

Take a look and see if there are any logic errors in this approach.

Are there better ways to store a value?

Thanks again for your help!!

“On” automation:

  alias: Bedroom Ceiling Fan on when AC on
  description: ''
  trigger:
  - platform: state
    entity_id: climate.home
    attribute: hvac_action
    to: cooling
  condition:
  - condition: device
    type: is_off
    device_id: d218013dfcc092ae059be751d98f50f5
    entity_id: switch.bedroom_ceiling_fan
    domain: switch
  action:
  - type: turn_on
    device_id: d218013dfcc092ae059be751d98f50f5
    entity_id: switch.bedroom_ceiling_fan
    domain: switch
  - service: mqtt.publish
    data:
      topic: var/bedroom/ceiling_fan
      payload: 'on'

“Off” automation:

  alias: Bedroom Ceiling Fan off when AC off
  description: ''
  trigger:
  - platform: state
    entity_id: climate.home
    attribute: hvac_action
    from: cooling
  condition:
  - condition: or
    conditions:
    - condition: state
      entity_id: sensor.bedroom_fan_automation_flag
      state: 'on'
    - condition: device
      type: is_off
      device_id: d218013dfcc092ae059be751d98f50f5
      entity_id: switch.bedroom_ceiling_fan
      domain: switch
  action:
  - type: turn_off
    device_id: d218013dfcc092ae059be751d98f50f5
    entity_id: switch.bedroom_ceiling_fan
    domain: switch
  - service: mqtt.publish
    data:
      topic: var/bedroom/ceiling_fan
      payload: 'off'