Using classes and inheritance cause problems with lingering triggers #653
-
|
So I tried to be clever and structure my code into classes. It works, kind of. I created a base class for the zha event, then classes for different devices that inherit from the base class, and then I created instanses of the classes in several script files (pyscript/scripts/). The base class creates a list of triggers that is attached to But if I don't have a reference to the instance (remove What am I missing here? This is basically how I implemented it: pyscript/modules/zha.py: class ZhaEventBase:
def __init__(self):
# Cannot use `super().__init__()` so use `zha_event_base()` instead
pass
def zha_event_base(self,
device_id:str,
command_callbacks:dict):
"""
`command_callbacks` is a flat dictonary with `"command": callback`.
"""
self.triggers = []
for command, callback in command_callbacks.items():
if callback is not None:
log.debug(f"Registering command '{command}'")
@event_trigger("zha_event", f"device_id == '{device_id}' and command == '{command}'")
def zha_event_callback(device_id=None, command=None, args=None, **kwargs):
callback(device_id, command, args)
self.triggers.append(zha_event_callback)pyscript/modules/philips_hue.py: from zha import ZhaEventBase
class WallSwitch(ZhaEventBase):
def __init__(self,
device_id:str,
command_callbacks:dict):
self.zha_event_base(device_id, command_callbacks, debug)pyscript/scripts/hallway.py: from philips_hue import WallSwitch
def wall_switch_toggle(device_id, command, args):
log.debug(f"wall_switch_toggle, {command=}")
ws_hallway = WallSwitch("123456778888888888",
{
"left_press_release": wall_switch_toggle,
}) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
Just to add my 2 cents because I've tripped over this recently so I can confirm this still happens. The issue as far as I can tell is with how destructors work....or rather don't work. In a basic class you can add @pyscript_compile decorators to the destructor (and explicitly call My suggestion is to avoid calling the constructor in the global scope of the module. This is because it will be called when the module is loaded which can lead to issues depending on load order wrt entites. Instead, construct the objects in a startup function. Then similarly have a For some or other reason, the derrived dtor will never call into a base class function....or at least I couldn't get it to work without |
Beta Was this translation helpful? Give feedback.
Just to add my 2 cents because I've tripped over this recently so I can confirm this still happens.
The issue as far as I can tell is with how destructors work....or rather don't work. In a basic class you can add @pyscript_compile decorators to the destructor (and explicitly call
del, however for classes with inheritence, this trick still doesn't work. Even constructors dont work in this instance.My suggestion is to avoid calling the constructor in the global scope of the module. This is because it will be called when the module is loaded which can lead to issues depending on load order wrt entites. Instead, construct the objects in a startup function.