MQTT timing issue: Wrong user for "new state"

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.


AppDaemon Script:

import appdaemon.plugins.hass.hassapi as hass


# ID combos:
#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.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.log("OFF triggered by switch1")
                        self.log("OFF triggered by switch1")
                elif entity == switch2:
                    if new_state == "on":
                        self.log("ON triggered by switch2")
                        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
            interaction = "unknown"
            user = "unknown"

        return interaction, user

Why not use listen_state() and get_state() instead?

This is where I came from. Then I tried fishing out the event. Same problem.
I simplified it to:

import appdaemon.plugins.hass.hassapi as hass

class MyTestClass(hass.Hass):

    def initialize(self):
        self.log("Hello from AppDaemon")

    def my_callback(self, entity, attribute, old, new, kwargs):
        self.log("----------STATE CHANGED EVENT----------")
        context=self.get_state(entity, attribute="context")

With just this, everything reports properly and snappy. Buth when I toggle a switch by script, I need to wait 1-2sec before it will report a physical interation without a user_id.

There’s ready made blueprints for this exact scenarios you can try if rolling your own is causing you issues.

In no particular order:

Thank you for your inpunts. I tested a few of these. Basically I run into the same problem as before. They work, but when toggle switch A and then within 1-2 sec switch B, only switch B acts.
I will take a closer look into it in the coming week.