fix indentation

This commit is contained in:
Oliver 2025-09-17 20:17:25 +00:00
parent 0a9b13eacf
commit 43930562cb

131
main.py
View File

@ -1,11 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" """
Gadgetbridge MQTT Step Counter Integration Gadgetbridge MQTT Step Counter Integration
Extracts sensor data from Gadgetbridge SQLite database and publishes to Home Assistant via MQTT Extracts sensor data from Gadgetbridge SQLite database and publishes to Home Assistant via MQTT
""" """
import os import os
@ -23,12 +20,44 @@ class GadgetbridgeMQTTPublisher:
def __init__(self): def __init__(self):
self.setup_logging() self.setup_logging()
self.db_path = os.getenv("GADGETBRIDGE_DB_PATH", "/data/Gadgetbridge.db") self.db_path = os.getenv("GADGETBRIDGE_DB_PATH", "/data/Gadgetbridge.db")
self.device_name = self.get_device_alias()
self.load_config() self.load_config()
self.mqtt_client = None self.mqtt_client = None
self.publish_interval = int(os.getenv("PUBLISH_INTERVAL_SECONDS", "300")) self.publish_interval = int(os.getenv("PUBLISH_INTERVAL_SECONDS", "300"))
self.max_retries = int(os.getenv("MAX_RETRIES", "5")) self.max_retries = int(os.getenv("MAX_RETRIES", "5"))
self.retry_delay = int(os.getenv("RETRY_DELAY_SECONDS", "30")) self.retry_delay = int(os.getenv("RETRY_DELAY_SECONDS", "30"))
# Initialize device_name with fallback - don't fail on DB issues during init
try:
self.device_name = self.get_device_alias()
except Exception as e:
self.logger.warning(f"Could not get device alias during init: {e}")
self.device_name = "fitness_tracker"
# Initialize sensors after device_name is set
self.initialize_sensors()
def setup_logging(self):
"""Setup logging configuration (console only)"""
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[
logging.StreamHandler(),
],
)
self.logger = logging.getLogger(__name__)
def load_config(self):
"""Load MQTT configuration from environment variables"""
self.mqtt_config = {
"broker": os.getenv("MQTT_BROKER", "localhost"),
"port": int(os.getenv("MQTT_PORT", "1883")),
"username": os.getenv("MQTT_USERNAME", ""),
"password": os.getenv("MQTT_PASSWORD", ""),
}
def initialize_sensors(self):
"""Initialize sensor definitions after device_name is available"""
self.sensors = [ self.sensors = [
{ {
"name": "Daily Steps", "name": "Daily Steps",
@ -139,26 +168,6 @@ class GadgetbridgeMQTTPublisher:
}, },
] ]
def setup_logging(self):
"""Setup logging configuration (console only)"""
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[
logging.StreamHandler(),
],
)
self.logger = logging.getLogger(__name__)
def load_config(self):
"""Load MQTT configuration from environment variables"""
self.mqtt_config = {
"broker": os.getenv("MQTT_BROKER", "localhost"),
"port": int(os.getenv("MQTT_PORT", "1883")),
"username": os.getenv("MQTT_USERNAME", ""),
"password": os.getenv("MQTT_PASSWORD", ""),
}
async def publish_home_assistant_discovery( async def publish_home_assistant_discovery(
self, entity_type: str, entity_id: str, config: Dict self, entity_type: str, entity_id: str, config: Dict
): ):
@ -340,55 +349,69 @@ class GadgetbridgeMQTTPublisher:
self.logger.info(f"Published sensor data: {data}") self.logger.info(f"Published sensor data: {data}")
async def run_main_loop(self): async def run_main_loop(self):
"""Main execution loop with error recovery - simplified version""" """Main execution loop with error recovery"""
while True: while True:
try: try:
async with aiomqtt.Client( self.logger.info("Attempting MQTT connection...")
hostname=self.mqtt_config["broker"], async with aiomqtt.Client(
port=self.mqtt_config["port"], hostname=self.mqtt_config["broker"],
username=self.mqtt_config["username"] or None, port=self.mqtt_config["port"],
password=self.mqtt_config["password"] or None, username=self.mqtt_config["username"] or None,
) as client: password=self.mqtt_config["password"] or None,
self.mqtt_client = client ) as client:
self.logger.info("MQTT connection successful") self.mqtt_client = client
self.logger.info("MQTT connection successful")
await self.setup_home_assistant_entities()
await self.setup_home_assistant_entities()
# Publish immediately on startup
sensor_data = self.get_sensor_data() # Publish immediately on startup
await self.publish_sensor_data(sensor_data)
# Main publishing loop
while True:
await asyncio.sleep(self.publish_interval)
sensor_data = self.get_sensor_data() sensor_data = self.get_sensor_data()
await self.publish_sensor_data(sensor_data) await self.publish_sensor_data(sensor_data)
self.logger.info(f"Next publish in {self.publish_interval} seconds...")
# Main publishing loop
while True:
await asyncio.sleep(self.publish_interval)
sensor_data = self.get_sensor_data()
await self.publish_sensor_data(sensor_data)
self.logger.info(f"Next publish in {self.publish_interval} seconds...")
except Exception as e: except Exception as e:
self.logger.error(f"Error in main loop: {e}") self.logger.error(f"Error in main loop: {e}")
self.logger.info(f"Restarting main loop in {self.retry_delay} seconds...") self.logger.info(f"Restarting main loop in {self.retry_delay} seconds...")
await asyncio.sleep(self.retry_delay) await asyncio.sleep(self.retry_delay)
async def run(self): async def run(self):
"""Main execution method (async) - now with proper error recovery""" """Main execution method (async) - now with proper error recovery"""
self.logger.info("Starting Gadgetbridge MQTT Publisher") self.logger.info("Starting Gadgetbridge MQTT Publisher")
# Initial database check # Initial database check with wait loop
if not os.path.exists(self.db_path): if not os.path.exists(self.db_path):
self.logger.error(f"Database file not found: {self.db_path}") self.logger.error(f"Database file not found: {self.db_path}")
self.logger.error("Waiting for database to become available...") self.logger.info("Waiting for database to become available...")
while not os.path.exists(self.db_path): while not os.path.exists(self.db_path):
await asyncio.sleep(30) await asyncio.sleep(30)
self.logger.info("Still waiting for database...")
self.logger.info("Database file found, continuing...") self.logger.info("Database file found, continuing...")
# Try to get proper device name now that DB might be available
try:
new_device_name = self.get_device_alias()
if new_device_name != self.device_name:
self.logger.info(f"Updating device name from {self.device_name} to {new_device_name}")
self.device_name = new_device_name
self.initialize_sensors() # Reinitialize with correct device name
except Exception as e:
self.logger.warning(f"Could not update device alias: {e}, using fallback")
# Run main loop with recovery # Run main loop with recovery
await self.run_main_loop() await self.run_main_loop()
def get_device_alias(self) -> str: def get_device_alias(self) -> str:
"""Fetch ALIAS from DEVICE table for device_name where NAME contains 'band' or 'watch' (case-insensitive)""" """Fetch ALIAS from DEVICE table for device_name where NAME contains 'band' or 'watch' (case-insensitive)"""
if not os.path.exists(self.db_path): if not os.path.exists(self.db_path):
self.logger.warning(f"Database file not found during init: {self.db_path}") self.logger.warning(f"Database file not found: {self.db_path}")
return "fitness_tracker" return "fitness_tracker"
try: try:
@ -418,4 +441,4 @@ async def run_main_loop(self):
if __name__ == "__main__": if __name__ == "__main__":
publisher = GadgetbridgeMQTTPublisher() publisher = GadgetbridgeMQTTPublisher()
asyncio.run(publisher.run()) asyncio.run(publisher.run())