Track sleep state and adjust data freshness checks for improved recovery logic

This commit is contained in:
Oliver Großkloß 2025-12-26 20:10:14 +01:00
parent 8514180505
commit e11b4564f0

30
main.py
View File

@ -155,6 +155,7 @@ class GadgetbridgeMQTT:
# New: Track data freshness for watchdog
self.last_data_timestamp = 0
self.is_sleeping = False # Track sleep state to skip stale checks during sleep
# Register signal handlers for graceful shutdown
signal.signal(signal.SIGTERM, self._signal_handler)
@ -404,7 +405,10 @@ class GadgetbridgeMQTT:
row = cursor.fetchone()
if row:
data["heart_rate"] = row[0]
self.last_data_timestamp = row[1] # <--- NEW: Update timestamp
# Only update timestamp if DB has newer data than our last recovery
# This prevents the recovery loop when DB timestamp is stale
if row[1] > self.last_data_timestamp:
self.last_data_timestamp = row[1]
except Exception as e:
logger.debug(f"Heart rate query failed: {e}")
@ -497,6 +501,9 @@ class GadgetbridgeMQTT:
)
data["is_awake"] = is_awake
# Update sleep state for watchdog (use longer stale threshold during sleep)
self.is_sleeping = not is_awake
stage_names = {
0: "not_sleep",
1: "unknown",
@ -518,10 +525,12 @@ class GadgetbridgeMQTT:
data["sleep_stage"] = "not_sleep" if is_awake else "unknown"
data["sleep_stage_code"] = 0
else:
# No sleep data - user is awake
data["is_awake"] = True
data["in_sleep_session"] = False
data["sleep_stage"] = "not_sleep"
data["sleep_stage_code"] = 0
self.is_sleeping = False
except Exception as e:
logger.debug(f"Sleep query failed: {e}")
@ -598,9 +607,14 @@ class GadgetbridgeMQTT:
# Use retain=True so HA gets values on restart
self.mqtt_client.publish(topic, str(value), qos=1, retain=True)
# Log key metrics including sleep status
sleep_info = f"sleep={data.get('sleep_duration', 0)}h" if 'sleep_duration' in data else "sleep=N/A"
awake_info = f"awake={data.get('is_awake', 'N/A')}"
logger.info(f"Published: steps={data.get('daily_steps', 'N/A')}, "
f"hr={data.get('heart_rate', 'N/A')}, "
f"battery={data.get('battery_level', 'N/A')}%")
f"battery={data.get('battery_level', 'N/A')}%, "
f"{sleep_info}, {awake_info}")
def process_database(self):
"""Read database and publish data"""
@ -636,15 +650,21 @@ class GadgetbridgeMQTT:
def check_and_recover_connection(self):
"""
WATCHDOG: Checks if data is stale (>20 mins) and forces Bluetooth restart if so.
During sleep, the band syncs data less frequently, so we use a longer
threshold (60 mins) to avoid false recovery triggers.
"""
if self.last_data_timestamp == 0:
return # No data seen yet, skip check
return # No data seen yet, skip check
# Use longer threshold during sleep (band syncs less frequently)
threshold = STALE_THRESHOLD_SECONDS * 3 if self.is_sleeping else STALE_THRESHOLD_SECONDS
current_ts = int(time.time())
time_diff = current_ts - self.last_data_timestamp
if time_diff > STALE_THRESHOLD_SECONDS:
logger.warning(f"Data stale ({time_diff}s > {STALE_THRESHOLD_SECONDS}s). Triggering recovery...")
if time_diff > threshold:
logger.warning(f"Data stale ({time_diff}s > {threshold}s). Triggering recovery...")
if self.device_mac:
# 1. Disconnect and wait
trigger_bluetooth_reconnect(self.device_mac)