Wait, is this peak ?
This commit is contained in:
+51
-21
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user