Wait, is this peak ?
Build, push image, and notify Watchtower / build-image (push) Successful in 3m32s
Build, push image, and notify Watchtower / notify (push) Successful in 13s

This commit is contained in:
2026-08-04 18:21:20 +02:00
parent caf81d4bbb
commit 5c60017e8d
13 changed files with 249 additions and 89 deletions
+51 -21
View File
@@ -34,9 +34,12 @@ class MicrowaveState:
# Global state trackers
microwave_states = {"2": MicrowaveState.IDLE}
cooking_data_cache = {} # Replaces cooking_queue
button_state = False
async_event_queue = None
# Async synchronization trackers for MQTT IR sensors responses
ir_data_cache = {} # mw_id -> dict of IR readings
ir_data_events = {} # mw_id -> asyncio.Event()
# --- HARDWARE SETUP ---
lora = get_lora()
@@ -141,20 +144,47 @@ async def handle_new_dish(microwave_id, detected_height):
"""Triggered when a new dish is placed inside."""
microwave_states[microwave_id] = MicrowaveState.ANALYZING
print(f"\n[{microwave_id}] 🍽️ Dish detected at {detected_height:.1f} cm! Requesting IR from microwave...")
# 1. Ask microwave for IR temp via MQTT
mqtt_client.publish(config.MQTT_TOPIC_COOKING, payloads.mqtt_cooking_init(microwave_id), qos=config.MQTT_QOS)
# 2. Read local sensors (passing detected_height to prevent GPIO collision)
sensors = await asyncio.to_thread(read_local_sensors, microwave_id, detected_height)
# Check if state changed while taking photos
if microwave_states[microwave_id] != MicrowaveState.ANALYZING:
# 1. Setup synchronization event and clear previous cache for this microwave
event = asyncio.Event()
ir_data_events[microwave_id] = event
ir_data_cache.pop(microwave_id, None)
# 2. Send IR request to ESP32 via MQTT immediately
mqtt_client.publish(
config.MQTT_TOPIC_COOKING,
payloads.mqtt_cooking_init(microwave_id),
qos=config.MQTT_QOS
)
# 3. Start local sensor reading in parallel
sensor_task = asyncio.create_task(asyncio.to_thread(read_local_sensors, microwave_id, detected_height))
# 4. Wait for local sensors to finish reading
sensors_data = await sensor_task
# Check if dish was removed while reading sensors
if microwave_states.get(microwave_id) != MicrowaveState.ANALYZING:
print(f"[{microwave_id}] Dish removed during sensor read. Aborting.")
ir_data_events.pop(microwave_id, None)
return
cooking_data_cache[microwave_id] = sensors
print(f"[{microwave_id}] Local sensors cached. Waiting for MQTT IR data...")
# 5. Wait for MQTT IR data (if it already arrived, event.wait() returns instantly)
try:
await asyncio.wait_for(event.wait(), timeout=10.0)
ir_payload = ir_data_cache.get(microwave_id, {})
sensors_data["ir_initial_temp"] = ir_payload.get("dish_temp")
sensors_data["ir_ambient_temp"] = ir_payload.get("ambient_temp")
print(f"[{microwave_id}] IR data synchronized successfully: {ir_payload}")
except asyncio.TimeoutError:
print(f"[{microwave_id}] ⚠️ Timeout waiting for MQTT IR data from ESP32.")
sensors_data["ir_initial_temp"] = None
sensors_data["ir_ambient_temp"] = None
finally:
ir_data_events.pop(microwave_id, None)
# 6. Dispatch cloud request task
asyncio.create_task(request_cloud_cooking_plan(microwave_id, sensors_data))
async def request_cloud_cooking_plan(microwave_id, sensors_data):
"""Sends all data to the cloud and starts the microwave if successful."""
@@ -236,14 +266,13 @@ async def process_messages_task():
)
elif topic == sensor_topic:
mw_id = data.get("id_microwave")
mw_id = str(data.get("id_microwave"))
print(f"[MQTT] Sensor data received for microwave {mw_id}: {data}")
if mw_id and microwave_states.get(mw_id) == MicrowaveState.ANALYZING:
sensors = cooking_data_cache.get(mw_id)
if sensors:
sensors["ir_initial_temp"] = data.get("dish_temp")
sensors["ir_ambient_temp"] = data.get("ambient_temp")
asyncio.create_task(request_cloud_cooking_plan(mw_id, sensors))
# Store IR data and notify the waiting dish handler
ir_data_cache[mw_id] = data
if mw_id in ir_data_events:
ir_data_events[mw_id].set()
async def get_filtered_dish_height(samples=3, delay=0.04):
"""Reads ultrasonic sensor multiple times and returns the median, discarding invalid zeros."""
@@ -299,8 +328,9 @@ async def monitor_dish_height_task():
microwave_states[mw_id] = MicrowaveState.IDLE
if current_state == MicrowaveState.COOKING:
_stop_hardware(mw_id)
if mw_id in cooking_data_cache:
del cooking_data_cache[mw_id]
# Remove from IR cache and events
ir_data_cache.pop(mw_id, None)
ir_data_events.pop(mw_id, None)
await asyncio.sleep(0.3)