Z2M - Detect what triggered in wall switch: manual push vs automation / interface

I’ve recently changed some zwave in wall switches to Zigbee ones, and can’t find a way to determine whether the connected light turns on or off due to the actual wall switch being flipped or due to an event triggered by HA (automation triggered by motion, or a click in my dashboard for example).

With Zwave; scene-events were triggered next to the actual state change of the light.

Is there a way to do this with Z2M? I’ve listened to all events in the HA dev tools, but don’t see any differences there, and also looked at the logs in Z2M, but I can’t see a trigger there either.

Example of the Z2M debug log; the light (Dimmer - Keuken Spots l1) is first turned on via the wall switch, then turned off via the HA Dashboard.

Debug 2023-04-16 14:07:31Received Zigbee message from 'Dimmer - Keuken Spots', type 'attributeReport', cluster 'genOnOff', data '{"onOff":1}' from endpoint 1 with groupID 0
Info 2023-04-16 14:07:31MQTT publish: topic 'zigbee2mqtt/Dimmer - Keuken Spots', payload '{"brightness":155,"brightness_l1":155,"brightness_l2":255,"linkquality":135,"max_brightness":255,"min_brightness":4,"power_on_behavior":"previous","power_on_behavior_l1":"previous","power_on_behavior_l2":"previous","state_l1":"ON","state_l2":"ON","switch_type_l1":"momentary","switch_type_l2":"toggle"}'
Info 2023-04-16 14:07:31MQTT publish: topic 'zigbee2mqtt/Dimmer - Keuken Spots/l1', payload '{"brightness":155,"power_on_behavior":"previous","state":"ON","switch_type":"momentary"}'
Info 2023-04-16 14:07:31MQTT publish: topic 'zigbee2mqtt/Dimmer - Keuken Spots/l2', payload '{"brightness":255,"power_on_behavior":"previous","state":"ON","switch_type":"toggle"}'
Debug 2023-04-16 14:07:54Received MQTT message on 'zigbee2mqtt/Dimmer - Keuken Spots/l1/set' with data '{"state":"OFF"}'
Debug 2023-04-16 14:07:54Publishing 'set' 'state' to 'Dimmer - Keuken Spots'
Info 2023-04-16 14:07:54MQTT publish: topic 'zigbee2mqtt/Dimmer - Keuken Spots', payload '{"brightness":155,"brightness_l1":155,"brightness_l2":255,"linkquality":141,"max_brightness":255,"min_brightness":4,"power_on_behavior":"previous","power_on_behavior_l1":"previous","power_on_behavior_l2":"previous","state_l1":"OFF","state_l2":"ON","switch_type_l1":"momentary","switch_type_l2":"toggle"}'
Info 2023-04-16 14:07:54MQTT publish: topic 'zigbee2mqtt/Dimmer - Keuken Spots/l1', payload '{"brightness":155,"power_on_behavior":"previous","state":"OFF","switch_type":"momentary"}'
Info 2023-04-16 14:07:54MQTT publish: topic 'zigbee2mqtt/Dimmer - Keuken Spots/l2', payload '{"brightness":255,"power_on_behavior":"previous","state":"ON","switch_type":"toggle"}'
Debug 2023-04-16 14:07:55Received Zigbee message from 'Dimmer - Keuken Spots', type 'attributeReport', cluster 'genLevelCtrl', data '{"61440":0,"currentLevel":0}' from endpoint 1 with groupID 0
Info 2023-04-16 14:07:55MQTT publish: topic 'zigbee2mqtt/Dimmer - Keuken Spots', payload '{"brightness":0,"brightness_l1":0,"brightness_l2":255,"linkquality":138,"max_brightness":255,"min_brightness":4,"power_on_behavior":"previous","power_on_behavior_l1":"previous","power_on_behavior_l2":"previous","state_l1":"OFF","state_l2":"ON","switch_type_l1":"momentary","switch_type_l2":"toggle"}'
Info 2023-04-16 14:07:55MQTT publish: topic 'zigbee2mqtt/Dimmer - Keuken Spots/l1', payload '{"brightness":0,"power_on_behavior":"previous","state":"OFF","switch_type":"momentary"}'
Info 2023-04-16 14:07:55MQTT publish: topic 'zigbee2mqtt/Dimmer - Keuken Spots/l2', payload '{"brightness":255,"power_on_behavior":"previous","state":"ON","switch_type":"toggle"}'

@duncank
try this code. Not my work. I found this here several months ago and played with it a bit. YMMV.

##########################################################
## Diagnostic: What caused the State Change
##########################################################
- id: what_caused_the_state_change
  alias: What caused the State Change
  description: 'What caused the State Change'
  initial_state: false. # REMEMBER TO TURN BACK TO TRUE!
  mode: queued
  trigger:
  - platform: state
    entity_id:
    - light.kitchen_can_lights_49
    - light.kitchen_pendants_106
    - light.garage_fan_225
    - switch.2_car_opener_relay_88
    - light.office_light_223
  condition:
  - condition: state
    entity_id: input_boolean.log_diagnostics
    state: 'on'
  action:
  # Physical
  - choose:
    - conditions:
      - condition: template
        value_template: '{{ trigger.to_state.context.parent_id == none }}'
      - condition: template
        value_template: '{{ trigger.to_state.context.user_id == none }}'
      - condition: template
        value_template: '{{ trigger.to_state.context.id != none }}'
      sequence:
      - service: variable.set_variable
        data:
          variable: vh_diagnostic_message
          value: '{{ trigger.entity_id }} likely Physical switched to {{ trigger.to_state.state |upper }}'
          attributes:
            parent_id: '{{ trigger.to_state.context.parent_id }}'
            user_id: '{{ trigger.to_state.context.user_id }}'
            context_id: '{{ trigger.to_state.context.id }}'
  # Automation
    - conditions:
      - condition: template
        value_template: '{{ trigger.to_state.context.parent_id != none }}'
      - condition: template
        value_template: '{{ trigger.to_state.context.user_id == none }}'
      - condition: template
        value_template: '{{ trigger.to_state.context.id != none }}'
      sequence:
      - service: variable.set_variable
        data:
          variable: vh_diagnostic_message
          value: '{{ trigger.entity_id }} likely Automation switched to {{ trigger.to_state.state |upper }}'
          attributes:
            parent_id: '{{ trigger.to_state.context.parent_id }}'
            user_id: '{{ trigger.to_state.context.user_id }}'
            context_id: '{{ trigger.to_state.context.id }}'
  # User Interface
    - conditions:
      - condition: template
        value_template: '{{ trigger.to_state.context.parent_id == none }}'
      - condition: template
        value_template: '{{ trigger.to_state.context.user_id != none }}'
      - condition: template
        value_template: '{{ trigger.to_state.context.id != none }}'
      sequence:
      - service: variable.set_variable
        data:
          variable: vh_diagnostic_message
          value: '{{ trigger.entity_id }} likely UI switched to {{ trigger.to_state.state |upper }}'
          attributes:
            parent_id: '{{ trigger.to_state.context.parent_id }}'
            user_id: '{{ trigger.to_state.context.user_id }}'
            context_id: '{{ trigger.to_state.context.id }}'
    default: []
#

I hope this helps. You may be able to find the original post by searching for: [ trigger.to_state.context.user_id != none] . Good luck!

1 Like

Thanks so much; this does exactly what I was looking for.
I’ve created a quick test where I get notifications on what caused the state changes, and it detects UI, Physical and Automation-triggered changes perfectly.