From cd520530db8b51fe60783f96c5f31fa34305d886 Mon Sep 17 00:00:00 2001 From: Ron Klinkien Date: Sat, 3 Jan 2026 18:49:43 +0100 Subject: [PATCH] Added last workout and last workouts sensors --- README.md | 21 +++++++++++++++++++ .../garmin_connect/coordinator.py | 11 ++++++++++ .../garmin_connect/sensor_descriptions.py | 19 +++++++++++++++++ .../garmin_connect/translations/en.json | 6 ++++++ docs/garmin_connect.markdown | 5 +++++ 5 files changed, 62 insertions(+) diff --git a/README.md b/README.md index 4b532ff..38bde50 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,7 @@ Sensor values depend on your Garmin devices and connected apps. |--------|-------------| | Next Alarm | Next scheduled alarm time | | Last Activity/Activities | Recent activity info | +| Last Workout/Workouts | Scheduled/planned training sessions | | Badges/User Points/Level | Gamification metrics | ### Menstrual Cycle Tracking @@ -361,6 +362,26 @@ pip install -r requirements_lint.txt # to auto-fix: ruff check . --fix ``` +### Discovering New API Endpoints + +Want to add support for new Garmin features? Here's how to find the API endpoints: + +1. **Login to [Garmin Connect](https://connect.garmin.com)** in your browser +2. **Open Developer Tools** (F12 or Right-click → Inspect) +3. Go to the **Network** tab +4. **Filter by "Fetch/XHR"** to see API calls only +5. **Navigate through the feature** you want to capture +6. **Look for API calls** - they typically go to: + - `connect.garmin.com/proxy/*` + - `connect.garmin.com/activity-service/*` + - `connect.garmin.com/metrics-service/*` + - `connect.garmin.com/*-service/*` +7. **Click on a request** to see the full URL and response data + +**Share your findings** in a GitHub issue with: +- The full API URL path +- Example response data (redact personal info) + ## 💖 Support This Project If you find this library useful for your projects, please consider supporting its continued development and maintenance: diff --git a/custom_components/garmin_connect/coordinator.py b/custom_components/garmin_connect/coordinator.py index 002e4c3..4f9f179 100644 --- a/custom_components/garmin_connect/coordinator.py +++ b/custom_components/garmin_connect/coordinator.py @@ -182,6 +182,17 @@ class GarminConnectDataUpdateCoordinator(DataUpdateCoordinator): summary["lastActivities"] = last_activities summary["lastActivity"] = last_activities[0] if last_activities else {} + # Fetch workouts (scheduled/planned training sessions) + try: + workouts = await self.hass.async_add_executor_job( + self.api.get_workouts, 0, 10 + ) + summary["workouts"] = workouts.get("workouts", []) if isinstance(workouts, dict) else workouts + summary["lastWorkout"] = summary["workouts"][0] if summary["workouts"] else {} + except Exception: + summary["workouts"] = [] + summary["lastWorkout"] = {} + badges = await self.hass.async_add_executor_job(self.api.get_earned_badges) summary["badges"] = badges diff --git a/custom_components/garmin_connect/sensor_descriptions.py b/custom_components/garmin_connect/sensor_descriptions.py index e819f00..74165ed 100644 --- a/custom_components/garmin_connect/sensor_descriptions.py +++ b/custom_components/garmin_connect/sensor_descriptions.py @@ -842,6 +842,25 @@ ACTIVITY_TRACKING_SENSORS: tuple[GarminConnectSensorEntityDescription, ...] = ( ], }, ), + GarminConnectSensorEntityDescription( + key="lastWorkout", + translation_key="last_workout", + icon="mdi:dumbbell", + + value_fn=lambda data: data.get("lastWorkout", {}).get("workoutName"), + attributes_fn=lambda data: data.get("lastWorkout", {}), + ), + GarminConnectSensorEntityDescription( + key="lastWorkouts", + translation_key="last_workouts", + state_class=SensorStateClass.TOTAL, + icon="mdi:dumbbell", + + value_fn=lambda data: len(data.get("workouts", [])), + attributes_fn=lambda data: { + "last_workouts": data.get("workouts", [])[-10:], + }, + ), GarminConnectSensorEntityDescription( key="badges", translation_key="badges", diff --git a/custom_components/garmin_connect/translations/en.json b/custom_components/garmin_connect/translations/en.json index de37c12..9863095 100644 --- a/custom_components/garmin_connect/translations/en.json +++ b/custom_components/garmin_connect/translations/en.json @@ -337,6 +337,12 @@ "last_activities": { "name": "Last activities" }, + "last_workout": { + "name": "Last workout" + }, + "last_workouts": { + "name": "Last workouts" + }, "badges": { "name": "Badges" }, diff --git a/docs/garmin_connect.markdown b/docs/garmin_connect.markdown index 47906d2..3ccc714 100644 --- a/docs/garmin_connect.markdown +++ b/docs/garmin_connect.markdown @@ -101,6 +101,11 @@ This integration provides **110+ sensors** covering various health and fitness m - **Fitness Age** - Estimated fitness age - **Endurance Score** - Overall endurance rating +### Workouts + +- **Last Workout** - Name of most recent scheduled workout +- **Last Workouts** - Count of recent workouts (details in attributes) + ### Menstrual Cycle Tracking - **Cycle Phase** - Current menstrual phase