Compare commits
5 Commits
6fa74c6b93
...
5381631876
| Author | SHA1 | Date | |
|---|---|---|---|
| 5381631876 | |||
| 2df05fd684 | |||
| 11357b9a0e | |||
| e2beef511c | |||
| e748d53c94 |
@@ -85,13 +85,6 @@ def cooking_state_temperature_provider():
|
||||
def cooking_state_on_state_change(state):
|
||||
print(f"[Main] Cooking state changed to: {state.state}")
|
||||
|
||||
# Send to the Wifi board the current state
|
||||
uart_device.send_as_command(UARTCommand(UARTCommandType.COOKING_STATE_UPDATE, {"state": state.state}))
|
||||
# Send to the orchestrator the current state
|
||||
lora.send_reliable({"id": DEVICE_ID, "new_cooking_state": state.state})
|
||||
|
||||
display.text(cookingState.CookingStates.get_state_name(state.state), 1, 2, 1)
|
||||
display.show()
|
||||
|
||||
if state.paused or state.state == cookingState.CookingStates.DONE or state.state == cookingState.CookingStates.IDLE:
|
||||
magnetron_led.off()
|
||||
@@ -108,6 +101,15 @@ def cooking_state_on_state_change(state):
|
||||
if state.state == cookingState.CookingStates.ALERT:
|
||||
pass
|
||||
|
||||
# Send to the Wifi board the current state
|
||||
uart_device.send_as_command(UARTCommand(UARTCommandType.COOKING_STATE_UPDATE, {"state": state.state}))
|
||||
# Send to the orchestrator the current state
|
||||
lora.send_reliable({"id": DEVICE_ID, "new_cooking_state": state.state})
|
||||
|
||||
display.fill(0)
|
||||
display.text(cookingState.CookingStates.get_state_name(state.state), 1, 2, 1)
|
||||
display.show()
|
||||
|
||||
def cooking_state_on_refresh(state):
|
||||
# TODO Show screen information
|
||||
pass
|
||||
|
||||
@@ -76,35 +76,31 @@ def init_hardware():
|
||||
mlx_temperature_sensor = temperature_sensor.MLX90614(temperature_sensor_i2c)
|
||||
|
||||
|
||||
def on_received_cooking_state_update(state, is_error=False, is_terminated=False):
|
||||
"""Callback executed when state changes are received from the LoRa board over UART."""
|
||||
if cooking_state:
|
||||
if is_error:
|
||||
cooking_state.set_state(cookingState.CookingStates.ERROR)
|
||||
elif is_terminated:
|
||||
cooking_state.set_state(cookingState.CookingStates.ABORTED)
|
||||
else:
|
||||
cooking_state.set_state(state)
|
||||
|
||||
|
||||
def on_cooking_state_change(state):
|
||||
"""Callback executed whenever local cooking state transitions."""
|
||||
BLINK_INTERVAL_MS = 500
|
||||
|
||||
log(f"[CookingState] State changed to: {state.state}")
|
||||
|
||||
if status_led and cookingState:
|
||||
if state == cookingState.CookingStates.IDLE:
|
||||
if state.state == cookingState.CookingStates.IDLE:
|
||||
log(f"[CookingState] State changed to IDLE. Turning LED off and stopping blink.")
|
||||
status_led.color = status_led.OFF
|
||||
status_led.blink_off()
|
||||
elif state == cookingState.CookingStates.COOKING:
|
||||
elif state.state == cookingState.CookingStates.COOKING:
|
||||
log(f"[CookingState] State changed to COOKING. Turning LED yellow and stopping blink.")
|
||||
status_led.color = status_led.YELLOW
|
||||
status_led.blink_off()
|
||||
elif state == cookingState.CookingStates.STIRRING_REQUIRED:
|
||||
elif state.state == cookingState.CookingStates.STIRRING_REQUIRED:
|
||||
log(f"[CookingState] State changed to STIRRING_REQUIRED. Turning LED orange and starting blink.")
|
||||
status_led.color = status_led.ORANGE
|
||||
status_led.blink_on(BLINK_INTERVAL_MS)
|
||||
elif state == cookingState.CookingStates.ALERT:
|
||||
elif state.state == cookingState.CookingStates.ALERT:
|
||||
log(f"[CookingState] State changed to ALERT. Turning LED red and starting blink.")
|
||||
status_led.color = status_led.RED
|
||||
status_led.blink_on(BLINK_INTERVAL_MS)
|
||||
elif state == cookingState.CookingStates.DONE:
|
||||
elif state.state == cookingState.CookingStates.DONE:
|
||||
log(f"[CookingState] State changed to DONE. Turning LED green and stopping blink.")
|
||||
status_led.color = status_led.GREEN
|
||||
status_led.blink_off()
|
||||
|
||||
@@ -193,23 +189,20 @@ async def sensor_publisher_task():
|
||||
|
||||
async def uart_task():
|
||||
"""Polls incoming UART messages from the LoRa board using dynamic method fallback."""
|
||||
global cooking_state
|
||||
while True:
|
||||
if uart_device:
|
||||
try:
|
||||
cmd = uart_device.read_as_command()
|
||||
|
||||
if cmd:
|
||||
print("[UART] Command received from LoRa board:", cmd)
|
||||
print("[UART] Command received from LoRa board:", cmd.command_type, cmd.payload)
|
||||
if (
|
||||
hasattr(cmd, "command_type")
|
||||
and cmd.command_type == UARTCommandType.STATE_UPDATE
|
||||
and on_received_cooking_state_update
|
||||
and cmd.command_type == UARTCommandType.COOKING_STATE_UPDATE
|
||||
):
|
||||
on_received_cooking_state_update(
|
||||
cmd.payload.get("state"),
|
||||
cmd.payload.get("is_error", False),
|
||||
cmd.payload.get("is_terminated", False),
|
||||
)
|
||||
if cooking_state:
|
||||
cooking_state.set_state(cmd.payload.get("state"))
|
||||
except Exception as e:
|
||||
print("[UART Task] Error reading command:", e)
|
||||
|
||||
|
||||
@@ -230,6 +230,9 @@ async def request_cloud_cooking_plan(microwave_id, sensors_data):
|
||||
print(f"[{microwave_id}] Cloud Plan Received! Starting microwave: {c_time}s @ {c_power}W")
|
||||
cloud_alert = False # Reset alert flag on success
|
||||
microwave_states[microwave_id] = MicrowaveState.COOKING
|
||||
if config.DEBUG:
|
||||
c_time = min(c_time, 10) # Limit to 10s for debug
|
||||
c_temp = min(c_temp, 50) # Limit to 50°C for debug
|
||||
mqtt_client.publish(
|
||||
config.MQTT_TOPIC_COOKING,
|
||||
payloads.mqtt_cooking_config(microwave_id, c_time, c_power, c_temp),
|
||||
@@ -306,8 +309,8 @@ async def get_filtered_dish_height(samples=3, delay=0.04):
|
||||
valid_samples = []
|
||||
for _ in range(samples):
|
||||
h = await asyncio.to_thread(ultrasonicRanger.get_dish_height)
|
||||
# Discard 0.0 or near-zero timeout glitches
|
||||
if h is not None and h > 0.5:
|
||||
# Discard negative glitches
|
||||
if h is not None and h >= 0.0:
|
||||
valid_samples.append(h)
|
||||
await asyncio.sleep(delay)
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ class BaseLoraDevice:
|
||||
# 1. Handle incoming ACK response
|
||||
if data.get("_type") == "_ack":
|
||||
ack_id = data.get("_ack_id")
|
||||
print(f"[ReliableLoRa] <- SUCCESSFULLY MATCHED ACK ID: {ack_id}")
|
||||
log(f"[ReliableLoRa] <- SUCCESSFULLY MATCHED ACK ID: {ack_id}")
|
||||
if ack_id is not None:
|
||||
self.received_acks.add(ack_id)
|
||||
if len(self.received_acks) > 100:
|
||||
@@ -61,11 +61,11 @@ class BaseLoraDevice:
|
||||
# 2. Handle incoming command expecting an ACK
|
||||
msg_id = data.get("_msg_id")
|
||||
if msg_id is not None:
|
||||
print(f"[ReliableLoRa] <- Received packet with msg_id {msg_id}. Queuing ACK.")
|
||||
log(f"[ReliableLoRa] <- Received packet with msg_id {msg_id}. Queuing ACK.")
|
||||
self._send_ack(msg_id)
|
||||
|
||||
if msg_id in self.processed_msg_ids:
|
||||
print(f"[ReliableLoRa] Discarding duplicate retry for msg_id {msg_id}")
|
||||
log(f"[ReliableLoRa] Discarding duplicate retry for msg_id {msg_id}")
|
||||
return None # Discard duplicate retry
|
||||
|
||||
self.processed_msg_ids.add(msg_id)
|
||||
@@ -86,10 +86,10 @@ class BaseLoraDevice:
|
||||
msg_id = self._generate_msg_id()
|
||||
payload["_msg_id"] = msg_id
|
||||
|
||||
print(f"\n[ReliableLoRa] === Starting send_reliable for msg_id {msg_id} ===")
|
||||
log(f"\n[ReliableLoRa] === Starting send_reliable for msg_id {msg_id} ===")
|
||||
|
||||
for attempt in range(max_retries):
|
||||
print(f"[ReliableLoRa] Attempt {attempt + 1}/{max_retries} transmitting msg_id {msg_id}")
|
||||
log(f"[ReliableLoRa] Attempt {attempt + 1}/{max_retries} transmitting msg_id {msg_id}")
|
||||
self.send(payload)
|
||||
|
||||
# 1. Open a single continuous RX window for the full timeout duration
|
||||
@@ -112,12 +112,12 @@ class BaseLoraDevice:
|
||||
try:
|
||||
if msg_id in self.received_acks:
|
||||
self.received_acks.remove(msg_id)
|
||||
print(f"[ReliableLoRa] === ACK received for msg_id {msg_id} on attempt {attempt + 1} ===")
|
||||
log(f"[ReliableLoRa] === ACK received for msg_id {msg_id} on attempt {attempt + 1} ===")
|
||||
return True
|
||||
finally:
|
||||
if lock: lock.release()
|
||||
|
||||
print(f"[ReliableLoRa] Attempt {attempt + 1} timed out waiting for ACK for msg_id {msg_id}")
|
||||
log(f"[ReliableLoRa] Attempt {attempt + 1} timed out waiting for ACK for msg_id {msg_id}")
|
||||
|
||||
print(f"[ReliableLoRa] ERROR: Failed to receive ACK for msg_id {msg_id} after {max_retries} attempts.")
|
||||
return False
|
||||
@@ -334,13 +334,13 @@ else:
|
||||
|
||||
hex_payload = payload.hex()
|
||||
|
||||
print(f"[RPi LoRa Serial] Transmitting HEX string: {hex_payload}")
|
||||
log(f"[RPi LoRa Serial] Transmitting HEX string: {hex_payload}")
|
||||
|
||||
# Format: AT+SEND=<group>,<payload_string>,<confirm>,<retries>
|
||||
cmd = f"AT+SEND={group},{hex_payload},0,3"
|
||||
|
||||
resp = self._send_at_cmd(cmd, wait_time=0.3)
|
||||
print(f"[RPi LoRa Serial] AT+SEND response: {resp}")
|
||||
log(f"[RPi LoRa Serial] AT+SEND response: {resp}")
|
||||
|
||||
def receive_packet(self, timeout_ms=500):
|
||||
"""Reads incoming serial lines from LA66 stick with robust format parsing."""
|
||||
|
||||
Reference in New Issue
Block a user