UART communication
Build, push image, and notify Watchtower / build-image (push) Successful in 2m4s
Build, push image, and notify Watchtower / notify (push) Successful in 1m54s

This commit is contained in:
2026-07-18 17:01:25 +02:00
parent 987067aa1e
commit 4366abba69
7 changed files with 161 additions and 35 deletions
+5 -1
View File
@@ -14,4 +14,8 @@ def get_database(*args, **kwargs):
def get_mqtt_client(*args, **kwargs):
from .mqtt import BrokerClient
return BrokerClient(*args, **kwargs)
return BrokerClient(*args, **kwargs)
def get_uart(*args, **kwargs):
from .uart_comm import SafeUART
return SafeUART(*args, **kwargs)
+3 -2
View File
@@ -5,7 +5,8 @@ HEARTBEAT_INTERVAL = 10
# MQTT
MQTT_BROKER_HOST = "192.168.50.1"
MQTT_TOPIC = b"smartwave/demo"
MQTT_TOPIC_SENSOR = b"smartwave/sensor"
MQTT_TOPIC_COOKING = b"smartwave/cooking"
MQTT_KEEPALIVE = 30
USE_TLS = True
MQTT_QOS = 2
MQTT_QOS = 1
+2 -2
View File
@@ -112,7 +112,7 @@ else:
# La clé ajoute d'elle-même l'octet de groupe configuré dans ses registres
cmd = f"AT+SEND=1,{hex_payload},1,3\r\n"
print(f"RPI : Envoi de la commande HEX -> AT+SEND=1,[HEX_DATA],1,3")
# print(f"RPI : Envoi de la commande HEX -> AT+SEND=1,[HEX_DATA],1,3")
self.ser.write(cmd.encode('utf-8'))
time.sleep(0.2)
@@ -123,7 +123,7 @@ else:
response += self.ser.readline().decode('utf-8', errors='ignore')
time.sleep(0.05)
print(f"[RPI LA66 TX STATUS] :\n{response.strip()}")
# print(f"[RPI LA66 TX STATUS] :\n{response.strip()}")
def receive_packet(self, timeout_ms=5000):
with self.lock:
+66
View File
@@ -0,0 +1,66 @@
# shared/uart_comm.py
import _thread
from machine import UART
import time
class SafeUART:
def __init__(self, uart_id, tx_pin, rx_pin, baudrate=115200):
# Initialize the hardware UART channel
self.uart = UART(uart_id, baudrate=baudrate, tx=tx_pin, rx=rx_pin, timeout=10)
# Core thread-safety assets
self.lock = _thread.allocate_lock()
self.rx_queue = []
self.buffer = b""
# Start the background data worker thread
_thread.stack_size(4096) # Cap the stack size for the UART listener
_thread.start_new_thread(self._listener_worker, ())
_thread.stack_size(0)
print(f"[UART] Thread initialized on UART{uart_id} (TX:{tx_pin}, RX:{rx_pin})")
def _listener_worker(self):
"""Asynchronous internal loop parsing incoming stream lines into the queue."""
while True:
try:
if self.uart.any():
with self.lock:
# Pull all raw bytes waiting in the hardware ring buffer
chunk = self.uart.read(self.uart.any())
if chunk:
self.buffer += chunk
# Process complete lines terminated by a newline character
while b'\n' in self.buffer:
line, self.buffer = self.buffer.split(b'\n', 1)
try:
decoded_line = line.decode('utf-8').strip()
if decoded_line:
self.rx_queue.append(decoded_line)
except Exception:
pass # Discard corrupt data frames safely
except Exception as e:
print("[UART Thread Error]:", e)
time.sleep_ms(20) # Give other background threads breathing room
def send(self, message):
"""Safely pushes strings across the serial wire from any thread context."""
if not message.endswith('\n'):
message += '\n'
with self.lock:
self.uart.write(message.encode('utf-8'))
def any(self):
"""Checks if any complete messages are waiting to be read."""
with self.lock:
return len(self.rx_queue) > 0
def read(self):
"""Pulls the oldest unread string from the queue. Returns None if empty."""
with self.lock:
if self.rx_queue:
return self.rx_queue.pop(0)
return None