Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 204f271fc2 | |||
| 5c60de3f03 |
@@ -205,7 +205,7 @@ def cooking_state_temperature_provider():
|
|||||||
return (0.0, 0.0)
|
return (0.0, 0.0)
|
||||||
|
|
||||||
def cooking_state_on_state_change(state):
|
def cooking_state_on_state_change(state):
|
||||||
global cooking_start_time
|
global cooking_start_time, uart_device
|
||||||
print(f"[CookingState] State changed to: {state.state}")
|
print(f"[CookingState] State changed to: {state.state}")
|
||||||
|
|
||||||
if state.paused or state.state in (cookingState.CookingStates.DONE, cookingState.CookingStates.IDLE, cookingState.CookingStates.ALERT):
|
if state.paused or state.state in (cookingState.CookingStates.DONE, cookingState.CookingStates.IDLE, cookingState.CookingStates.ALERT):
|
||||||
@@ -214,7 +214,7 @@ def cooking_state_on_state_change(state):
|
|||||||
magnetron_led.on()
|
magnetron_led.on()
|
||||||
|
|
||||||
# Send state updates to WiFi board and Orchestrator
|
# Send state updates to WiFi board and Orchestrator
|
||||||
if uart_device:
|
if uart_device != None:
|
||||||
uart_device.send_as_command(UARTCommand(UARTCommandType.COOKING_STATE_UPDATE, {"state": state.state}))
|
uart_device.send_as_command(UARTCommand(UARTCommandType.COOKING_STATE_UPDATE, {"state": state.state}))
|
||||||
|
|
||||||
# Send LoRa update with start time and remaining time if beginning cooking process
|
# Send LoRa update with start time and remaining time if beginning cooking process
|
||||||
@@ -347,6 +347,8 @@ async def lora_process_task():
|
|||||||
alert.timestamp = data.get("timestamp", time.time())
|
alert.timestamp = data.get("timestamp", time.time())
|
||||||
alert_manager.add_alert(alert)
|
alert_manager.add_alert(alert)
|
||||||
microwave_state = MicrowaveState.ALERT
|
microwave_state = MicrowaveState.ALERT
|
||||||
|
if cooking_state is not None:
|
||||||
|
cooking_state.set_state(cookingState.CookingStates.ALERT)
|
||||||
|
|
||||||
elif action == LoraCommands.MICROVAVE_STATE_UPDATE:
|
elif action == LoraCommands.MICROVAVE_STATE_UPDATE:
|
||||||
new_state = data.get("new_microwave_state")
|
new_state = data.get("new_microwave_state")
|
||||||
@@ -356,7 +358,8 @@ async def lora_process_task():
|
|||||||
if new_state not in (MicrowaveState.ALERT): # Not alert so we can show the error
|
if new_state not in (MicrowaveState.ALERT): # Not alert so we can show the error
|
||||||
update_screen()
|
update_screen()
|
||||||
if new_state == MicrowaveState.IDLE:
|
if new_state == MicrowaveState.IDLE:
|
||||||
cooking_state = None
|
if cooking_state is not None:
|
||||||
|
cooking_state.set_state(cookingState.CookingStates.IDLE)
|
||||||
await asyncio.sleep_ms(20)
|
await asyncio.sleep_ms(20)
|
||||||
|
|
||||||
await asyncio.sleep_ms(100)
|
await asyncio.sleep_ms(100)
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ def on_microwave_change(state: MicrowaveState, field: MicrowaveStateFields):
|
|||||||
if state.cooking_state in (CookingStates.DONE, CookingStates.STIRRING_REQUIRED, CookingStates.ALERT):
|
if state.cooking_state in (CookingStates.DONE, CookingStates.STIRRING_REQUIRED, CookingStates.ALERT):
|
||||||
# Trigger buzzer for user attention
|
# Trigger buzzer for user attention
|
||||||
beats = 5 if state.cooking_state == CookingStates.ALERT else (1 if state.cooking_state == CookingStates.STIRRING_REQUIRED else 3)
|
beats = 5 if state.cooking_state == CookingStates.ALERT else (1 if state.cooking_state == CookingStates.STIRRING_REQUIRED else 3)
|
||||||
buzzer.buzzer_siren(beatsNb=beats)
|
buzzer.buzzer_siren(beats_nb=beats)
|
||||||
elif state.cooking_state == CookingStates.DONE and state.state == MicrowaveState.COOKING:
|
elif state.cooking_state == CookingStates.DONE and state.state == MicrowaveState.COOKING:
|
||||||
state.set_state(MicrowaveState.DONE)
|
state.set_state(MicrowaveState.DONE)
|
||||||
print(f"[{state.microwave_id}] Cooking finished. Waiting for user to remove dish.")
|
print(f"[{state.microwave_id}] Cooking finished. Waiting for user to remove dish.")
|
||||||
@@ -275,17 +275,17 @@ async def rfid_listener_task():
|
|||||||
TECHNICIAN_MODE = True
|
TECHNICIAN_MODE = True
|
||||||
print(f"[RFID] Card {tag_id} VALIDATED! -> TECHNICIAN_MODE = TRUE")
|
print(f"[RFID] Card {tag_id} VALIDATED! -> TECHNICIAN_MODE = TRUE")
|
||||||
# Optional: Sound positive feedback beep
|
# Optional: Sound positive feedback beep
|
||||||
buzzer.buzzer_siren(beatsNb=1)
|
buzzer.buzzer_siren(beats_nb=2)
|
||||||
else:
|
else:
|
||||||
print(f"[RFID] Card {tag_id} REJECTED / Invalid.")
|
print(f"[RFID] Card {tag_id} REJECTED / Invalid.")
|
||||||
# Optional: Sound error feedback beep
|
# Optional: Sound error feedback beep
|
||||||
buzzer.buzzer_siren(beatsNb=2)
|
buzzer.buzzer_siren(beats_nb=4)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[RFID Task] Error reading RFID tag: {e}")
|
print(f"[RFID Task] Error reading RFID tag: {e}")
|
||||||
|
|
||||||
# Sleep 100ms between checks to keep CPU usage near zero
|
# Sleep 100ms between checks to keep CPU usage near zero
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.2)
|
||||||
|
|
||||||
async def display_broadcast_worker_task():
|
async def display_broadcast_worker_task():
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,33 +1,45 @@
|
|||||||
import time
|
import time
|
||||||
|
import threading
|
||||||
import grovepi
|
import grovepi
|
||||||
from sensors.lock import grove_lock
|
from sensors.lock import grove_lock
|
||||||
from shared import config
|
from shared import config
|
||||||
|
|
||||||
# Pin definition
|
BUZZER_PIN = 8 # Must be a PWM pin on GrovePi (D3, D5, D6, D8 support analogWrite)
|
||||||
BUZZER_PIN = 8
|
|
||||||
|
|
||||||
grovepi.pinMode(BUZZER_PIN, "OUTPUT")
|
# Initialize pin mode
|
||||||
buzzer_state = 0
|
try:
|
||||||
|
with grove_lock:
|
||||||
|
grovepi.pinMode(BUZZER_PIN, "OUTPUT")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[BUZZER] Init error: {e}")
|
||||||
|
|
||||||
def set_buzzer(state: int):
|
def _siren_worker(beats_nb: int, delay: float):
|
||||||
global buzzer_state
|
|
||||||
buzzer_state = state
|
|
||||||
if not config.BUZZER_ACTIVATED:
|
if not config.BUZZER_ACTIVATED:
|
||||||
return
|
return
|
||||||
try:
|
|
||||||
with grove_lock:
|
with grove_lock:
|
||||||
grovepi.digitalWrite(BUZZER_PIN, state)
|
try:
|
||||||
|
for _ in range(beats_nb):
|
||||||
|
# 1. Send single PWM write to start sound (Duty cycle ~128/255)
|
||||||
|
grovepi.analogWrite(BUZZER_PIN, 128)
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
|
# 2. Send single PWM write to kill sound
|
||||||
|
grovepi.analogWrite(BUZZER_PIN, 0)
|
||||||
|
time.sleep(delay)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[BUZZER] Error occurred while setting buzzer state: {e}")
|
print(f"[BUZZER] Error during siren execution: {e}")
|
||||||
|
finally:
|
||||||
|
# Absolute safety reset
|
||||||
|
try:
|
||||||
|
grovepi.analogWrite(BUZZER_PIN, 0)
|
||||||
|
grovepi.digitalWrite(BUZZER_PIN, 0)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
def buzzer_toggle():
|
def buzzer_siren(beats_nb: int = 3, delay: float = 0.2, async_run: bool = True):
|
||||||
global buzzer_state
|
if async_run:
|
||||||
new_state = 1 - buzzer_state
|
thread = threading.Thread(target=_siren_worker, args=(beats_nb, delay), daemon=True)
|
||||||
set_buzzer(new_state)
|
thread.start()
|
||||||
|
else:
|
||||||
def buzzer_siren(beatsNb: int = 3, delay: float = 0.3):
|
_siren_worker(beats_nb, delay)
|
||||||
for _ in range(beatsNb):
|
|
||||||
set_buzzer(1)
|
|
||||||
time.sleep(delay)
|
|
||||||
set_buzzer(0)
|
|
||||||
time.sleep(delay)
|
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
import grovepi
|
|
||||||
import math
|
|
||||||
from sensors.lock import grove_lock
|
|
||||||
from picamera2 import Picamera2, Preview
|
from picamera2 import Picamera2, Preview
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user