2 lamps. The goal is that when the button of one lamp is pressed, the other one turns on/off as well. I use AppDaemon.
This works fine so far. The problem is in some circumstances the new_state reports wrong values.
The easiest way to reproduce this:
I toggle switch1 → switch2 turns on. Within 2 seconds I toggle switch2. In this case new_state.context.user_id is Not Null. But it should be Null.
But if i wait 5 seconds instead of 2, Everything works fine.
Is there a better way to detect a physical interaction? I understand that fast interaction is not a normal usecase, but either way it should not report wrong data.
Setup:
- switch1: [TuYa WHD02 control via MQTT | Zigbee2MQTT]
- switch2: [TuYa TS0001_power control via MQTT | Zigbee2MQTT]
- Each mounted behind a physical toggle switch
- Each has a lamp attached to its relay
- Connected to HA via Zigbee2Mqtt
AppDaemon Script:
import appdaemon.plugins.hass.hassapi as hass
#https://community.home-assistant.io/t/interaction-attribute-for-entites/450159
# ID combos: https://community.home-assistant.io/t/work-with-triggered-by-in-automations/400352/8
#interaction id parent_id user_id
#Physical Not Null Null Null
#Automation Not Null Not Null Null
#UI Not Null Null Not Null
class MyTestClass(hass.Hass):
def initialize(self):
self.log("Hello from AppDaemon")
self.listen_event(
self.listen_state_change,
"state_changed"
)
#self.switch_changed(self.test, "switch.schalter_1_kuche")
def listen_state_change(self, event, data, cb_args):
entity = data['entity_id']
switch1 = "switch.schalter_1_kuche"
switch2 = "switch.schalter_2_kuche"
if entity == switch1 or entity == switch2:
self.log("----------STATE CHANGED EVENT----------")
context = data['new_state']['context']
interaction, user = self.determine_interaction(context)
self.log("NEW Interaction: {}, User: {}, Switch: {}".format(interaction, user, entity))
old_context = data['old_state']['context']
old_interaction, old_user = self.determine_interaction(old_context)
self.log("OLD Interaction: {}, User: {}, Switch: {}".format(old_interaction, old_user, entity))
new_state = data['new_state']['state']
if interaction == "physical":
if entity == switch1:
if new_state == "on":
self.turn_on(switch2)
self.log("OFF triggered by switch1")
else:
self.turn_off(switch2)
self.log("OFF triggered by switch1")
elif entity == switch2:
if new_state == "on":
self.turn_on(switch1)
self.log("ON triggered by switch2")
else:
self.turn_off(switch1)
self.log("OFF triggered by switch2")
def determine_interaction(self, context):
id = context.get("id")
parent_id = context.get("parent_id")
user_id = context.get("user_id")
if id is not None and parent_id is None and user_id is None:
interaction = "physical"
user = "unknown"
elif id is not None and parent_id is not None and user_id is None:
interaction = "automation"
user = "unknown"
elif id is not None and parent_id is None and user_id is not None:
interaction = "ui"
user = user_id
else:
interaction = "unknown"
user = "unknown"
return interaction, user