diff --git a/pyplumio/devices/__init__.py b/pyplumio/devices/__init__.py index 9cc4009e..fb7a1ecd 100644 --- a/pyplumio/devices/__init__.py +++ b/pyplumio/devices/__init__.py @@ -133,7 +133,7 @@ def __init__(self, queue: asyncio.Queue[Frame], network: NetworkInfo): def handle_frame(self, frame: Frame) -> None: """Handle frame received from the device.""" - frame.sender_device = self + frame.assign_to(self) if frame.data is not None: for name, value in frame.data.items(): self.dispatch_nowait(name, value) diff --git a/pyplumio/frames/__init__.py b/pyplumio/frames/__init__.py index 2f8a302e..d2652f63 100644 --- a/pyplumio/frames/__init__.py +++ b/pyplumio/frames/__init__.py @@ -73,22 +73,20 @@ class Frame(ABC): __slots__ = ( "recipient", - "recipient_device", "sender", - "sender_device", "econet_type", "econet_version", + "_handler", "_message", "_data", ) recipient: DeviceType - recipient_device: PhysicalDevice | None sender: DeviceType - sender_device: PhysicalDevice | None econet_type: int econet_version: int frame_type: ClassVar[FrameType] + _handler: PhysicalDevice | None _message: bytearray | None _data: dict[str, Any] | None @@ -104,11 +102,10 @@ def __init__( ) -> None: """Process a frame data and message.""" self.recipient = recipient - self.recipient_device = None self.sender = sender - self.sender_device = None self.econet_type = econet_type self.econet_version = econet_version + self._handler = None self._data = data if not kwargs else ensure_dict(data, kwargs) self._message = message @@ -153,6 +150,15 @@ def hex(self, *args: Any, **kwargs: Any) -> str: """Return a frame message represented as hex string.""" return self.bytes.hex(*args, **kwargs) + def assign_to(self, device: PhysicalDevice) -> None: + """Assign device handler to the frame.""" + self._handler = device + + @property + def handler(self) -> PhysicalDevice | None: + """Return the frame handler.""" + return self._handler + @property def data(self) -> dict[str, Any]: """Return the frame data.""" diff --git a/pyplumio/structures/regulator_data.py b/pyplumio/structures/regulator_data.py index f4a9b25a..194468ce 100644 --- a/pyplumio/structures/regulator_data.py +++ b/pyplumio/structures/regulator_data.py @@ -53,7 +53,7 @@ def decode( message, offset + 2, data ) - if (device := self.frame.sender_device) is not None and ( + if (device := self.frame.handler) is not None and ( schema := device.get_nowait(ATTR_REGDATA_SCHEMA, []) ): self._bitarray_index = 0 diff --git a/pyplumio/structures/thermostat_parameters.py b/pyplumio/structures/thermostat_parameters.py index 1a4e8340..8b545db3 100644 --- a/pyplumio/structures/thermostat_parameters.py +++ b/pyplumio/structures/thermostat_parameters.py @@ -247,7 +247,7 @@ def decode( self, message: bytearray, offset: int = 0, data: dict[str, Any] | None = None ) -> tuple[dict[str, Any], int]: """Decode bytes and return message data and offset.""" - if (device := self.frame.sender_device) is not None and ( + if (device := self.frame.handler) is not None and ( thermostats := device.get_nowait(ATTR_THERMOSTATS_AVAILABLE, 0) ) == 0: return ( diff --git a/tests/frames/test_messages.py b/tests/frames/test_messages.py index 5d8ee818..e1362509 100644 --- a/tests/frames/test_messages.py +++ b/tests/frames/test_messages.py @@ -36,9 +36,9 @@ def test_messages_type() -> None: async def test_regulator_data_message(ecomax: EcoMAX, schema, regdata) -> None: """Test a regulator data message.""" frame = RegulatorDataMessage(message=regdata["message"]) - frame.sender_device = ecomax - frame.sender_device.load_nowait(schema["data"]) - await frame.sender_device.wait_until_done() + frame.assign_to(ecomax) + ecomax.load_nowait(schema["data"]) + await ecomax.wait_until_done() if regdata["id"] == "unknown_regulator_data_version": assert ATTR_FRAME_VERSIONS not in frame.data diff --git a/tests/frames/test_responses.py b/tests/frames/test_responses.py index f8c26826..2654bdcf 100644 --- a/tests/frames/test_responses.py +++ b/tests/frames/test_responses.py @@ -123,9 +123,9 @@ def test_schedules_response(message, data) -> None: async def test_thermostat_parameters_response(ecomax: EcoMAX, message, data) -> None: """Test a thermostat parameters response.""" frame = ThermostatParametersResponse(message=message) - frame.sender_device = ecomax - frame.sender_device.load_nowait({ATTR_THERMOSTATS_AVAILABLE: 3}) - await frame.sender_device.wait_until_done() + frame.assign_to(ecomax) + ecomax.load_nowait({ATTR_THERMOSTATS_AVAILABLE: 3}) + await ecomax.wait_until_done() assert frame.data == data