Working MQTT back !
This commit is contained in:
@@ -5,16 +5,50 @@ esp.osdebug(True)
|
||||
#import webrepl
|
||||
#webrepl.start()
|
||||
|
||||
def do_connect(ssid, pwd):
|
||||
import network
|
||||
sta_if = network.WLAN(network.STA_IF)
|
||||
if not sta_if.isconnected():
|
||||
print('connecting to network...')
|
||||
sta_if.active(True)
|
||||
sta_if.connect(ssid, pwd)
|
||||
while not sta_if.isconnected():
|
||||
pass
|
||||
print('network config:', sta_if.ifconfig())
|
||||
# def do_connect(ssid, pwd):
|
||||
# import network
|
||||
# sta_if = network.WLAN(network.STA_IF)
|
||||
# sta_if.config(pm=sta_if.PM_NONE)
|
||||
# if not sta_if.isconnected():
|
||||
# print('connecting to network...')
|
||||
# sta_if.active(True)
|
||||
# sta_if.connect(ssid, pwd)
|
||||
# while not sta_if.isconnected():
|
||||
# pass
|
||||
# print('network config:', sta_if.ifconfig())
|
||||
|
||||
import network
|
||||
import time
|
||||
|
||||
def do_connect(ssid, password):
|
||||
wlan = network.WLAN(network.STA_IF)
|
||||
|
||||
# 1. ALWAYS activate the interface FIRST
|
||||
if not wlan.active():
|
||||
wlan.active(True)
|
||||
|
||||
# 2. Configure Wi-Fi options AFTER activation
|
||||
try:
|
||||
# Disable Wi-Fi modem sleep (0 = PM_NONE)
|
||||
wlan.config(pm=0)
|
||||
except Exception as e:
|
||||
print("[Wi-Fi] Warning: Failed to set power management:", e)
|
||||
|
||||
# 3. Connect to the access point
|
||||
if not wlan.isconnected():
|
||||
print(f"[Wi-Fi] Connecting to {ssid}...")
|
||||
wlan.connect(ssid, password)
|
||||
|
||||
timeout = 15
|
||||
start_time = time.time()
|
||||
while not wlan.isconnected():
|
||||
if time.time() - start_time > timeout:
|
||||
print("[Wi-Fi] Connection timed out!")
|
||||
return False
|
||||
time.sleep(0.5)
|
||||
|
||||
print("[Wi-Fi] Connected! Network config:", wlan.ifconfig())
|
||||
return True
|
||||
|
||||
# Attempt to connect to WiFi network
|
||||
do_connect("Smartwave-1", 'Smartwave-prot-1')
|
||||
|
||||
+268
-203
@@ -1,23 +1,12 @@
|
||||
import _thread
|
||||
import select
|
||||
from machine import Pin, I2C
|
||||
from sensors import temperature_sensor
|
||||
from shared import get_mqtt_client, get_uart, config, payloads, cookingState
|
||||
from shared.uart_comm import UARTCommand, UARTCommandType
|
||||
from shared.sensors import RGBLED
|
||||
from shared.logging import log
|
||||
import gc
|
||||
import sys
|
||||
import time
|
||||
import ujson as json
|
||||
import sys
|
||||
import uasyncio as asyncio
|
||||
from machine import Pin, I2C
|
||||
|
||||
# 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))
|
||||
# 1. Clean memory immediately
|
||||
gc.collect()
|
||||
|
||||
# --- READ DEVICE ID ---
|
||||
try:
|
||||
@@ -26,214 +15,290 @@ try:
|
||||
except Exception:
|
||||
DEVICE_ID = "ESP32_Inconnu"
|
||||
|
||||
# --- Cooking State ---
|
||||
cooking_state = None # This will hold the current cooking state if any
|
||||
# --- GLOBAL APP STATE ---
|
||||
orchestrator_id = None
|
||||
cooking_state = None
|
||||
mqtt_connected = False
|
||||
|
||||
# --- MQTT SETUP (Initialized First!) ---
|
||||
from shared import get_mqtt_client, config, payloads
|
||||
|
||||
# --- MQTT SETUP ---
|
||||
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,
|
||||
host="192.168.50.1",
|
||||
client_id="smartwave-esp32-demo",
|
||||
use_tls=True,
|
||||
cafile=MQTT_CA_FILE,
|
||||
keepalive=config.MQTT_KEEPALIVE,
|
||||
keepalive=30,
|
||||
)
|
||||
|
||||
global orchestrator_id
|
||||
orchestrator_id = None
|
||||
def on_mqtt_message(message):
|
||||
print("[MQTT Thread] Received message:", message)
|
||||
# --- HARDWARE & MODULE DEFERRED IMPORTS ---
|
||||
# We declare variables here, but initialize them AFTER MQTT connects
|
||||
status_led = None
|
||||
uart_device = None
|
||||
mlx_temperature_sensor = None
|
||||
cookingState = None
|
||||
log = None
|
||||
UARTCommand = None
|
||||
UARTCommandType = None
|
||||
|
||||
|
||||
def init_hardware():
|
||||
"""Initializes hardware peripherals AFTER MQTT TLS has reserved its memory."""
|
||||
global status_led, uart_device, mlx_temperature_sensor
|
||||
global cookingState, log, UARTCommand, UARTCommandType
|
||||
|
||||
# Try and parse the payload as json, but if it fails, just print the raw payload
|
||||
payload_data=None
|
||||
try:
|
||||
payload_data = json.loads(message['payload'])
|
||||
except Exception as e:
|
||||
print("[MQTT Thread] Error parsing JSON:", e)
|
||||
sys.print_exception(e)
|
||||
pass # Maybe it's not JSON
|
||||
print("[Main] Initializing hardware peripherals...")
|
||||
|
||||
if message['topic'] == config.MQTT_TOPIC_HELLO and payload_data and "id_orchestrator" in payload_data and payload_data["id_microwave"] == DEVICE_ID:
|
||||
print("[MQTT Thread] Hello response received from orchestrator:", payload_data["id_orchestrator"])
|
||||
global orchestrator_id
|
||||
orchestrator_id = payload_data["id_orchestrator"]
|
||||
# Unsubscribe from the hello topic since we got a response
|
||||
mqtt_client.unsubscribe(config.MQTT_TOPIC_HELLO)
|
||||
print("[MQTT Thread] Unsubscribed from topic:", config.MQTT_TOPIC_HELLO)
|
||||
|
||||
# Handle cooking messages
|
||||
elif message['topic'] == config.MQTT_TOPIC_COOKING and payload_data and payload_data["id_microwave"] == DEVICE_ID:
|
||||
# Cooking sensors init request
|
||||
if not "cook_time" in payload_data:
|
||||
print("[MQTT Thread] Cooking sensors init received from the orchestrator")
|
||||
obj_temp = mlx_temperature_sensor.read_object_temp()
|
||||
amb_temp = mlx_temperature_sensor.read_ambient_temp()
|
||||
queue_publish(config.MQTT_TOPIC_SENSOR, payloads.mqtt_sensor_data(DEVICE_ID, obj_temp, amb_temp))
|
||||
# Received cooking parameters from the orchestrator
|
||||
else:
|
||||
print("[MQTT Thread] Cooking parameters received from the orchestrator:", payload_data)
|
||||
global cooking_state
|
||||
cooking_state = cookingState.CookingState(
|
||||
cook_time=payload_data["cook_time"],
|
||||
power_level=payload_data["power_level"],
|
||||
target_temp=payload_data["target_temp"]
|
||||
)
|
||||
cooking_state.set_state_change_callback(on_cooking_state_change)
|
||||
cooking_state.set_state(cookingState.CookingStates.IDLE) # Set initial state to IDLE
|
||||
# Send to the LoRa board the cooking parameters
|
||||
uart_device.send_as_command(UARTCommand(UARTCommandType.COOKING_PARAMS, payload_data))
|
||||
print("[MQTT Thread] Cooking parameters sent to LoRa board.")
|
||||
|
||||
print("[MQTT Thread] Message processing complete.")
|
||||
# Deferred module imports
|
||||
from shared import get_uart, cookingState as cs, logging
|
||||
from shared.uart_comm import UARTCommand as UC, UARTCommandType as UCT
|
||||
from shared.sensors import RGBLED
|
||||
from sensors import temperature_sensor
|
||||
|
||||
mqtt_client.set_callback(on_mqtt_message)
|
||||
cookingState = cs
|
||||
log = logging.log
|
||||
UARTCommand = UC
|
||||
UARTCommandType = UCT
|
||||
|
||||
# Status LED
|
||||
status_led = RGBLED(red_pin=21, green_pin=19, blue_pin=18)
|
||||
|
||||
# Hardware UART 2
|
||||
uart_device = get_uart(uart_id=2, tx_pin=17, rx_pin=16)
|
||||
|
||||
# I2C Temperature Sensor
|
||||
temperature_sensor_i2c = I2C(
|
||||
0,
|
||||
scl=Pin(25, Pin.IN, Pin.PULL_UP),
|
||||
sda=Pin(26, Pin.IN, Pin.PULL_UP),
|
||||
freq=100000,
|
||||
)
|
||||
devices = temperature_sensor_i2c.scan()
|
||||
if 0x5A in devices:
|
||||
print("[Main] MLX90614 found at address 0x5A!")
|
||||
else:
|
||||
print("[Main] MLX90614 not found on I2C bus.")
|
||||
mlx_temperature_sensor = temperature_sensor.MLX90614(temperature_sensor_i2c)
|
||||
|
||||
|
||||
def mqtt_background_thread():
|
||||
"""Background MQTT worker handling ALL socket operations safely."""
|
||||
print("[Thread] Background MQTT worker started.")
|
||||
# --- CALLBACKS ---
|
||||
def on_cooking_state_change(state):
|
||||
if status_led is None:
|
||||
return
|
||||
print(f"[Main] Cooking state changed to: {state.state}")
|
||||
BLINK_INTERVAL_MS = 500
|
||||
|
||||
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)
|
||||
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)
|
||||
sys.print_exception(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
|
||||
from shared.sensors import RGBLED
|
||||
if state.state == cookingState.CookingStates.IDLE:
|
||||
status_led.color = RGBLED.OFF
|
||||
status_led.blink_off()
|
||||
elif state.state == cookingState.CookingStates.COOKING:
|
||||
status_led.color = RGBLED.YELLOW
|
||||
status_led.blink_off()
|
||||
elif state.state == cookingState.CookingStates.STIRRING_REQUIRED:
|
||||
status_led.color = RGBLED.ORANGE
|
||||
status_led.blink_on(BLINK_INTERVAL_MS)
|
||||
elif state.state == cookingState.CookingStates.DONE:
|
||||
status_led.color = RGBLED.GREEN
|
||||
status_led.blink_off()
|
||||
elif state.state == cookingState.CookingStates.ALERT:
|
||||
status_led.color = RGBLED.RED
|
||||
status_led.blink_on(BLINK_INTERVAL_MS)
|
||||
|
||||
# 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)
|
||||
|
||||
# Cooking Cycle
|
||||
cooking_state = None
|
||||
def on_received_cooking_state_update(new_state):
|
||||
global cooking_state
|
||||
if cooking_state is None:
|
||||
print("[Main] No active cooking state to update.")
|
||||
return
|
||||
|
||||
log(f"[Main] Updating cooking state to: {new_state}")
|
||||
if log:
|
||||
log(f"[Main] Updating cooking state to: {new_state}")
|
||||
cooking_state.set_state(new_state)
|
||||
|
||||
# Status LED
|
||||
status_led = RGBLED(red_pin=21, green_pin=19, blue_pin=18)
|
||||
def on_cooking_state_change(state):
|
||||
print(f"[Main] Cooking state changed to: {state.state}")
|
||||
|
||||
# === STATUS LED UPDATE ===
|
||||
BLINK_INTERVAL_MS = 500 # Blink every 500ms
|
||||
|
||||
if state.state == cookingState.CookingStates.IDLE:
|
||||
status_led.color = RGBLED.OFF
|
||||
status_led.blink_off()
|
||||
if state.state == cookingState.CookingStates.COOKING:
|
||||
status_led.color = RGBLED.YELLOW
|
||||
status_led.blink_off()
|
||||
if state.state == cookingState.CookingStates.STIRRING_REQUIRED:
|
||||
status_led.color = RGBLED.ORANGE
|
||||
status_led.blink_on(BLINK_INTERVAL_MS)
|
||||
if state.state == cookingState.CookingStates.DONE:
|
||||
status_led.color = RGBLED.GREEN
|
||||
status_led.blink_off()
|
||||
if state.state == cookingState.CookingStates.ALERT:
|
||||
status_led.color = RGBLED.RED
|
||||
status_led.blink_on(BLINK_INTERVAL_MS)
|
||||
|
||||
|
||||
# --- MAIN APPLICATION THREAD (Core 0) ---
|
||||
print("[Main] Main execution path active.")
|
||||
|
||||
# Temperature sensor setup
|
||||
temperature_sensor_i2c = I2C(0, scl=Pin(25, Pin.IN, Pin.PULL_UP), sda=Pin(26, Pin.IN, Pin.PULL_UP), freq=100000)
|
||||
# Scan to verify the sensor is connected and detected
|
||||
print("Scanning I2C bus...")
|
||||
devices = temperature_sensor_i2c.scan()
|
||||
if 0x5A in devices:
|
||||
print("MLX90614 found at address 0x5A!")
|
||||
else:
|
||||
print("MLX90614 not found. Please check your wiring.")
|
||||
mlx_temperature_sensor = temperature_sensor.MLX90614(temperature_sensor_i2c)
|
||||
|
||||
# --- Launch background worker ---
|
||||
_thread.start_new_thread(mqtt_background_thread, ())
|
||||
time.sleep(2) # Give the thread a moment to initial connect
|
||||
mqtt_hello_sent_timestamp = -config.MQTT_HELLO_INTERVAL
|
||||
mqtt_client.subscribe(config.MQTT_TOPIC_HELLO, qos=config.MQTT_QOS)
|
||||
|
||||
while True:
|
||||
# MQTT HELLO sent every x seconds until we get a response from the orchestrator
|
||||
if (orchestrator_id == None and -(mqtt_hello_sent_timestamp - time.time()) > config.MQTT_HELLO_INTERVAL):
|
||||
print("[Main] Attempting to send initial hello to orchestrator...")
|
||||
queue_publish(config.MQTT_TOPIC_HELLO, payloads.mqtt_hello(DEVICE_ID))
|
||||
mqtt_hello_sent_timestamp = time.time()
|
||||
pass
|
||||
def on_mqtt_message(message):
|
||||
global orchestrator_id, cooking_state
|
||||
print("[MQTT] Received message on topic:", message.get("topic"))
|
||||
|
||||
# 1. Listen for incoming UART serial packets from the WROOM board
|
||||
while uart_device.any():
|
||||
command = uart_device.read_as_command()
|
||||
if command:
|
||||
print(f"[Main] Received command from LoRa Board: {command.command_type}")
|
||||
if command.command_type == UARTCommandType.COOKING_STATE_UPDATE:
|
||||
# Handle cooking state update command
|
||||
new_state = command.payload.get("state", None)
|
||||
print(f"[Main] Cooking state update received: {new_state}")
|
||||
on_received_cooking_state_update(new_state)
|
||||
else:
|
||||
print(f"[Main] Unknown command type received: {command.command_type}")
|
||||
payload_data = None
|
||||
try:
|
||||
payload_data = json.loads(message["payload"])
|
||||
except Exception as e:
|
||||
print("[MQTT] Payload parsing warning:", e)
|
||||
|
||||
topic = message.get("topic")
|
||||
|
||||
# 1. Orchestrator Hello Response
|
||||
if (
|
||||
topic == config.MQTT_TOPIC_HELLO
|
||||
and payload_data
|
||||
and payload_data.get("id_microwave") == DEVICE_ID
|
||||
):
|
||||
orchestrator_id = payload_data.get("id_orchestrator")
|
||||
print("[MQTT] Hello response received from orchestrator:", orchestrator_id)
|
||||
try:
|
||||
mqtt_client.unsubscribe(config.MQTT_TOPIC_HELLO)
|
||||
print("[MQTT] Unsubscribed from topic:", config.MQTT_TOPIC_HELLO)
|
||||
except Exception as e:
|
||||
print("[MQTT] Unsubscribe error:", e)
|
||||
sys.print_exception(e)
|
||||
|
||||
# 2. Cooking Parameters / Sensor Request
|
||||
elif (
|
||||
topic == config.MQTT_TOPIC_COOKING
|
||||
and payload_data
|
||||
and payload_data.get("id_microwave") == DEVICE_ID
|
||||
):
|
||||
if "cook_time" not in payload_data:
|
||||
print("[MQTT] Sensor data requested by orchestrator.")
|
||||
obj_temp = mlx_temperature_sensor.read_object_temp() if mlx_temperature_sensor else 0
|
||||
amb_temp = mlx_temperature_sensor.read_ambient_temp() if mlx_temperature_sensor else 0
|
||||
|
||||
sensor_payload = payloads.mqtt_sensor_data(DEVICE_ID, obj_temp, amb_temp)
|
||||
mqtt_client.publish(
|
||||
config.MQTT_TOPIC_SENSOR, sensor_payload, qos=config.MQTT_QOS
|
||||
)
|
||||
else:
|
||||
# Fallback to reading as a raw string if parsing fails
|
||||
raw_command = uart_device.read()
|
||||
print(f"[Main] Received raw command from WiFi Board: {raw_command}")
|
||||
|
||||
# 2. Example: Send data to the Heltec board every 5 seconds
|
||||
# uart_device.send("Status Check: WiFi Active")
|
||||
time.sleep(1)
|
||||
print("[MQTT] Cooking parameters received:", payload_data)
|
||||
if cookingState:
|
||||
cooking_state = cookingState.CookingState(
|
||||
cook_time=payload_data["cook_time"],
|
||||
power_level=payload_data["power_level"],
|
||||
target_temp=payload_data["target_temp"],
|
||||
)
|
||||
cooking_state.set_state_change_callback(on_cooking_state_change)
|
||||
cooking_state.set_state(cookingState.CookingStates.IDLE)
|
||||
|
||||
if uart_device and UARTCommand:
|
||||
uart_device.send_as_command(
|
||||
UARTCommand(UARTCommandType.COOKING_PARAMS, payload_data)
|
||||
)
|
||||
print("[MQTT] Cooking parameters sent to LoRa board.")
|
||||
|
||||
|
||||
mqtt_client.set_callback(on_mqtt_message)
|
||||
|
||||
|
||||
async def connect_mqtt_async():
|
||||
"""Connects to MQTT safely while memory is clean."""
|
||||
global mqtt_connected
|
||||
mqtt_connected = False
|
||||
|
||||
while True:
|
||||
try:
|
||||
print("[MQTT] Connecting to broker with TLS...")
|
||||
gc.collect()
|
||||
mqtt_client.connect()
|
||||
print("[MQTT] Connected! Subscribing to topics...")
|
||||
mqtt_client.subscribe(config.MQTT_TOPIC_COOKING, qos=config.MQTT_QOS)
|
||||
mqtt_client.subscribe(config.MQTT_TOPIC_HELLO, qos=config.MQTT_QOS)
|
||||
print("[MQTT] Subscribed successfully!")
|
||||
mqtt_connected = True
|
||||
return
|
||||
except Exception as e:
|
||||
print("[MQTT] Connection failed:", e)
|
||||
sys.print_exception(e)
|
||||
try:
|
||||
mqtt_client.close()
|
||||
except Exception:
|
||||
pass
|
||||
print("[MQTT] Retrying connection in 5 seconds...")
|
||||
await asyncio.sleep(5)
|
||||
|
||||
|
||||
# --- CONCURRENT ASYNC TASKS ---
|
||||
|
||||
async def mqtt_poll_task():
|
||||
global mqtt_connected
|
||||
last_ping = time.time()
|
||||
|
||||
while True:
|
||||
if mqtt_connected:
|
||||
try:
|
||||
mqtt_client.poll()
|
||||
now = time.time()
|
||||
if now - last_ping >= 15:
|
||||
if mqtt_client._client:
|
||||
mqtt_client._client.ping()
|
||||
last_ping = now
|
||||
except OSError as e:
|
||||
print("[MQTT Task] Socket error encountered during poll/ping:", e)
|
||||
mqtt_connected = False
|
||||
await connect_mqtt_async()
|
||||
|
||||
await asyncio.sleep_ms(30)
|
||||
|
||||
|
||||
async def orchestrator_hello_task():
|
||||
global mqtt_connected
|
||||
while True:
|
||||
if mqtt_connected and orchestrator_id is None:
|
||||
print("[Hello Task] Sending initial hello to orchestrator...")
|
||||
try:
|
||||
mqtt_client.publish(
|
||||
config.MQTT_TOPIC_HELLO,
|
||||
payloads.mqtt_hello(DEVICE_ID),
|
||||
qos=config.MQTT_QOS,
|
||||
)
|
||||
except OSError as e:
|
||||
print("[Hello Task] Hello publish failed:", e)
|
||||
mqtt_connected = False
|
||||
await connect_mqtt_async()
|
||||
|
||||
await asyncio.sleep(config.MQTT_HELLO_INTERVAL)
|
||||
|
||||
|
||||
async def uart_task():
|
||||
while True:
|
||||
if uart_device is not None:
|
||||
while uart_device.any():
|
||||
command = uart_device.read_as_command()
|
||||
if command:
|
||||
print(f"[UART Task] Received command: {command.command_type}")
|
||||
if command.command_type == UARTCommandType.COOKING_STATE_UPDATE:
|
||||
new_state = command.payload.get("state", None)
|
||||
print(f"[UART Task] Cooking state update: {new_state}")
|
||||
on_received_cooking_state_update(new_state)
|
||||
else:
|
||||
print(f"[UART Task] Unknown command type: {command.command_type}")
|
||||
else:
|
||||
raw_command = uart_device.read()
|
||||
print(f"[UART Task] Received raw command: {raw_command}")
|
||||
|
||||
await asyncio.sleep_ms(20)
|
||||
|
||||
|
||||
async def memory_cleanup_task():
|
||||
while True:
|
||||
gc.collect()
|
||||
await asyncio.sleep(10)
|
||||
|
||||
|
||||
# --- MAIN ENTRY POINT ---
|
||||
async def main():
|
||||
print("[Main] Starting application...")
|
||||
|
||||
# STEP 1: Connect MQTT FIRST (while RAM is unfragmented)
|
||||
await connect_mqtt_async()
|
||||
|
||||
# STEP 2: Initialize Hardware & Secondary Modules AFTER connection
|
||||
init_hardware()
|
||||
|
||||
# STEP 3: Launch tasks
|
||||
asyncio.create_task(mqtt_poll_task())
|
||||
asyncio.create_task(orchestrator_hello_task())
|
||||
asyncio.create_task(uart_task())
|
||||
asyncio.create_task(memory_cleanup_task())
|
||||
|
||||
print("[Main] All tasks running concurrently!")
|
||||
|
||||
while True:
|
||||
await asyncio.sleep(3600)
|
||||
|
||||
|
||||
try:
|
||||
asyncio.run(main())
|
||||
except KeyboardInterrupt:
|
||||
print("[Main] Program stopped by user.")
|
||||
Reference in New Issue
Block a user