Files
Smartwave/micro_ondes/esp_wifi/main.py
T
Ninluc 4366abba69
Build, push image, and notify Watchtower / build-image (push) Successful in 2m4s
Build, push image, and notify Watchtower / notify (push) Successful in 1m54s
UART communication
2026-07-18 17:01:25 +02:00

127 lines
4.4 KiB
Python

import _thread
import select
from machine import Pin
from shared import get_mqtt_client, get_uart, config
import time
# Simple thread-safe queue list
msg_queue = []
queue_lock = _thread.allocate_lock()
def queue_publish(topic, payload):
"""Safely queues a message from the main thread."""
with queue_lock:
msg_queue.append((topic, payload))
# --- Hardware & Client Setup ---
vext = Pin(19, Pin.OUT)
vext.value(0)
time.sleep_ms(100)
try:
with open("device_id.txt", "r") as f:
DEVICE_ID = f.read().strip()
except Exception:
DEVICE_ID = "ESP32_Inconnu"
MQTT_CA_FILE = "/certs/ca.crt"
mqtt_client = get_mqtt_client(
host=config.MQTT_BROKER_HOST,
client_id="smartwave-esp32-" + DEVICE_ID,
use_tls=config.USE_TLS,
cafile=MQTT_CA_FILE,
keepalive=config.MQTT_KEEPALIVE,
)
def on_mqtt_message(message):
print("[MQTT Thread] Received message:", message)
mqtt_client.set_callback(on_mqtt_message)
def mqtt_background_thread():
"""Background MQTT worker handling ALL socket operations safely."""
print("[Thread] Background MQTT worker started.")
while True:
try:
print("[Thread] Attempting connection to MQTT broker...")
mqtt_client.connect()
print("[Thread] Connected! Subscribing to topic...")
mqtt_client.subscribe(config.MQTT_TOPIC_COOKING, qos=config.MQTT_QOS)
print("[Thread] Successfully subscribed. Setting up poller...")
poller = select.poll()
poller.register(mqtt_client._client.sock, select.POLLIN)
last_check = time.time()
while True:
# 1. Process outbound messages queued by the main thread
while len(msg_queue) > 0:
with queue_lock:
topic, payload = msg_queue.pop(0)
print(f"[Thread] Safely publishing queued message to {topic}...")
mqtt_client.publish(topic, payload, qos=config.MQTT_QOS)
# 2. Check for incoming messages (non-blocking poll)
# Shortened timeout to keep the queue responsive
events = poller.poll(200)
if events:
mqtt_client.wait()
# 3. Handle Keepalive tracking manually
if time.time() - last_check >= 15:
print("[Thread] Sending keepalive ping...")
mqtt_client._client.ping()
last_check = time.time()
# Small breathe room for the CPU core
time.sleep_ms(50)
except Exception as e:
print("[Thread] Connection dropped or error encountered:", e)
print("[Thread] Cleaning up socket context. Retrying in 5 seconds...")
# --- FIX FOR ERROR 23 (SOCKET LEAK) ---
# Manually force-kill the underlying socket file descriptor if it exists
try:
if mqtt_client._client and hasattr(mqtt_client._client, "sock"):
if mqtt_client._client.sock is not None:
mqtt_client._client.sock.close()
except Exception:
pass # Already dead or closed
# Now we let the wrapper do its normal cleanup safely
try:
mqtt_client.close()
except Exception:
pass
time.sleep(5)
# UART
uart_device = get_uart(uart_id=2, tx_pin=17, rx_pin=16)
# --- Launch background worker ---
_thread.start_new_thread(mqtt_background_thread, ())
# --- MAIN APPLICATION THREAD (Core 0) ---
print("[Main] Main execution path active.")
time.sleep(2) # Give the thread a moment to initial connect
while True:
print("[Main] Queueing a test message for MQTT...")
# Instead of direct publishing, push it to the queue safely
queue_publish(config.MQTT_TOPIC_SENSOR, "Hello from ESP32!")
# 1. Check if the Heltec V3 sent us something over the wire
while uart_device.any():
incoming_msg = uart_device.read()
print(f"[Main] Received from esp-lora over UART: {incoming_msg}")
# 2. Example: Send data to the Heltec board every 5 seconds
# uart_device.send("Status Check: WiFi Active")
time.sleep_ms(200) # Fast responsive polling loop for local UART