Determine if switch was turned on by human or HA (reliably?)

Hello! First post, n00b to HA!

I spent hours trying to figure this out.

“SHORT” question: How do I reliably determine that a light-switch toggle was the result of a HA automation?

I’ve seen the suggestion to use trigger.to_state.context.parent == none, which works when the light turns on via motion, but it doesn’t work on another automation, where I turn the lights off via a time_pattern & motion check. Inspecting the trace.json, I don’t see anything I can key off of.

LONGER explanation:
GOAL (and I’m sure this is common):

  • Motion detected, lights turn on
  • Human powers off the switch. He must want it that way.
  • Do not automate anything with those lights until there has been no motion or further manual control of that switch for some cool down period

Automations I’ve got so far:
Motion detected:

  • if manual_control_timer active, restart timer
  • else, turn on light
  • (this gets correctly identified as a HA automation, vs a human interaction)

Every 30 seconds

  • if no motion has been detected for 20min, and manual_control_timer not active, turn off light
  • This one is the problem - when this automation turns off the light, it triggers the next automation, bc I don’t know what to key off of to identify it as an automation vs a manual control

ON light switch ToGGLE

  • if trigger.to_state.context.parent_id == none (a human toggled it, but doesn’t seem reliable), we restart the manual_control_timer
  • This one restarts the timer regardless, bc parent_id is always none, and gets me stuck in an infinite manual control

Anyways - thank you so much for any advice. Other than that one detection, I think this setup would work pretty sweet

Take a look into “entity_controller” component as it may do what you want (or you can grab some ideas from there):

1 Like

Thank you. I’ve seen that repo, and may go that route, but I’d like to try to get it working vanilla, first.

trigger.to_state.context.user_id

user_id will contain a long alphanumeric string if it was a user (otherwise none).

Search for context.user_id and you’ll find examples of how it is employed.

NOTE

Another technique, that is reliable, uses switches that can report their button actions (pressed, released, etc). Several z-wave, zigbee, and UPB switches support this feature.

Another way is to detect a dimmer switch’s brightness change (i.e. motion turns on the light to a preset level and if that level is changed by the user then it indicates the user wants manual control and the auto-off feature is temporarily disabled).

In all of my testing, user_id is always null (unless I trigger something from the dashboard). Maybe I missed something there.

About the zigbee reporting note: interesting! I didn’t know that. I’m using all wifi switches currently, but even if I was able to detect physical button pushes, I’d still want to group them as manual-actions alongside google-assistant comments.

In the meantime, I’ve “solved”/bypassed my lack of being able to detect if it was triggered by HA by updating the cron auto-off task from

turn off lights

to

disable disable-automaton automation
turn off lights
enable disable-automation automation

Feels a bit improper, but it works. I feel like HA should have a reliable way to determine what I’m looking for, though.

Yes, there is to my knowledge no possibility to know if someone pushed the physical switch, or an automation triggered it. At least not with Tasmota switches.

You didn’t miss anything, that’s how it works. For user_id to contain a value, the user must login to Home Assistant and control an entity via the Lovelace UI.

If someone manually operates a switch, you can use the techniques I detect it.

It is improper. Disabling/re-enabling automations as part of normal operations is an anti-pattern.

What kind of switch is it?

I use node red for a lot of automations following this guide to set it up Installing Node Red in Docker for Home Assistant | by Jordan Rounds | Medium

Part of the guide is creating a “node red” user in Home Assistant. With that setup, I see in my history if node red controlled devices automatically versus manually controlled one’s.

I’m kind of surprised the home assistant automations don’t show different in the history versus manual control…

?

I use automations and the Logbook indicates which devices were turned off by an automation using the automation’s name (not a generic Node-Red user). The devices controlled by a user via the UI indicate the user’s name. Devices controlled via their physical switches (manual control) show no identification.

Thanks I figured I was probably missing something easy here because I knew I saw that somewhere in the past. The history screen of the entity definitely doesn’t give as much detail as the logbook.

I have some node red automations that keep track of how a light was controlled by storing variables. I’m not sure if/how variables can be used in Home Assistant automations to possibly keep track of manual versus automatic control of a light though, but just another possible idea here.

I’ve also used your brightness change idea and that seems to be the simplest solution here if its a dimmer.

OP here. As a new HA user, I keep switching up my approach to motion-controlled lights.
I’ve since “refined” my logic to use timers instead of the “for” attribute.
This is the kitchen, for example.

when motion detected:
    if timer is idle:
        turn on lights
   start timer
   pause timer (immediately, so it's stuck at 20 minutes, for example)
when motion clear
    start timer
when timer completes:
    turn off lights

So far, I’ve really been liking the timer approach, as I can see the countdown in the UI, and it is easy to debug/test by manually finishing/starting timers. Other actions can also reset the timer, like opening the fridge, etc, which may be just out of motion-sensor FOV. gracefully handles the “purposefully turn off the light” scenario, as the timer keeps the light off as long as you’re in the room, + 20 minutes (or whatever).

Sometimes I sit at the kitchen island and work, motionless, so I may add an extra feature where the lights occasionally pulse, reminding me to move when the timer is approaching it’s end.