Track sleep state and adjust data freshness checks for improved recovery logic
This commit is contained in:
parent
8514180505
commit
e11b4564f0
34
main.py
34
main.py
@ -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}")
|
||||
|
||||
@ -496,6 +500,9 @@ class GadgetbridgeMQTT:
|
||||
resting_hr=resting_hr,
|
||||
)
|
||||
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",
|
||||
@ -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,21 +650,27 @@ 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)
|
||||
|
||||
# 2. Reset timestamp so we don't loop immediately
|
||||
self.last_data_timestamp = current_ts
|
||||
self.last_data_timestamp = current_ts
|
||||
else:
|
||||
logger.warning("Cannot recover: No device MAC available")
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user