diff --git a/backend/main.py b/backend/main.py index 2437c46..ed391b4 100644 --- a/backend/main.py +++ b/backend/main.py @@ -42,7 +42,7 @@ class GPIOSettings(BaseModel): statusPin: int = 7 # Gate open status pin class LoggingSettings(BaseModel): - level: str = "WARNING" # Default to WARNING level + level: str = "INFO" # Default to INFO level maxBytes: int = 10 * 1024 * 1024 # 10MB default backupCount: int = 5 # Keep 5 backup files by default @@ -278,6 +278,15 @@ last_open_time = None gate_monitor_running = False auto_close_running = False +async def start_background_tasks(): + """Start all background monitoring tasks""" + logger.info("Starting background tasks...") + + # Don't set global flags here, let the tasks set them + app.state.status_task = asyncio.create_task(update_gate_status()) + app.state.auto_close_task = asyncio.create_task(check_auto_close()) + logger.info("Background tasks started") + async def update_gate_status(): """Monitor gate status and update database when it changes""" global gate_monitor_running @@ -333,64 +342,54 @@ async def update_gate_status(): logger.info("Gate status monitor stopped") async def check_auto_close(): - """Check if gate has been open too long and close it if needed""" - global last_open_time, auto_close_running + """Monitor gate status and auto-close if open too long""" + global auto_close_running if auto_close_running: logger.warning("Auto-close monitor already running, skipping...") return - + auto_close_running = True - logger.info("Starting auto-close monitoring task") try: - settings = app.state.current_settings - if not settings: - logger.warning("No settings available, using default settings") - settings = Settings() - - status_pin = settings.gpio.statusPin - consecutive_errors = 0 - while True: try: - if not auto_close_running: - logger.info("Auto-close monitor stopped") - break - - if GPIO.input(status_pin) == GPIO.HIGH: # Gate is open - current_time = datetime.now() - + settings = app.state.current_settings + if not settings: + logger.warning("No settings available for auto-close, using defaults") + settings = Settings() + + current_time = datetime.now() + + # Check if gate is open + if gate_status.is_open: + # If this is the first time we see it open, record the time + global last_open_time if last_open_time is None: last_open_time = current_time - logger.debug("Gate opened, starting timer") + logger.debug("Gate opened, starting auto-close timer") + # Calculate how long it's been open time_open = (current_time - last_open_time).total_seconds() - logger.debug(f"Gate has been open for {time_open:.1f} seconds") + # Auto-close if it's been open too long if time_open > settings.maxOpenTimeSeconds: logger.warning(f"Gate has been open for {time_open:.1f} seconds, auto-closing") - timestamp = current_time.isoformat() - - await add_event(timestamp, "auto-close", "system") - + await add_event(current_time.isoformat(), "auto-close", "system") await trigger_gate() last_open_time = None - logger.info("Gate auto-closed successfully") else: + # Reset last open time if gate is closed if last_open_time is not None: - logger.debug("Gate is now closed, resetting timer") - last_open_time = None + logger.debug("Gate closed, resetting auto-close timer") + last_open_time = None - consecutive_errors = 0 await asyncio.sleep(1) except Exception as e: - consecutive_errors += 1 - wait_time = min(30, 2 ** consecutive_errors) - logger.error(f"Error in check_auto_close (attempt {consecutive_errors}): {e}", exc_info=True) - logger.warning(f"Retrying in {wait_time} seconds...") - await asyncio.sleep(wait_time) + logger.error(f"Error in auto_close_monitor: {e}", exc_info=True) + await asyncio.sleep(5) # Wait before retrying + finally: auto_close_running = False logger.info("Auto-close monitor stopped") @@ -467,7 +466,7 @@ async def get_settings_route(): "statusPin": 7 }), "logging": settings_dict.get("logging", { - "level": "WARNING", + "level": "INFO", "maxBytes": 10 * 1024 * 1024, "backupCount": 5 }) @@ -698,16 +697,6 @@ async def publish_mqtt_state(state: bool) -> bool: logger.error(f"Failed to publish MQTT state: {e}", exc_info=True) return False -async def start_background_tasks(): - """Start all background monitoring tasks""" - logger.info("Starting background tasks...") - global gate_monitor_running, auto_close_running - gate_monitor_running = True - auto_close_running = True - app.state.status_task = asyncio.create_task(update_gate_status()) - app.state.auto_close_task = asyncio.create_task(check_auto_close()) - logger.info("Background tasks started") - async def validate_startup_state() -> tuple[bool, list[str]]: """Validate application startup state""" errors = []