By checking three conditions you can tell if it was an automation, a physical device or a person performing an action in a dashboard that changed an entity. This can be useful if you need to know if a person or an automation did something, e.g. were the lights turned on automatically or by a person operating a physical switch or dashboard control?
The three context ids and how they relate to the three causes are:
User mbuscher provided this automation to demonstrate its use, it will generate a log of what caused a switch to turn on or off:
trigger:
- platform: state
entity_id:
- switch.office
not_to:
- unknown
- unavailable
action:
- choose:
- conditions:
- condition: template
value_template: '{{ trigger.to_state.context.id != none }}'
- condition: template
value_template: '{{ trigger.to_state.context.parent_id == none }}'
- condition: template
value_template: '{{ trigger.to_state.context.user_id == none }}'
sequence:
- service: system_log.write
data:
level: debug
message: Physical device
- choose:
- conditions:
- condition: template
value_template: '{{ trigger.to_state.context.id != none }}'
- condition: template
value_template: '{{ trigger.to_state.context.parent_id == none }}'
- condition: template
value_template: '{{ trigger.to_state.context.user_id != none }}'
sequence:
- service: system_log.write
data:
level: debug
message: HA user interface
- choose:
- conditions:
- condition: template
value_template: '{{ trigger.to_state.context.id != none }}'
- condition: template
value_template: '{{ trigger.to_state.context.parent_id != none }}'
- condition: template
value_template: '{{ trigger.to_state.context.user_id == none }}'
sequence:
- service: system_log.write
data:
level: debug
message: HA automation
There are some exceptions though. context.parent_id
is only available for automations with triggers that have an identifiable parent entity or device so:
- Event trigger
- Home Assistant trigger
- MQTT trigger
- Numeric state trigger
- State trigger
- Sun trigger
- Tag trigger
- Template trigger
- Time trigger
- Time pattern trigger
- Persistent notification trigger
- Webhook trigger
- Zone trigger
- Geolocation trigger
- Device triggers
- Calendar trigger
- Sentence trigger
A practical example of use:
.
For each of my rooms I have an input select that stores if the lights for that room are in ‘Automatic’ or ‘Manual’ scene mode. If someone presses a physical light switch in a room the scene mode for that room changes to ‘Manual’ and sends me an actionable notification asking if I would like to change the mode back to ‘Automatic’. Until this happens motion lights will no longer be active for this room as the motion lights automation has a condition that checks the input select is in ‘Automatic’ mode.
Here is the automation for detecting the physical button press and changing the input select . This has been truncated, there are a lot more rooms & triggers, other scene types too that have been omitted here for clarity. The main thing to note are the context conditions:
- id: 68e2bb6b-ac35-4013-81aa-5e631dfd99fc
alias: 'Lights to Manual Mode'
mode: parallel
max: 10
trigger:
- id: bathroom_scene
platform: state
entity_id:
- light.bathroom_light
not_from:
- unavailable
- unknown
not_to:
- unavailable
- unknown
- id: cinema_scene
platform: state
entity_id:
- light.cinema
not_from:
- unavailable
- unknown
not_to:
- unavailable
- unknown
- id: workshop_scene
platform: state
entity_id:
- light.electronics_workshop
- light.mechanical_workshop
not_from:
- unavailable
- unknown
not_to:
- unavailable
- unknown
condition:
- condition: template ### Not in manual mode already? ###
value_template: "{{ not is_state('input_select.'~ trigger.id, 'Manual') }}"
- condition: template ### This is the required 'context', only physical activation of light pass here ###
value_template: "{{ trigger.to_state.context.id != none }}"
- condition: template
value_template: "{{ trigger.to_state.context.parent_id == none }}"
- condition: template
value_template: "{{ trigger.to_state.context.user_id == none }}"
action:
- service: input_select.select_option
target:
entity_id: "{{ 'input_select.'~ trigger.id }}"
data:
option: 'Manual'
- service: notify.telegram_system
data:
title: '💡 <b>Light Mode Changed</b>'
message: "{{ trigger.id|replace('_scene','')|replace('_',' ')|title }} changed to manual mode."
data:
inline_keyboard: "Back to Automatic?:/{{ trigger.id }}"
Examples of motion light automation:
- id: 364b9af0-4147-4f09-a740-e36de92dbb2f
alias: 'Mechanical Workshop Lights Auto On'
mode: single
max_exceeded: silent
trigger:
- platform: state
entity_id: binary_sensor.pir_workshop
from: 'off'
to: 'on'
condition:
- condition: state
entity_id: input_select.workshop_scene ### Note this must be 'Automatic' to pass
state: 'Automatic'
- condition: state
entity_id: light.mechanical_workshop
state: 'off'
action:
service: light.turn_on
data:
entity_id:
- light.mechanical_workshop
brightness: 255
- id: e428d821-5e20-439f-a831-2ebf97a14bbe
alias: 'Mechanical Workshop Lights Auto Off'
trigger:
- platform: state
entity_id: binary_sensor.pir_workshop
to: 'off'
for:
minutes: 6
condition:
- condition: state
entity_id: input_select.workshop_scene ### Note this must be 'Automatic' to pass
state: 'Automatic'
- condition: state
entity_id: light.mechanical_workshop
state: 'on'
action:
service: light.turn_off
entity_id: light.mechanical_workshop