Add signal handlers, retry logic, and improved boot script

This commit is contained in:
Oliver Großkloß 2025-12-07 15:41:03 +01:00
parent 86a2d896f9
commit 4bf5f13233
4 changed files with 59 additions and 28 deletions

Binary file not shown.

Binary file not shown.

70
main.py
View File

@ -12,6 +12,7 @@ import logging
import sys
import time
import re
import signal
from datetime import datetime, timedelta
from pathlib import Path
@ -92,6 +93,16 @@ class GadgetbridgeMQTT:
self.mqtt_client = None
self.last_publish_time = 0
self.last_db_mtime = 0
self.running = True
# Register signal handlers for graceful shutdown
signal.signal(signal.SIGTERM, self._signal_handler)
signal.signal(signal.SIGINT, self._signal_handler)
def _signal_handler(self, signum, frame):
"""Handle shutdown signals gracefully"""
logger.info(f"Received signal {signum}. Shutting down...")
self.running = False
def connect_mqtt(self):
"""Connect to MQTT broker"""
@ -365,39 +376,47 @@ class GadgetbridgeMQTT:
discovery_published = False
try:
while True:
while self.running:
current_time = time.time()
# Check if it's time to trigger sync and publish
if current_time - self.last_publish_time >= interval:
logger.info("Triggering Gadgetbridge sync...")
trigger_gadgetbridge_sync()
try:
logger.info("Triggering Gadgetbridge sync...")
trigger_gadgetbridge_sync()
# Wait for export to complete
time.sleep(10)
# Wait for export to complete
time.sleep(10)
# Find latest database
self.db_path = find_latest_db(export_dir)
# Find latest database with retry
self.db_path = find_latest_db(export_dir)
if not self.db_path:
logger.warning(f"No database found, retrying in 3s...")
time.sleep(3)
self.db_path = find_latest_db(export_dir)
if self.db_path:
logger.info(f"Using database: {os.path.basename(self.db_path)}")
if self.db_path:
logger.info(f"Using database: {os.path.basename(self.db_path)}")
# Publish discovery on first successful read
if not discovery_published:
# Need to read device name first
try:
conn = sqlite3.connect(self.db_path, timeout=5.0)
cursor = conn.cursor()
self.device_name = self.get_device_alias(cursor)
conn.close()
except:
pass
self.publish_discovery()
discovery_published = True
# Publish discovery on first successful read
if not discovery_published:
# Need to read device name first
try:
conn = sqlite3.connect(self.db_path, timeout=5.0)
cursor = conn.cursor()
self.device_name = self.get_device_alias(cursor)
conn.close()
except:
pass
self.publish_discovery()
discovery_published = True
self.process_database()
else:
logger.warning(f"No database found in {export_dir}")
self.process_database()
else:
logger.warning(f"No database found in {export_dir}")
except Exception as e:
logger.error(f"Sync cycle failed: {e}")
self.last_publish_time = current_time
logger.info(f"Next publish in {interval}s...")
@ -405,8 +424,9 @@ class GadgetbridgeMQTT:
time.sleep(10) # Check every 10 seconds
except KeyboardInterrupt:
logger.info("Shutting down...")
logger.info("Interrupted by user")
finally:
logger.info("Cleaning up...")
self.disconnect_mqtt()

View File

@ -121,9 +121,20 @@ termux-wake-lock
# Wait for system to fully boot
sleep 30
# Kill any existing process
pkill -f gadgetbridge_mqtt.py 2>/dev/null
# Start the MQTT publisher in background
cd ~
python ~/scripts/gadgetbridge_mqtt.py >> ~/gb_mqtt.log 2>&1 &
# Verify it started
sleep 2
if pgrep -f gadgetbridge_mqtt.py > /dev/null; then
echo "$(date): Gadgetbridge MQTT started successfully" >> ~/gb_mqtt.log
else
echo "$(date): ERROR - Failed to start" >> ~/gb_mqtt.log
fi
"""
with open(boot_script, "w") as f: