Detecting Method Used to Turn on Light

Hi All,

Is it possible for HA to detect what method was used to turn on a light? I’d like to trigger an automation if the light switch was turned on manually via the wall vs an automation or user turning it on via the HA Dashboard.

Thanks!

6 Likes

I don’t think so. Someone please correct me if I’m wrong.

An answer I’ve seen before (though never tried) is to create helper switches in HA and use them to turn on the light; one for each input method.

e.g. create a helper switch called “Light (Automation Control)” and add an automation to turn on the light based on that helper switch state.

Then when the manual switch is activated, you can add a Light (Automation)" helper switch. If it’s off you know it was the manual switch and not an automation. And vice versa.

This should work for as many inputs as you want as long as you trigger the helper switches and not the light directly.

What are you trying to achieve ?
Can you not just add a second action to the switch?

I’ve done it on mine by when turning on a light checking how long since the associated light automation last ran. This however only works if the light automation only has a single trigger, and single entitiy in that trigger. Multiple lights on one automation wouldn’t work (I dont believe there is anyway of accessing the last_triggered triggering entity_id).

If automation ran less than 2 seconds ago, assume automation turned the light on, if greater than 2 seconds, assume it was switched on at the switch manually.

I can probably grab a snippet later when at home.

Just a thought. Have you investigated using device triggers instead of entity triggers? And using event triggers instead of state triggers?

I turned on a light directly, then turned it off in HA

HA clearly knows that I turned it off using HA, and which logged in user performed that action.
The question is, how can we expose that information.

3 Likes

Every state change has s context id associated with it. When is turned off physically I believe is empty.

1 Like

So that is in the SQL db for the recorder log, can it be exposed during an automation?

The answer is yes!

self._context

I’m keen to see the outcome of this. I know that the Adaptive Lighting custom component can determine if a light was turned on by HA or locally but haven’t seen how to do it outside of that.

I DID IT!!! At least the part where a dashboard entry makes the change

I am simultaneously not proud of myself for spending this much time, but also proud for finding a solution.

This code specifically will detect if an automation was trigged from a a user id context, like from the UI. I have tested this with a light and nothing else, but it works. This SPECIFIC code looks for the absence of a user ID, like if I turned on the light from the wall, and not from the HA UI

alias: New Automation
description: ''
trigger:
  - platform: state
    entity_id: light.living_room_main_lights
condition:
  - condition: template
    value_template: '{{ trigger.to_state.context.user_id == none }}'
action:
  - event: lr_lights_changed
    event_data: {}
mode: single

The automation trigger is the entity STATE change you are looking for, the condition is lack of user id context, and the action is what you want to do when there is no user

19 Likes

That’s awesome! I can’t wait to test this out for my kitchen light. Thanks for sharing.

aaand I got it to ignore automations as well, add the following condition:

condition:
  - condition: template
    value_template: '{{ trigger.to_state.context.parent_id == none }}'

If there is no parent ID, there was no automation or script above this one
And if there i no user ID, it was not done from the UI
Therefore it was done at the device (if I am wrong let me know)

8 Likes

I kinda knew HA had this functionality now, but I hadn’t really tried it out yet. So don’t worry, your time was also useful for others :wink:

1 Like

I would like to receive events of who turned on the light, home assistant, or person. Reading a post here, I put together such automation and it works. Defines correctly, but I think that you can do it differently and correctly. How to write automation correctly so that you can get a notification who turned on the light, home assistant or a person?

Мне бы хотелось получать события кто включил свет, home assistant или человек. Читая тут пост, я собрал такую автоматизацию и она работает. Определяет правильно, но мне думается, что можно сделать по другому и правильно. Как правильно написать автоматизацию, чтобы можно было получить уведомление, кто включил свет, home assistant или человек?

alias: 'who turned on the light, the home assistant or the person?'
description: ''
trigger:
  - platform: state
    entity_id: light.yeelight_stripe_0x0000000007000
condition: []
action:
  - choose:
      - conditions:
          - condition: template
            value_template: '{{ trigger.to_state.context.user_id == none }}'
          - condition: template
            value_template: '{{ trigger.to_state.context.parent_id == none }}'
        sequence:
          - service: notify.notify
            data:
              message: The light was turned on by a man
      - conditions:
          - condition: template
            value_template: '{{ trigger.to_state.context.user_id == none }}'
        sequence:
          - service: notify.notify
            data:
              message: The light turned on the Home Assistant
    default: []
mode: single
3 Likes

I created an automation that turns off the rest mode if the ceiling chandelier turns on automatically, and if I turn on the ceiling chandelier myself, the rest mode will not turn off. This code below works if I use a selection, but if I don’t use a selection and only a condition and an action, then this option doesn’t work. What is the right way to avoid using selection and to make automation work?

Создал автоматизацию которая выключает режим отдыха, если потолочная люстра включится автоматически, а если я включу потолочную люстру сам, то режим отдыха не выключится. Данный код ниже работает, если я использую выбор, но если я не буду использовать выбор и только условие и действие, то данный вариант не работает. Как правильно сделать, чтобы не использовать выбор и чтобы автоматизация работала?

  alias: 'Turn off the rest mode when the ceiling chandelier is turned on'
  description: If you turn on the ceiling chandelier via the voice assistant Alice, the rest mode will turn off
  trigger:
  - platform: device
    type: turned_on
    device_id: 1bx2b4c9a1b1bd26226sc4y13c090n12
    entity_id: light.yeelight_ceiling4_0x00000000100000
    domain: light
  condition:
  - condition: state
    entity_id: switch.tv
    state: 'on'
  - condition: state
    entity_id: input_boolean.relax_mode
    state: 'on'
  action:
  - choose:
    - conditions:
      - condition: template
        value_template: '{{ trigger.to_state.context.user_id == none }}'
      - condition: template
        value_template: '{{ trigger.to_state.context.parent_id == none }}'
      sequence: []
    - conditions:
      - condition: template
        value_template: '{{ trigger.to_state.context.parent_id == none }}'
      sequence:
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.relax_mode
    default: []
  mode: single
1 Like

Nicely done, thanks for sharing!

Hey guys, I just can’t get this method working.

In my Automation I have a switch.0 that can be turned on either by Home Assistant (another automation) or a user. So I am trying to accomplish the same as a topicstarter - Run action (switch off particular device) if the switch.0 was turned on automatically and do nothing in case if it was activated by user/person/me. In case my second trigger alongside with conditions (numeric state) launches action, I can’t get it working (switch isn’t turned off) in case switch.0 was automatically turned on.

alias: Swimpool Filtration 8HR off
description: ''
trigger:
  - platform: state
    entity_id: sensor.swimpool_filtration_on, switch.0
condition:
  - condition: numeric_state
    entity_id: sensor.swimpool_filtration_on
    above: '9'
  - condition: state
    entity_id: switch.sonoff_10011b1ed2
    state: 'off'
    for:
      hours: 0
      minutes: 1
      seconds: 0
      milliseconds: 0
action:
  - choose:
      - conditions:
          - condition: template
            value_template: '{{ trigger.to_state.context.user_id == none }}'
          - condition: template
            value_template: '{{ trigger.to_state.context.parent_id == none }}'
        sequence: []
      - conditions:
          - condition: template
            value_template: '{{ trigger.to_state.context.parent_id == none }}'
        sequence:
          - service: switch.turn_off
            target:
              entity_id:
                - switch.0
mode: single
1 Like

All in all, a good idea and work…! :slight_smile:

However, the solution only works if you use the Home Assistant app to “switch on and off manually”. Unfortunately, this does not work with HomeKit.

Or can you evaluate a user ID, ID or name from HomeKit? It is also shown in the log file that a switching operation was carried out by HomeKit.

I realize I am reviving an old post (there is a similar post with “Triggered By” in the title) - here is what seems to happen:

  • If there is a user_id, it is always the UI in HA
  • If user_id == none and there is a parent_id, it is an automation
  • If user_id == none and parent_id == none it can either be physical switch (or something else outside of HA) or it can be an HA automation under certain conditions. So it is does not work in all cases

The problem comes when user_id == none and parent_id == none - this should always be the physical switch (or something programmatic outside of HA, e.g., ISY program). And the above is true for almost all automations - however, there seems to be at least one exception:

  • let’s say automation a changes the state of Entity target and automation b is an automation triggered by a state change in target and is also testing for what triggered it with the context values we specified in the bullet list above
  • then automation b should have a parent_id, but will still show parent_id as none if the trigger in automation a is only a time pattern trigger (I have not tried a time trigger yet) - so, something about Time Pattern triggers does not pass a parent_id, but others like State and Sun do. I am not sure why.

So, if you want this to work consistently, you will want that parent to have a trigger that sends a parent_id value. Since input helper state change does send down a parent, it is better to have the time pattern trigger a helper whose state change trigger then executes the action that triggers the next automation.

This is really a workaround and the better real solution would be for HA to have a parent_id for any trigger events in the parent when the source of the state change is an HA automation of any kind.

If anyone else has seen different behaviors or has a more elegant solution, I would love to improve on this.

2 Likes