mirror of
https://github.com/cyberjunky/home-assistant-garmin_connect.git
synced 2026-01-09 12:57:58 -05:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef91580157 | ||
|
|
1c3e5a4385 | ||
|
|
b6aebe1637 | ||
|
|
9cf15616ab | ||
|
|
911ca663ab | ||
|
|
645d3842bd | ||
|
|
04aa1e7093 | ||
|
|
f33c2803bc | ||
|
|
d118638429 | ||
|
|
3103929f5f | ||
|
|
842355d273 | ||
|
|
e2728b6bc2 | ||
|
|
b75133a2d4 | ||
|
|
ecbed70aee | ||
|
|
a761bc00a3 | ||
|
|
517bd5af5d | ||
|
|
dc4e7301d8 | ||
|
|
e7ab9ef561 | ||
|
|
5438cd2d59 | ||
|
|
4113550397 | ||
|
|
4b53fdb162 | ||
|
|
6a1b5240d7 | ||
|
|
5155e90c8a | ||
|
|
1844b50877 | ||
|
|
0241207443 | ||
|
|
eaec42124b | ||
|
|
8dea9bfa4b | ||
|
|
f13f59ae46 | ||
|
|
e958d2af89 | ||
|
|
8beb401e41 | ||
|
|
4cd2826643 |
@@ -1,16 +1,19 @@
|
||||
[](https://github.com/custom-components/hacs) [](https://www.python.org/) [](https://www.paypal.me/cyberjunkynl/)
|
||||
[](https://github.com/hacs/integration) [](https://www.python.org/) [](https://www.paypal.me/cyberjunkynl/)
|
||||
|
||||
# Garmin Connect
|
||||
The Garmin Connect integration allows you to expose data from Garmin Connect to Home Assistant.
|
||||
|
||||
NOTE: This integration doesn't support 2FA on Garmin Connect, so if you have enabled it -and want to keep it- this integration doesn't work, it will try to login repeatedly and generate lots of 2FA codes via email.
|
||||
The change of adding support for it is unlikely since the Garmin Connect API is closed source, and will not be open for open-sourced projects.
|
||||
|
||||
## Installation
|
||||
|
||||
### HACS - Recommended
|
||||
- Have [HACS](https://hacs.xyz) installed, this will allow you to easily manage and track updates.
|
||||
- Add https://github.com/cyberjunky/home-assistant-garmin_connect to custom repositories in HACS
|
||||
- Inside HACS click 'Explore & download repositories'
|
||||
- Search for 'Garmin Connect'.
|
||||
- Click Install below the found integration.
|
||||
- Click on found integration.
|
||||
- Click Download this repository with HACS.
|
||||
- Restart Home-Assistant.
|
||||
- Follow configuration steps below.
|
||||
|
||||
|
||||
@@ -93,10 +93,13 @@ class GarminConnectDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
summary = await self.hass.async_add_executor_job(
|
||||
self._api.get_user_summary, date.today().isoformat()
|
||||
)
|
||||
_LOGGER.debug(summary)
|
||||
body = await self.hass.async_add_executor_job(
|
||||
self._api.get_body_composition, date.today().isoformat()
|
||||
)
|
||||
_LOGGER.debug(body)
|
||||
alarms = await self.hass.async_add_executor_job(self._api.get_device_alarms)
|
||||
_LOGGER.debug(alarms)
|
||||
except (
|
||||
GarminConnectAuthenticationError,
|
||||
GarminConnectTooManyRequestsError,
|
||||
|
||||
@@ -2,31 +2,35 @@
|
||||
from datetime import timedelta
|
||||
|
||||
from homeassistant.const import (
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
LENGTH_METERS,
|
||||
MASS_KILOGRAMS,
|
||||
PERCENTAGE,
|
||||
TIME_MINUTES,
|
||||
TIME_YEARS,
|
||||
)
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
SensorStateClass,
|
||||
)
|
||||
|
||||
DOMAIN = "garmin_connect"
|
||||
DATA_COORDINATOR = "coordinator"
|
||||
DEFAULT_UPDATE_INTERVAL = timedelta(minutes=5)
|
||||
|
||||
GARMIN_ENTITY_LIST = {
|
||||
"totalSteps": ["Total Steps", "steps", "mdi:walk", None, True],
|
||||
"dailyStepGoal": ["Daily Step Goal", "steps", "mdi:walk", None, True],
|
||||
"totalKilocalories": ["Total KiloCalories", "kcal", "mdi:food", None, True],
|
||||
"activeKilocalories": ["Active KiloCalories", "kcal", "mdi:food", None, True],
|
||||
"bmrKilocalories": ["BMR KiloCalories", "kcal", "mdi:food", None, True],
|
||||
"consumedKilocalories": ["Consumed KiloCalories", "kcal", "mdi:food", None, False],
|
||||
"burnedKilocalories": ["Burned KiloCalories", "kcal", "mdi:food", None, True],
|
||||
"totalSteps": ["Total Steps", "steps", "mdi:walk", None, SensorStateClass.TOTAL, True],
|
||||
"dailyStepGoal": ["Daily Step Goal", "steps", "mdi:walk", None, SensorStateClass.TOTAL, True],
|
||||
"totalKilocalories": ["Total KiloCalories", "kcal", "mdi:food", None, SensorStateClass.TOTAL, True],
|
||||
"activeKilocalories": ["Active KiloCalories", "kcal", "mdi:food", None, SensorStateClass.TOTAL, True],
|
||||
"bmrKilocalories": ["BMR KiloCalories", "kcal", "mdi:food", None, SensorStateClass.TOTAL, True],
|
||||
"consumedKilocalories": ["Consumed KiloCalories", "kcal", "mdi:food", None, SensorStateClass.TOTAL, False],
|
||||
"burnedKilocalories": ["Burned KiloCalories", "kcal", "mdi:food", None, SensorStateClass.TOTAL, True],
|
||||
"remainingKilocalories": [
|
||||
"Remaining KiloCalories",
|
||||
"kcal",
|
||||
"mdi:food",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"netRemainingKilocalories": [
|
||||
@@ -34,36 +38,41 @@ GARMIN_ENTITY_LIST = {
|
||||
"kcal",
|
||||
"mdi:food",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"netCalorieGoal": ["Net Calorie Goal", "cal", "mdi:food", None, False],
|
||||
"netCalorieGoal": ["Net Calorie Goal", "kcal", "mdi:food", None, SensorStateClass.TOTAL, False],
|
||||
"totalDistanceMeters": [
|
||||
"Total Distance Mtr",
|
||||
LENGTH_METERS,
|
||||
"mdi:walk",
|
||||
None,
|
||||
SensorDeviceClass.DISTANCE,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"wellnessStartTimeLocal": [
|
||||
"Wellness Start Time",
|
||||
None,
|
||||
"mdi:clock",
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
SensorDeviceClass.TIMESTAMP,
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"wellnessEndTimeLocal": [
|
||||
"Wellness End Time",
|
||||
None,
|
||||
"mdi:clock",
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
SensorDeviceClass.TIMESTAMP,
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"wellnessDescription": ["Wellness Description", "", "mdi:clock", None, False],
|
||||
"wellnessDescription": ["Wellness Description", "", "mdi:clock", None, SensorStateClass.TOTAL, False],
|
||||
"wellnessDistanceMeters": [
|
||||
"Wellness Distance Mtr",
|
||||
LENGTH_METERS,
|
||||
"mdi:walk",
|
||||
None,
|
||||
SensorDeviceClass.DISTANCE,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"wellnessActiveKilocalories": [
|
||||
@@ -71,66 +80,74 @@ GARMIN_ENTITY_LIST = {
|
||||
"kcal",
|
||||
"mdi:food",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"wellnessKilocalories": ["Wellness KiloCalories", "kcal", "mdi:food", None, False],
|
||||
"wellnessKilocalories": ["Wellness KiloCalories", "kcal", "mdi:food", None, SensorStateClass.TOTAL, False],
|
||||
"highlyActiveSeconds": [
|
||||
"Highly Active Time",
|
||||
TIME_MINUTES,
|
||||
"mdi:fire",
|
||||
None,
|
||||
SensorDeviceClass.DURATION,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"activeSeconds": ["Active Time", TIME_MINUTES, "mdi:fire", None, True],
|
||||
"sedentarySeconds": ["Sedentary Time", TIME_MINUTES, "mdi:seat", None, True],
|
||||
"sleepingSeconds": ["Sleeping Time", TIME_MINUTES, "mdi:sleep", None, True],
|
||||
"activeSeconds": ["Active Time", TIME_MINUTES, "mdi:fire", None, SensorStateClass.TOTAL, True],
|
||||
"sedentarySeconds": ["Sedentary Time", TIME_MINUTES, "mdi:seat", None, SensorStateClass.TOTAL, True],
|
||||
"sleepingSeconds": ["Sleeping Time", TIME_MINUTES, "mdi:sleep", None, SensorStateClass.TOTAL, True],
|
||||
"measurableAwakeDuration": [
|
||||
"Awake Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:sleep",
|
||||
None,
|
||||
SensorDeviceClass.DURATION,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"measurableAsleepDuration": [
|
||||
"Sleep Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:sleep",
|
||||
None,
|
||||
SensorDeviceClass.DURATION,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"floorsAscendedInMeters": [
|
||||
"Floors Ascended Mtr",
|
||||
LENGTH_METERS,
|
||||
"mdi:stairs",
|
||||
None,
|
||||
SensorDeviceClass.DISTANCE,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"floorsDescendedInMeters": [
|
||||
"Floors Descended Mtr",
|
||||
LENGTH_METERS,
|
||||
"mdi:stairs",
|
||||
None,
|
||||
SensorDeviceClass.DISTANCE,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"floorsAscended": ["Floors Ascended", "floors", "mdi:stairs", None, True],
|
||||
"floorsDescended": ["Floors Descended", "floors", "mdi:stairs", None, True],
|
||||
"floorsAscended": ["Floors Ascended", "floors", "mdi:stairs", None, SensorStateClass.TOTAL, True],
|
||||
"floorsDescended": ["Floors Descended", "floors", "mdi:stairs", None, SensorStateClass.TOTAL, True],
|
||||
"userFloorsAscendedGoal": [
|
||||
"Floors Ascended Goal",
|
||||
"floors",
|
||||
"mdi:stairs",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"minHeartRate": ["Min Heart Rate", "bpm", "mdi:heart-pulse", None, True],
|
||||
"maxHeartRate": ["Max Heart Rate", "bpm", "mdi:heart-pulse", None, True],
|
||||
"restingHeartRate": ["Resting Heart Rate", "bpm", "mdi:heart-pulse", None, True],
|
||||
"minAvgHeartRate": ["Min Avg Heart Rate", "bpm", "mdi:heart-pulse", None, False],
|
||||
"maxAvgHeartRate": ["Max Avg Heart Rate", "bpm", "mdi:heart-pulse", None, False],
|
||||
"minHeartRate": ["Min Heart Rate", "bpm", "mdi:heart-pulse", None, SensorStateClass.TOTAL, True],
|
||||
"maxHeartRate": ["Max Heart Rate", "bpm", "mdi:heart-pulse", None, SensorStateClass.TOTAL, True],
|
||||
"restingHeartRate": ["Resting Heart Rate", "bpm", "mdi:heart-pulse", None, SensorStateClass.TOTAL, True],
|
||||
"minAvgHeartRate": ["Min Avg Heart Rate", "bpm", "mdi:heart-pulse", None, SensorStateClass.TOTAL, False],
|
||||
"maxAvgHeartRate": ["Max Avg Heart Rate", "bpm", "mdi:heart-pulse", None, SensorStateClass.TOTAL, False],
|
||||
"abnormalHeartRateAlertsCount": [
|
||||
"Abnormal HR Counts",
|
||||
None,
|
||||
"mdi:heart-pulse",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"lastSevenDaysAvgRestingHeartRate": [
|
||||
@@ -138,52 +155,59 @@ GARMIN_ENTITY_LIST = {
|
||||
"bpm",
|
||||
"mdi:heart-pulse",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"averageStressLevel": ["Avg Stress Level", "lvl", "mdi:flash-alert", None, True],
|
||||
"maxStressLevel": ["Max Stress Level", "lvl", "mdi:flash-alert", None, True],
|
||||
"stressQualifier": ["Stress Qualifier", None, "mdi:flash-alert", None, False],
|
||||
"stressDuration": ["Stress Duration", TIME_MINUTES, "mdi:flash-alert", None, False],
|
||||
"averageStressLevel": ["Avg Stress Level", "lvl", "mdi:flash-alert", None, SensorStateClass.TOTAL, True],
|
||||
"maxStressLevel": ["Max Stress Level", "lvl", "mdi:flash-alert", None, SensorStateClass.TOTAL, True],
|
||||
"stressQualifier": ["Stress Qualifier", None, "mdi:flash-alert", None, SensorStateClass.TOTAL, False],
|
||||
"stressDuration": ["Stress Duration", TIME_MINUTES, "mdi:flash-alert", None, SensorStateClass.TOTAL, False],
|
||||
"restStressDuration": [
|
||||
"Rest Stress Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorDeviceClass.DURATION,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"activityStressDuration": [
|
||||
"Activity Stress Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorDeviceClass.DURATION,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"uncategorizedStressDuration": [
|
||||
"Uncat. Stress Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorDeviceClass.DURATION,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"totalStressDuration": [
|
||||
"Total Stress Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorDeviceClass.DURATION,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"lowStressDuration": [
|
||||
"Low Stress Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorDeviceClass.DURATION,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"mediumStressDuration": [
|
||||
"Medium Stress Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorDeviceClass.DURATION,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"highStressDuration": [
|
||||
@@ -191,6 +215,7 @@ GARMIN_ENTITY_LIST = {
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"stressPercentage": [
|
||||
@@ -198,6 +223,7 @@ GARMIN_ENTITY_LIST = {
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"restStressPercentage": [
|
||||
@@ -205,6 +231,7 @@ GARMIN_ENTITY_LIST = {
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"activityStressPercentage": [
|
||||
@@ -212,6 +239,7 @@ GARMIN_ENTITY_LIST = {
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"uncategorizedStressPercentage": [
|
||||
@@ -219,6 +247,7 @@ GARMIN_ENTITY_LIST = {
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"lowStressPercentage": [
|
||||
@@ -226,6 +255,7 @@ GARMIN_ENTITY_LIST = {
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"mediumStressPercentage": [
|
||||
@@ -233,6 +263,7 @@ GARMIN_ENTITY_LIST = {
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"highStressPercentage": [
|
||||
@@ -240,20 +271,23 @@ GARMIN_ENTITY_LIST = {
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"moderateIntensityMinutes": [
|
||||
"Moderate Intensity",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
SensorDeviceClass.DURATION,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"vigorousIntensityMinutes": [
|
||||
"Vigorous Intensity",
|
||||
TIME_MINUTES,
|
||||
"mdi:run-fast",
|
||||
None,
|
||||
SensorDeviceClass.DURATION,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"intensityMinutesGoal": [
|
||||
@@ -261,6 +295,7 @@ GARMIN_ENTITY_LIST = {
|
||||
TIME_MINUTES,
|
||||
"mdi:run-fast",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"bodyBatteryChargedValue": [
|
||||
@@ -268,6 +303,7 @@ GARMIN_ENTITY_LIST = {
|
||||
PERCENTAGE,
|
||||
"mdi:battery-charging-100",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"bodyBatteryDrainedValue": [
|
||||
@@ -275,6 +311,7 @@ GARMIN_ENTITY_LIST = {
|
||||
PERCENTAGE,
|
||||
"mdi:battery-alert-variant-outline",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"bodyBatteryHighestValue": [
|
||||
@@ -282,6 +319,7 @@ GARMIN_ENTITY_LIST = {
|
||||
PERCENTAGE,
|
||||
"mdi:battery-heart",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"bodyBatteryLowestValue": [
|
||||
@@ -289,6 +327,7 @@ GARMIN_ENTITY_LIST = {
|
||||
PERCENTAGE,
|
||||
"mdi:battery-heart-outline",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"bodyBatteryMostRecentValue": [
|
||||
@@ -296,16 +335,18 @@ GARMIN_ENTITY_LIST = {
|
||||
PERCENTAGE,
|
||||
"mdi:battery-positive",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
True,
|
||||
],
|
||||
"averageSpo2": ["Average SPO2", PERCENTAGE, "mdi:diabetes", None, True],
|
||||
"lowestSpo2": ["Lowest SPO2", PERCENTAGE, "mdi:diabetes", None, True],
|
||||
"latestSpo2": ["Latest SPO2", PERCENTAGE, "mdi:diabetes", None, True],
|
||||
"averageSpo2": ["Average SPO2", PERCENTAGE, "mdi:diabetes", None, SensorStateClass.TOTAL, True],
|
||||
"lowestSpo2": ["Lowest SPO2", PERCENTAGE, "mdi:diabetes", None, SensorStateClass.TOTAL, True],
|
||||
"latestSpo2": ["Latest SPO2", PERCENTAGE, "mdi:diabetes", None, SensorStateClass.TOTAL, True],
|
||||
"latestSpo2ReadingTimeLocal": [
|
||||
"Latest SPO2 Time",
|
||||
None,
|
||||
"mdi:diabetes",
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
SensorDeviceClass.TIMESTAMP,
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"averageMonitoringEnvironmentAltitude": [
|
||||
@@ -313,6 +354,7 @@ GARMIN_ENTITY_LIST = {
|
||||
PERCENTAGE,
|
||||
"mdi:image-filter-hdr",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"highestRespirationValue": [
|
||||
@@ -320,6 +362,7 @@ GARMIN_ENTITY_LIST = {
|
||||
"brpm",
|
||||
"mdi:progress-clock",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"lowestRespirationValue": [
|
||||
@@ -327,6 +370,7 @@ GARMIN_ENTITY_LIST = {
|
||||
"brpm",
|
||||
"mdi:progress-clock",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"latestRespirationValue": [
|
||||
@@ -334,23 +378,25 @@ GARMIN_ENTITY_LIST = {
|
||||
"brpm",
|
||||
"mdi:progress-clock",
|
||||
None,
|
||||
SensorStateClass.TOTAL,
|
||||
False,
|
||||
],
|
||||
"latestRespirationTimeGMT": [
|
||||
"Latest Respiration Update",
|
||||
None,
|
||||
"mdi:progress-clock",
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
SensorDeviceClass.TIMESTAMP,
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"weight": ["Weight", MASS_KILOGRAMS, "mdi:weight-kilogram", None, False],
|
||||
"bmi": ["BMI", "bmi", "mdi:food", None, False],
|
||||
"bodyFat": ["Body Fat", PERCENTAGE, "mdi:food", None, False],
|
||||
"bodyWater": ["Body Water", PERCENTAGE, "mdi:water-percent", None, False],
|
||||
"boneMass": ["Bone Mass", MASS_KILOGRAMS, "mdi:bone", None, False],
|
||||
"muscleMass": ["Muscle Mass", MASS_KILOGRAMS, "mdi:dumbbell", None, False],
|
||||
"physiqueRating": ["Physique Rating", None, "mdi:numeric", None, False],
|
||||
"visceralFat": ["Visceral Fat", PERCENTAGE, "mdi:food", None, False],
|
||||
"metabolicAge": ["Metabolic Age", TIME_YEARS, "mdi:calendar-heart", None, False],
|
||||
"nextAlarm": ["Next Alarm Time", None, "mdi:alarm", DEVICE_CLASS_TIMESTAMP, True],
|
||||
"weight": ["Weight", MASS_KILOGRAMS, "mdi:weight-kilogram", SensorDeviceClass.WEIGHT, SensorStateClass.TOTAL, False],
|
||||
"bmi": ["BMI", "bmi", "mdi:food", None, SensorStateClass.TOTAL, False],
|
||||
"bodyFat": ["Body Fat", PERCENTAGE, "mdi:food", None, SensorStateClass.TOTAL, False],
|
||||
"bodyWater": ["Body Water", PERCENTAGE, "mdi:water-percent", None, SensorStateClass.TOTAL, False],
|
||||
"boneMass": ["Bone Mass", MASS_KILOGRAMS, "mdi:bone", SensorDeviceClass.WEIGHT, SensorStateClass.TOTAL, False],
|
||||
"muscleMass": ["Muscle Mass", MASS_KILOGRAMS, "mdi:dumbbell", SensorDeviceClass.WEIGHT, SensorStateClass.TOTAL, False],
|
||||
"physiqueRating": ["Physique Rating", None, "mdi:numeric", None, SensorStateClass.TOTAL, False],
|
||||
"visceralFat": ["Visceral Fat", PERCENTAGE, "mdi:food", None, SensorStateClass.TOTAL, False],
|
||||
"metabolicAge": ["Metabolic Age", TIME_YEARS, "mdi:calendar-heart", None, SensorStateClass.TOTAL, False],
|
||||
"nextAlarm": ["Next Alarm Time", None, "mdi:alarm", SensorDeviceClass.TIMESTAMP, None, True],
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
"name": "Garmin Connect",
|
||||
"documentation": "https://github.com/cyberjunky/home-assistant-garmin_connect",
|
||||
"issue_tracker": "https://github.com/cyberjunky/home-assistant-garmin_connect/issues",
|
||||
"requirements": ["garminconnect==0.1.24"],
|
||||
"requirements": ["garminconnect==0.1.50"],
|
||||
"codeowners": ["@cyberjunky"],
|
||||
"config_flow": true,
|
||||
"iot_class": "cloud_polling",
|
||||
"version": "0.1.8"
|
||||
"version": "0.2.9"
|
||||
}
|
||||
|
||||
@@ -2,10 +2,16 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import datetime
|
||||
import pytz
|
||||
from tzlocal import get_localzone
|
||||
|
||||
from homeassistant.components.sensor import SensorEntity, SensorStateClass
|
||||
from homeassistant.components.sensor import (
|
||||
SensorEntity,
|
||||
SensorDeviceClass,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import ATTR_ATTRIBUTION, CONF_ID, DEVICE_CLASS_TIMESTAMP
|
||||
from homeassistant.const import ATTR_ATTRIBUTION, CONF_ID
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.helpers.update_coordinator import (
|
||||
@@ -35,16 +41,17 @@ async def async_setup_entry(
|
||||
entities = []
|
||||
for (
|
||||
sensor_type,
|
||||
(name, unit, icon, device_class, enabled_by_default),
|
||||
(name, unit, icon, device_class, state_class, enabled_by_default),
|
||||
) in GARMIN_ENTITY_LIST.items():
|
||||
|
||||
_LOGGER.debug(
|
||||
"Registering entity: %s, %s, %s, %s, %s, %s",
|
||||
"Registering entity: %s, %s, %s, %s, %s, %s, %s",
|
||||
sensor_type,
|
||||
name,
|
||||
unit,
|
||||
icon,
|
||||
device_class,
|
||||
state_class,
|
||||
enabled_by_default,
|
||||
)
|
||||
entities.append(
|
||||
@@ -56,6 +63,7 @@ async def async_setup_entry(
|
||||
unit,
|
||||
icon,
|
||||
device_class,
|
||||
state_class,
|
||||
enabled_by_default,
|
||||
)
|
||||
)
|
||||
@@ -75,6 +83,7 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
|
||||
unit,
|
||||
icon,
|
||||
device_class,
|
||||
state_class,
|
||||
enabled_default: bool = True,
|
||||
):
|
||||
"""Initialize a Garmin Connect sensor."""
|
||||
@@ -83,14 +92,15 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
|
||||
self._unique_id = unique_id
|
||||
self._type = sensor_type
|
||||
self._device_class = device_class
|
||||
self._state_class = state_class
|
||||
self._enabled_default = enabled_default
|
||||
|
||||
self._attr_name = name
|
||||
self._attr_device_class = self._device_class
|
||||
self._attr_icon = icon
|
||||
self._attr_unit_of_measurement = unit
|
||||
self._attr_native_unit_of_measurement = unit
|
||||
self._attr_unique_id = f"{self._unique_id}_{self._type}"
|
||||
self._attr_state_class = SensorStateClass.TOTAL
|
||||
self._attr_state_class = state_class
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
@@ -108,12 +118,22 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
|
||||
self.coordinator.data[self._type]
|
||||
)
|
||||
if active_alarms:
|
||||
value = active_alarms[0]
|
||||
date_time_obj = datetime.datetime.strptime(active_alarms[0], "%Y-%m-%dT%H:%M:%S")
|
||||
tz = get_localzone()
|
||||
timezone = pytz.timezone(tz.zone)
|
||||
timezone_date_time_obj = timezone.localize(date_time_obj)
|
||||
return timezone_date_time_obj
|
||||
else:
|
||||
value = None
|
||||
return None
|
||||
elif self._type == "stressQualifier":
|
||||
return value
|
||||
|
||||
if self._device_class == DEVICE_CLASS_TIMESTAMP:
|
||||
return value
|
||||
if self._device_class == SensorDeviceClass.TIMESTAMP:
|
||||
date_time_obj = datetime.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")
|
||||
tz = get_localzone()
|
||||
timezone = pytz.timezone(tz.zone)
|
||||
timezone_date_time_obj = timezone.localize(date_time_obj)
|
||||
return timezone_date_time_obj
|
||||
|
||||
return round(value, 2)
|
||||
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
"password": "[%key:common::config_flow::data::password%]",
|
||||
"username": "[%key:common::config_flow::data::username%]"
|
||||
},
|
||||
"description": "Enter your credentials.",
|
||||
"title": "Garmin Connect"
|
||||
"description": "Enter your credentials."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
"password": "Password",
|
||||
"username": "Username"
|
||||
},
|
||||
"description": "Enter your credentials.",
|
||||
"title": "Garmin Connect"
|
||||
"description": "Enter your credentials."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user