Access to trigger.to_state.context from a different entity?

Hi there,
I’m trying to distinguish how a light got switched on (tuya motion sensor or physical switch (through shell1 pm). The normal case is motion sensor and in my automation I want to make sure that I adhere to some logic when it was triggered by hand (light switch). In the forum I’ve seen that accessing trigger.to_state.context.parent_id == none (Work with "Triggered by" in automations - #8 by 123) gives some clues on how it got triggered. However, my problem is that my automation is in the context of a motion sensor and therefore I don’t have trigger.to_state.context of the light/shelly device, any advice?

Here my automation:

alias: Garage Light off
description: ""
trigger:
  - type: no_motion
    platform: device
    device_id: xxx
    entity_id: binary_sensor.lumi_lumi_sensor_motion_aq2_motion
    domain: binary_sensor
condition:
  - condition: template
    value_template: >
      {{ (as_timestamp(now()) -
      as_timestamp(state_attr('automation.garage_light_on','last_triggered'), 0)
      < 10 * 60)}}
action:
  - type: turn_off
    device_id: xxx
    entity_id: switch.shelly_1pm_garage_switch_0
    domain: switch
mode: single

You’ll probably have more success by using “state” triggers, rather than “device” ones.

1 Like

You do. All automation triggers change the context.

What you need to do is store the context when the switch turns on. You need to check all three contexts as per the table:

Screenshot 2022-06-21 081430

Then use that when your no-motion automation runs.

e.g. this triggered template sensor will save the switch context when it turns on:

(configuration.yaml)

template:
  - trigger:
      - platform: state
        entity_id: switch.shelly_1pm_garage_switch_0
		to: "on"
    sensor:
      - name: "Garage Switch On Context"
        state: >
		  {% set c_id = trigger.to_state.context.id %}
		  {% set c_parent = trigger.to_state.context.parent_id %}
          {% set c_user = trigger.to_state.context.user_id %}
		  {% if c_id != none and c_parent == none and c_user == none %}
		    physical
		  {% elif c_id != none and c_parent == none and c_user != none %}
		    dashboard_ui
		  {% elif c_id != none and c_parent != none and c_user == none %}
		    automation
		  {% else %}
		    unknown
		  {% endif %}

You then use this sensor in a state condition in your “no motion” automation.

e.g. if you want the switch turned off automatically after three minutes of no motion, but only when an automation turned the switch on:

alias: "Garage Light Auto Off"
trigger:
  - platform: state
    entity_id: binary_sensor.lumi_lumi_sensor_motion_aq2_motion
    to: "off"
    for:
      minutes: 3
condition:
  - condition: state
    entity_id: sensor.garage_switch_on_context
    state: "automation"
action:
  - service: switch.turn_off
    target:
      entity_id: switch.shelly_1pm_garage_switch_0
mode: single

You could remove the condition and use a choose action depending on the state of sensor.garage_switch_on_context if you want different things to happen depending on how it was turned on.

6 Likes

Thank you @tom_l for the detailed example. I’ll try this out and get back to the forum.

@tom_l This worked nicely. Thank you very much for your help and great code sample.
Have a nice day.

wow, great post, thanks for sharing, this should be part of context out of the box (user_interface, automation, physical/external, unknown).

do scripts behave as automations for this context?

I don’t actually know. I suspect not as it is the trigger that affects the context, not a service call.

Yes it would simplify things having such an entity attribute, but you would still need to store it when the first action happens for use later.

Would it be possible to dynamically create attributes for all lights?
Or create the sensors dynamically?
Maybe using something like this: