fix indentation
This commit is contained in:
parent
0a9b13eacf
commit
43930562cb
125
main.py
125
main.py
@ -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
|
# Publish immediately on startup
|
||||||
sensor_data = self.get_sensor_data()
|
|
||||||
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...")
|
||||||
|
|
||||||
except Exception as e:
|
# Main publishing loop
|
||||||
self.logger.error(f"Error in main loop: {e}")
|
while True:
|
||||||
self.logger.info(f"Restarting main loop in {self.retry_delay} seconds...")
|
await asyncio.sleep(self.publish_interval)
|
||||||
await asyncio.sleep(self.retry_delay)
|
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:
|
||||||
|
self.logger.error(f"Error in main loop: {e}")
|
||||||
|
self.logger.info(f"Restarting main loop in {self.retry_delay} seconds...")
|
||||||
|
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:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user