diff --git a/umnp/microcontroller/communication/udp_communicator.py b/umnp/microcontroller/communication/udp_communicator.py index a713209cfe11185d5d107d6259f07f41e421bb5b..54e835fa6655fb376b6fccd38cb0a9924e686423 100644 --- a/umnp/microcontroller/communication/udp_communicator.py +++ b/umnp/microcontroller/communication/udp_communicator.py @@ -22,8 +22,8 @@ else: class UDPCommunicator: def __init__( self, - sender: UDPSender, - receiver: UDPReceiver, + sender: UDPSender | None, + receiver: UDPReceiver | None, device: "MeasurementDevice", max_msgs: int = 10, ): @@ -44,18 +44,28 @@ class UDPCommunicator: @property def network_error(self): - return self._sender.error + if self._sender: + return self._sender.error + else: + return None def clear_network_error(self): - self._sender.reset_error() + if self._sender: + self._sender.reset_error() async def queue_incoming_message(self, msg, source): + if self._receiver is None: + return + async with self._receive_lock: self._messages_received.append((msg, source, time.time())) while len(self._messages_received) > self._max_msgs: self._messages_received.pop(0) async def get_newest_message(self): + if self._receiver is None: + return + async with self._receive_lock: if len(self._messages_received): return self._messages_received.pop(0) @@ -64,7 +74,8 @@ class UDPCommunicator: async def receive_task(self): while True: - await self._receiver.receive(self) + if self._receiver: + await self._receiver.receive(self) await asyncio.sleep(0.500) async def send_task(self): @@ -78,12 +89,19 @@ class UDPCommunicator: await asyncio.sleep(0.5) continue + if self._sender is None: + await asyncio.sleep(0.1) + continue + if isinstance(msg, Message): await self._sender.broadcast(msg.encode()) await asyncio.sleep(0.5) async def send_message(self, msg: Message): + if self._sender is None: + return + self._messages_send_queue.append(msg) async def control_task(self): @@ -95,10 +113,12 @@ class UDPCommunicator: await asyncio.sleep(0.5) async def start(self): - receiver = asyncio.create_task(self.receive_task()) - sender = asyncio.create_task(self.send_task()) - controller = asyncio.create_task(self.control_task()) + receive_task = asyncio.create_task(self.receive_task()) + send_task = asyncio.create_task(self.send_task()) + control_task = asyncio.create_task(self.control_task()) + tasks = [] + for name, task in self._tasks.items(): result = asyncio.create_task(task.run()) tasks.append(result) @@ -106,9 +126,9 @@ class UDPCommunicator: for t in tasks: await t - await receiver - await sender - await controller + await receive_task + await send_task + await control_task def add_task(self, task: PeriodicTask, name: str): self._tasks[name] = task diff --git a/umnp/microcontroller/measurementdevice.py b/umnp/microcontroller/measurementdevice.py index 72aba1739ac974904463b06a52952883443c7772..bf27ad29eda497758794e63f13caf3b9ac549bc9 100644 --- a/umnp/microcontroller/measurementdevice.py +++ b/umnp/microcontroller/measurementdevice.py @@ -11,6 +11,7 @@ from umnp.microcontroller.devices.network.udp import ( DEFAULT_UMNP_COMMAND_IN_PORT, ) from umnp.proto import DeviceMessage +from umnp.proto.common.logging import log_error from umnp.proto.constants import MSG_STRING_ENCODING from umnp.proto.device_message import MSG_TYPE_LIFE_SIGN, MSG_TYPE_INFO @@ -160,10 +161,18 @@ class MeasurementDevice: data_port: int = DEFAULT_UMNP_DATA_IN_PORT, cmd_port: int = DEFAULT_UMNP_COMMAND_IN_PORT, ): + + r = None + s = None if not self._communicator: - s = self.create_sender(port=data_port) - r = self.create_receiver(port=cmd_port) + try: + s = self.create_sender(port=data_port) + r = self.create_receiver(port=cmd_port) + except ValueError: + log_error("No network hardware available") + self._communicator = UDPCommunicator(receiver=r, sender=s, device=self) + return self._communicator @property