fix: background task initialization
- Fixed double-start issue with background tasks - Improved task error handling - Added more descriptive logging - Made auto-close logic more consistent
This commit is contained in:
parent
9046cbca1d
commit
acf51a9242
|
|
@ -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 = []
|
||||
|
|
|
|||
Loading…
Reference in New Issue