Compare commits

...

2 Commits

Author SHA1 Message Date
Ninluc 204f271fc2 Fix global
Build, push image, and notify Watchtower / build-image (push) Successful in 42s
Build, push image, and notify Watchtower / notify (push) Successful in 14s
2026-08-23 20:04:26 +02:00
Ninluc 5c60de3f03 Fix buzzer 2026-08-23 20:04:20 +02:00
4 changed files with 45 additions and 33 deletions
+6 -3
View File
@@ -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)
+4 -4
View File
@@ -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():
""" """
+35 -23
View File
@@ -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:
grovepi.digitalWrite(BUZZER_PIN, state)
except Exception as e:
print(f"[BUZZER] Error occurred while setting buzzer state: {e}")
def buzzer_toggle(): with grove_lock:
global buzzer_state try:
new_state = 1 - buzzer_state for _ in range(beats_nb):
set_buzzer(new_state) # 1. Send single PWM write to start sound (Duty cycle ~128/255)
grovepi.analogWrite(BUZZER_PIN, 128)
def buzzer_siren(beatsNb: int = 3, delay: float = 0.3): time.sleep(delay)
for _ in range(beatsNb):
set_buzzer(1) # 2. Send single PWM write to kill sound
time.sleep(delay) grovepi.analogWrite(BUZZER_PIN, 0)
set_buzzer(0) time.sleep(delay)
time.sleep(delay) except Exception as 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_siren(beats_nb: int = 3, delay: float = 0.2, async_run: bool = True):
if async_run:
thread = threading.Thread(target=_siren_worker, args=(beats_nb, delay), daemon=True)
thread.start()
else:
_siren_worker(beats_nb, delay)
-3
View File
@@ -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