From 1f8316d07706a8fc05f8b8fd0c9d5af1d57696a8 Mon Sep 17 00:00:00 2001 From: Laurent Date: Sat, 27 Dec 2025 13:20:53 +0100 Subject: [PATCH] Reworked serial reading --- rpi/hardware/generic/__init__.py | 0 rpi/hardware/generic/serial_reader.py | 40 +++++++++++++++++++++++++++ rpi/hardware/rfid/reader.py | 34 ++++------------------- rpi/main.py | 8 ++++-- 4 files changed, 50 insertions(+), 32 deletions(-) create mode 100644 rpi/hardware/generic/__init__.py create mode 100644 rpi/hardware/generic/serial_reader.py diff --git a/rpi/hardware/generic/__init__.py b/rpi/hardware/generic/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/rpi/hardware/generic/serial_reader.py b/rpi/hardware/generic/serial_reader.py new file mode 100644 index 00000000..09eb41b8 --- /dev/null +++ b/rpi/hardware/generic/serial_reader.py @@ -0,0 +1,40 @@ +import threading +from threading import Thread +from typing import Callable + +from serial import Serial + +class SerialReader: + + serial : Serial = None + __thread : Thread | None = None + __listeners : list[Callable] = None + + def __init__(self, port, baudrate): + self.serial = Serial(port, baudrate) + self._run_event = threading.Event() + self.__listeners = [] + + def start(self) -> None: + self._run_event.set() + if self.__thread is None or not self.__thread.is_alive(): + self.__thread = Thread(target=self.__read, daemon=True) + self.__thread.start() + + def stop(self) -> None: + if self._run_event.is_set(): + self._run_event.clear() + + def subscribe(self, listener : Callable) -> None: + self.__listeners.append(listener) + + def __notify(self, data : str): + for listener in self.__listeners: + listener(data) + + def __read(self): + while self._run_event.is_set(): + line = self.serial.readline() + if line: + data = line.decode('utf-8', errors='ignore') + self.__notify(data) \ No newline at end of file diff --git a/rpi/hardware/rfid/reader.py b/rpi/hardware/rfid/reader.py index fea8f424..7712800c 100644 --- a/rpi/hardware/rfid/reader.py +++ b/rpi/hardware/rfid/reader.py @@ -4,40 +4,18 @@ from threading import Thread import threading from serial import Serial +from hardware.generic.serial_reader import SerialReader -class RfidReader: - - __serial : Serial = None - __thread : Thread | None = None - __listeners : list[Callable] = None +class RfidReader(SerialReader): def __init__(self, port : str, baudrate: int): - self.__serial = Serial(port, baudrate) - self._run_event = threading.Event() - self.__listeners = [] - - def start(self) -> None: - self._run_event.set() - if self.__thread is None or not self.__thread.is_alive(): - self.__thread = Thread(target=self.__read, daemon=True) - self.__thread.start() - - def stop(self) -> None: - if self._run_event.is_set(): - self._run_event.clear() - - def subscribe(self, listener : Callable) -> None: - self.__listeners.append(listener) - - def __notify(self, uid : int): - for listener in self.__listeners: - listener(uid) + super().__init__(port, baudrate) def __read(self): while self._run_event.is_set(): data = b"" while len(data) < 14 and self._run_event.is_set(): - character = self.__serial.read(1) + character = self.serial.read(1) if not character: continue data += character @@ -45,14 +23,12 @@ class RfidReader: hex_value = data[5:11].decode(errors='ignore') try: res = int(hex_value, 16) - self.__notify(res) + self.__notify(str(res)) except ValueError: print("Invalid hex:", hex_value) else: print("Received incomplete data:", data) - - if __name__ == "__main__": def callback(uid): diff --git a/rpi/main.py b/rpi/main.py index 633a4658..69504497 100644 --- a/rpi/main.py +++ b/rpi/main.py @@ -2,6 +2,7 @@ import cv2 from flask import Flask +from hardware.generic.serial_reader import SerialReader from hardware.screen.screen import Screen from hardware.rfid.reader import RfidReader from services.detection_service import DetectionService @@ -11,7 +12,8 @@ app = Flask(__name__) screen = Screen() mqtt_service = MQTTService("127.0.0.1", 1883) -reader = RfidReader("/dev/serial0", 9600) +rfid_reader = RfidReader("/dev/serial0", 9600) +light_sensor_reader = SerialReader("/dev/ttyUSB1", 57600) detection_service = DetectionService() @app.route("/party/start", methods=['POST']) @@ -24,8 +26,8 @@ if __name__ == "__main__": screen.enableBackground() screen.displayMessage("Waiting for scan...") - reader.start() - reader.subscribe(lambda uid: mqtt_service.publish( + rfid_reader.start() + rfid_reader.subscribe(lambda uid: mqtt_service.publish( "rpi", "/board-mate/rfid/scan", str(uid), 0 ))