Candeo C203 + ZHA – can HA distinguish physical wall-switch operation from an automation?

Candeo C203 + ZHA – can HA distinguish physical wall-switch operation from an automation?

I’m planning a new installation using Home Assistant Green + Connect ZBT-2/ZHA with Candeo C203 Zigbee dimmer modules. The C203s will have wired retractive wall switches connected to their physical switch input.

I need Home Assistant to distinguish reliably between:

  1. Home Assistant turning or dimming the C203 via Zigbee, and
  2. somebody physically pressing/holding the wired retractive wall switch connected to the C203.

The use case is:

  • Motion detected between sunset and 23:00 → lights on at 80%
  • Motion detected between 23:00 and sunrise → lights on at 30%
  • If the lights were turned on by motion → switch off after 3 minutes of no motion
  • If somebody physically operates the wall switch → treat that as manual override, set/leave the lights at 80%, cancel or ignore the automatic off timer, and leave them on until manually switched off

Does the C203 under ZHA expose physical operation of its wired switch input as a distinct event, command, attribute or other reliable indicator that a Home Assistant automation can trigger on?

I’m specifically trying to avoid simply inferring manual operation from the light’s state changing, because Home Assistant itself may have caused that same state change.

If the C203 does not expose a distinct physical-switch event under ZHA, is there another reliable way to implement this manual-override behaviour?

@Candeo – I’d particularly appreciate confirmation of what the C203 actually reports over Zigbee when its wired retractive input is operated.

I do not have the specific device setup, don’t know what your devices are capable of, so wouldn’t know for certain, but if you are asking “Whether HA is capable of distinguish physical operations?” The short answer is a “yes.”

  • My wall switch (Inovelli) would report back clicks to HA as an event
  • And if some automation rans, another activity would show up
  • Furthermore, if someone logged into HA frontend / dashboard and then toggled the said switch, HA would show who (the log-in user) is turning on/off the light.

Good question, and yes, this is doable. First, subscribe to zha_event in Developer Tools → Events and press the wall switch: most in-wall dimmers with a wired input (Candeo included) fire a distinct ZHA event when the physical input changes, and you can trigger a “manual override” helper directly from that event. If the C203 doesn’t send a distinct event, the reliable fallback is checking the state change’s context in your automation: when your motion automation changes the light, trigger.to_state.context.parent_id is set, while a physical press has no parent context, so a condition like {{ trigger.to_state.context.parent_id is none }} reliably marks manual overrides. Feed that into a helper or timer your auto-off automation checks before switching off, and physical presses will cleanly pause the motion logic.

One catch with the parent_id check, from my own database. Changes made by my automations were clean, only one was followed by a no-parent echo on the same light in two weeks. But 873 of my 1,149 light changes with no parent and no user came from three bulbs in a Zigbee2MQTT group. My automation turns the group on, and within a quarter second each bulb reports its new state over MQTT with no context at all, while the group entity keeps the parent_id. I’m on Zigbee2MQTT, so I don’t know if ZHA groups do the same.

Here, read this: How to use context. It explains how to do it universally within HA without relying on manufacturer-specific implementations.

Thanks – that’s really helpful. When you say “Candeo included” fire a distinct ZHA event, do you know specifically whether the Candeo C203 does this when its wired retractive input is pressed/held?

If so, do you know what zha_event / command is generated? That’s the bit I’m particularly trying to confirm, as I’d much rather trigger the manual override from an explicit physical-input event than infer it from context.

Thanks – that’s helpful. The key thing I’m trying to pin down is whether the Candeo C203 itself exposes a physical press on its wired retractive input distinctly enough for HA to use it as a manual override trigger.

Thanks – that’s exactly the sort of edge case I was concerned about. I’m planning to use ZHA rather than Zigbee2MQTT, but it sounds like relying purely on context/parent_id may not be quite as bulletproof as an explicit physical-switch event.

Thanks – I’ll read that. I’m especially interested in whether context is reliable enough here if the C203 doesn’t expose a distinct physical-input event, as I need manual wall control to reliably override the motion timer.

I don’t know what the C203 sends either. From the HA code, a light’s own state updates within 5 seconds of a command sent to that light keep the command’s context. My automation sends the command to the group entity, not to the bulbs, and none of the bulbs’ updates had a context. Once yours are in, this counts each light’s real on/off flips from the last 7 days by context, leaving out brightness changes and returns from unavailable.

SELECT states_meta.entity_id,
  SUM(states.context_user_id_bin IS NOT NULL) AS by_user,
  SUM(states.context_user_id_bin IS NULL AND states.context_parent_id_bin IS NOT NULL) AS by_automation,
  SUM(states.context_user_id_bin IS NULL AND states.context_parent_id_bin IS NULL) AS no_context
FROM states
JOIN states_meta ON states.metadata_id = states_meta.metadata_id
JOIN states AS old ON old.state_id = states.old_state_id
WHERE states_meta.entity_id LIKE 'light.%'
  AND states.state IN ('on', 'off')
  AND old.state IN ('on', 'off')
  AND old.state <> states.state
  AND states.last_updated_ts > strftime('%s', 'now', '-7 days')
GROUP BY states_meta.entity_id
ORDER BY no_context DESC

I ran the same counts on my Postgres and tried this SQLite version on an empty copy of HA’s schema with fake rows.