From a2f4b16bf25a302b8b3fa0ad3debef1d12415f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Gro=C3=9Fklo=C3=9F?= Date: Sun, 7 Dec 2025 16:24:10 +0100 Subject: [PATCH] Rename to Fitness Tracker, add Device sensor with actual band name --- __pycache__/main.cpython-314.pyc | Bin 0 -> 23936 bytes main.py | 29 +++++++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 __pycache__/main.cpython-314.pyc diff --git a/__pycache__/main.cpython-314.pyc b/__pycache__/main.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf819e2a3de225cd6fed0d53325bf6da8b658103 GIT binary patch literal 23936 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 As{jB1 literal 0 HcmV?d00001 diff --git a/main.py b/main.py index 1bbe883..8300d57 100644 --- a/main.py +++ b/main.py @@ -89,7 +89,8 @@ class GadgetbridgeMQTT: def __init__(self, config): self.config = config self.db_path = None - self.device_name = "fitness_tracker" + self.device_name = "fitness_tracker" # MQTT identifier (always fitness_tracker) + self.device_alias = "Unknown" # Actual device name for display self.device_id = None # Track device ID for filtering queries self.mqtt_client = None self.last_publish_time = 0 @@ -155,13 +156,13 @@ class GadgetbridgeMQTT: row = cursor.fetchone() if row: device_id = row[0] - alias = row[1] if row[1] else row[2] # Use ALIAS, fallback to NAME - device_name = re.sub(r"\W+", "_", alias).lower() if alias else "fitness_tracker" - logger.info(f"Selected device: ID={device_id}, Name={alias}") - return device_id, device_name + # Get actual device name for display + device_alias = row[1] if row[1] else row[2] # Use ALIAS, fallback to NAME + logger.info(f"Selected device: ID={device_id}, Name={device_alias}") + return device_id, device_alias except Exception as e: logger.error(f"Error getting device info: {e}") - return None, "fitness_tracker" + return None, "Unknown" def get_day_start_timestamp(self): """Get timestamp for start of current day (4am)""" @@ -285,18 +286,22 @@ class GadgetbridgeMQTT: # Server time data["server_time"] = datetime.now().astimezone().isoformat() + # Device name (actual band name) + data["device"] = self.device_alias + return data def publish_discovery(self): """Publish Home Assistant MQTT discovery configs""" device_info = { "identifiers": [self.device_name], - "name": f"Gadgetbridge {self.device_name.replace('_', ' ').title()}", - "model": "Fitness Tracker", + "name": "Fitness Tracker", + "model": self.device_alias, "manufacturer": "Gadgetbridge", } sensors = [ + ("device", "Device", None, "mdi:watch", None, None), ("daily_steps", "Daily Steps", "steps", "mdi:walk", "total_increasing", None), ("weekly_steps", "Weekly Steps", "steps", "mdi:walk", "total", None), ("battery_level", "Battery", "%", "mdi:battery", None, "battery"), @@ -313,7 +318,7 @@ class GadgetbridgeMQTT: for sensor_id, name, unit, icon, state_class, device_class in sensors: config = { - "name": f"{self.device_name.replace('_', ' ').title()} {name}", + "name": f"Fitness Tracker {name}", "unique_id": f"{self.device_name}_{sensor_id}", "state_topic": f"gadgetbridge/{self.device_name}/{sensor_id}", "device": device_info, @@ -352,8 +357,8 @@ class GadgetbridgeMQTT: conn = sqlite3.connect(self.db_path, timeout=10.0) cursor = conn.cursor() - # Get device ID and name - self.device_id, self.device_name = self.get_device_info(cursor) + # Get device ID and actual name + self.device_id, self.device_alias = self.get_device_info(cursor) if not self.device_id: logger.warning("No fitness device found in database") @@ -421,7 +426,7 @@ class GadgetbridgeMQTT: try: conn = sqlite3.connect(self.db_path, timeout=5.0) cursor = conn.cursor() - self.device_id, self.device_name = self.get_device_info(cursor) + self.device_id, self.device_alias = self.get_device_info(cursor) conn.close() except Exception as e: logger.warning(f"Could not read device info: {e}")