import _thread import select # <--- Built-in module to handle TLS timeouts from machine import Pin from shared import get_mqtt_client from shared import config import time # --- Hardware Configuration --- vext = Pin(19, Pin.OUT) vext.value(0) time.sleep_ms(100) # --- Read Unique Device ID --- 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" # --- Setup MQTT Client --- 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, # Can safely be 30 now ) 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 using select.poll() for keepalive tracking.""" 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, qos=config.MQTT_QOS) print("[Thread] Successfully subscribed. Setting up poller...") # --- THE SELECT POLLER SETUP --- # Create a poller and register our active TLS socket to look for incoming data (POLLIN) poller = select.poll() poller.register(mqtt_client._client.sock, select.POLLIN) # Listening loop while True: # Wait for network events for a maximum of 15000 milliseconds (15 seconds) events = poller.poll(15000) if not events: # The 15 seconds expired with zero network traffic! # Send a keepalive ping to Mosquitto. print("[Thread] No data for 15s. Sending keepalive ping...") mqtt_client._client.ping() else: # Data has physically arrived on the socket! # Calling wait() now is completely safe and won't block indefinitely. mqtt_client.wait() except Exception as e: print("[Thread] Connection dropped or error encountered:", e) print("[Thread] Cleaning up socket context. Retrying in 5 seconds...") try: mqtt_client.close() except Exception: pass time.sleep(5) # --- Launch background worker --- _thread.start_new_thread(mqtt_background_thread, ()) # --- MAIN APPLICATION THREAD (Core 0) --- print("[Main] Main execution path active.") while True: # Your main physical loop runs completely unhindered here time.sleep(1)