Compare commits

...

35 Commits
0.1.2 ... 0.2.6

Author SHA1 Message Date
Ron
d118638429 Corrected units/device type for some body related sensors 2023-01-06 12:50:22 +01:00
Ron
3103929f5f Updated version and bumped garminconnect pkg version 2023-01-06 12:49:27 +01:00
Ron
842355d273 Added debug logging 2023-01-06 12:48:23 +01:00
Ron
e2728b6bc2 Update manifest.json 2023-01-04 20:08:21 +01:00
Ron
b75133a2d4 Fixed error with stress qualfier 2023-01-04 20:08:07 +01:00
Ron
ecbed70aee Update manifest.json 2023-01-04 19:43:06 +01:00
Ron
a761bc00a3 Update sensor.py 2023-01-04 19:42:46 +01:00
Ron
517bd5af5d Converted alarm time value to datetime 2023-01-04 19:42:20 +01:00
Ron
dc4e7301d8 Update manifest.json 2023-01-04 19:04:57 +01:00
Ron
e7ab9ef561 Update sensor.py 2023-01-04 19:04:04 +01:00
Ron
5438cd2d59 Updated version 2023-01-04 15:04:00 +01:00
Ron
4113550397 Implemented SensorDeviceClass 2023-01-04 15:03:23 +01:00
Ron
4b53fdb162 Implemented SensorDeviceClass 2023-01-04 15:02:47 +01:00
Ron Klinkien
6a1b5240d7 Update README.md 2022-05-24 21:19:04 +02:00
Ron Klinkien
5155e90c8a Corrected cal to kcal for Netto Galorie Goal 2022-05-24 20:04:55 +02:00
Ron Klinkien
1844b50877 Fixed unit of measurement legacy code 2022-05-24 20:01:16 +02:00
Ron Klinkien
0241207443 Merge pull request #37 from wrt54g/main
Update HACS URL
2022-05-03 08:38:36 +02:00
Sven
eaec42124b Update HACS URL 2022-05-03 08:08:11 +02:00
Ron Klinkien
8dea9bfa4b Return correct results 2022-04-22 11:44:40 +02:00
Ron Klinkien
f13f59ae46 Don't use timestamp for nextalarm sensor 2022-04-22 09:43:30 +02:00
Ron Klinkien
e958d2af89 Remove title of step user 2022-04-11 11:08:18 +02:00
Ron Klinkien
8beb401e41 Remove title of step user 2022-04-11 11:07:38 +02:00
Ron Klinkien
4cd2826643 Update README.md 2022-01-05 10:23:20 +01:00
Ron Klinkien
6a5a7fbd34 Added statistics to sensors
Updated sensor code to newer standard
2021-12-30 11:34:38 +01:00
Ron Klinkien
30fe26751c Update manifest.json 2021-12-29 21:55:46 +01:00
Ron Klinkien
05adddd8e5 Update config_flow.py 2021-12-29 21:54:35 +01:00
Ron Klinkien
3fd9388170 Update __init__.py 2021-12-29 21:54:16 +01:00
Ron Klinkien
dd7cfc021f Update manifest.json 2021-12-29 13:09:07 +01:00
Ron Klinkien
154190f9e9 Update hacs.json 2021-12-24 16:41:58 +01:00
Ron Klinkien
e2d3a61c0e Merge pull request #22 from obbers/main
Remvove country from hacs.json
2021-12-24 16:41:21 +01:00
Ron Klinkien
47717f019c Bumped garminconnect-ha 2021-12-24 13:38:00 +01:00
Ron Klinkien
03f576207f Bumped garminconnect-ha to 0.1.16
Renamed bodyMass to boneMass
2021-12-24 12:37:16 +01:00
Gary Sinclair
db334c0761 Merge branch 'cyberjunky:main' into main 2021-12-23 14:35:08 -06:00
Ron Klinkien
78f5266a5f Bumped garminconnect-ha to 1.0.15 2021-12-23 20:55:53 +01:00
Gary Sinclair
7ce7bd2277 Remove Country from hacs.json 2021-12-08 08:40:03 -06:00
9 changed files with 73 additions and 82 deletions

View File

@@ -1,16 +1,19 @@
[![hacs_badge](https://img.shields.io/badge/HACS-Default-orange.svg)](https://github.com/custom-components/hacs) [![made-with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org/) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/cyberjunkynl/)
[![hacs_badge](https://img.shields.io/badge/HACS-Default-orange.svg)](https://github.com/hacs/integration) [![made-with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org/) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](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.

View File

@@ -2,7 +2,7 @@
from datetime import date
import logging
from garminconnect_ha import (
from garminconnect import (
Garmin,
GarminConnectAuthenticationError,
GarminConnectConnectionError,
@@ -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,

View File

@@ -1,7 +1,7 @@
"""Config flow for Garmin Connect integration."""
import logging
from garminconnect_ha import (
from garminconnect import (
Garmin,
GarminConnectAuthenticationError,
GarminConnectConnectionError,

View File

@@ -2,16 +2,15 @@
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
DOMAIN = "garmin_connect"
ATTRIBUTION = "connect.garmin.com"
DATA_COORDINATOR = "coordinator"
DEFAULT_UPDATE_INTERVAL = timedelta(minutes=5)
@@ -37,26 +36,26 @@ GARMIN_ENTITY_LIST = {
None,
False,
],
"netCalorieGoal": ["Net Calorie Goal", "cal", "mdi:food", None, False],
"netCalorieGoal": ["Net Calorie Goal", "kcal", "mdi:food", None, False],
"totalDistanceMeters": [
"Total Distance Mtr",
LENGTH_METERS,
"mdi:walk",
None,
SensorDeviceClass.DISTANCE,
True,
],
"wellnessStartTimeLocal": [
"Wellness Start Time",
None,
"mdi:clock",
DEVICE_CLASS_TIMESTAMP,
SensorDeviceClass.TIMESTAMP,
False,
],
"wellnessEndTimeLocal": [
"Wellness End Time",
None,
"mdi:clock",
DEVICE_CLASS_TIMESTAMP,
SensorDeviceClass.TIMESTAMP,
False,
],
"wellnessDescription": ["Wellness Description", "", "mdi:clock", None, False],
@@ -64,7 +63,7 @@ GARMIN_ENTITY_LIST = {
"Wellness Distance Mtr",
LENGTH_METERS,
"mdi:walk",
None,
SensorDeviceClass.DISTANCE,
False,
],
"wellnessActiveKilocalories": [
@@ -103,14 +102,14 @@ GARMIN_ENTITY_LIST = {
"Floors Ascended Mtr",
LENGTH_METERS,
"mdi:stairs",
None,
SensorDeviceClass.DISTANCE,
False,
],
"floorsDescendedInMeters": [
"Floors Descended Mtr",
LENGTH_METERS,
"mdi:stairs",
None,
SensorDeviceClass.DISTANCE,
False,
],
"floorsAscended": ["Floors Ascended", "floors", "mdi:stairs", None, True],
@@ -198,49 +197,49 @@ GARMIN_ENTITY_LIST = {
"Stress Percentage",
PERCENTAGE,
"mdi:flash-alert",
None,
SensorDeviceClass.BATTERY,
False,
],
"restStressPercentage": [
"Rest Stress Percentage",
PERCENTAGE,
"mdi:flash-alert",
None,
SensorDeviceClass.BATTERY,
False,
],
"activityStressPercentage": [
"Activity Stress Percentage",
PERCENTAGE,
"mdi:flash-alert",
None,
SensorDeviceClass.BATTERY,
False,
],
"uncategorizedStressPercentage": [
"Uncat. Stress Percentage",
PERCENTAGE,
"mdi:flash-alert",
None,
SensorDeviceClass.BATTERY,
False,
],
"lowStressPercentage": [
"Low Stress Percentage",
PERCENTAGE,
"mdi:flash-alert",
None,
SensorDeviceClass.BATTERY,
False,
],
"mediumStressPercentage": [
"Medium Stress Percentage",
PERCENTAGE,
"mdi:flash-alert",
None,
SensorDeviceClass.BATTERY,
False,
],
"highStressPercentage": [
"High Stress Percentage",
PERCENTAGE,
"mdi:flash-alert",
None,
SensorDeviceClass.BATTERY,
False,
],
"moderateIntensityMinutes": [
@@ -268,35 +267,35 @@ GARMIN_ENTITY_LIST = {
"Body Battery Charged",
PERCENTAGE,
"mdi:battery-charging-100",
None,
SensorDeviceClass.BATTERY,
True,
],
"bodyBatteryDrainedValue": [
"Body Battery Drained",
PERCENTAGE,
"mdi:battery-alert-variant-outline",
None,
SensorDeviceClass.BATTERY,
True,
],
"bodyBatteryHighestValue": [
"Body Battery Highest",
PERCENTAGE,
"mdi:battery-heart",
None,
SensorDeviceClass.BATTERY,
True,
],
"bodyBatteryLowestValue": [
"Body Battery Lowest",
PERCENTAGE,
"mdi:battery-heart-outline",
None,
SensorDeviceClass.BATTERY,
True,
],
"bodyBatteryMostRecentValue": [
"Body Battery Most Recent",
PERCENTAGE,
"mdi:battery-positive",
None,
SensorDeviceClass.BATTERY,
True,
],
"averageSpo2": ["Average SPO2", PERCENTAGE, "mdi:diabetes", None, True],
@@ -306,7 +305,7 @@ GARMIN_ENTITY_LIST = {
"Latest SPO2 Time",
None,
"mdi:diabetes",
DEVICE_CLASS_TIMESTAMP,
SensorDeviceClass.TIMESTAMP,
False,
],
"averageMonitoringEnvironmentAltitude": [
@@ -341,17 +340,17 @@ GARMIN_ENTITY_LIST = {
"Latest Respiration Update",
None,
"mdi:progress-clock",
DEVICE_CLASS_TIMESTAMP,
SensorDeviceClass.TIMESTAMP,
False,
],
"weight": ["Weight", MASS_KILOGRAMS, "mdi:weight-kilogram", None, False],
"weight": ["Weight", MASS_KILOGRAMS, "mdi:weight-kilogram", SensorDeviceClass.WEIGHT, 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],
"bodyMass": ["Body Mass", MASS_KILOGRAMS, "mdi:food", None, False],
"muscleMass": ["Muscle Mass", MASS_KILOGRAMS, "mdi:dumbbell", None, False],
"bodyFat": ["Body Fat", PERCENTAGE, "mdi:food", SensorDeviceClass.BATTERY, False],
"bodyWater": ["Body Water", PERCENTAGE, "mdi:water-percent", SensorDeviceClass.BATTERY, False],
"boneMass": ["Bone Mass", MASS_KILOGRAMS, "mdi:bone", SensorDeviceClass.WEIGHT, False],
"muscleMass": ["Muscle Mass", MASS_KILOGRAMS, "mdi:dumbbell", SensorDeviceClass.WEIGHT, False],
"physiqueRating": ["Physique Rating", None, "mdi:numeric", None, False],
"visceralFat": ["Visceral Fat", PERCENTAGE, "mdi:food", None, False],
"visceralFat": ["Visceral Fat", PERCENTAGE, "mdi:food", SensorDeviceClass.BATTERY, False],
"metabolicAge": ["Metabolic Age", TIME_YEARS, "mdi:calendar-heart", None, False],
"nextAlarm": ["Next Alarm Time", None, "mdi:alarm", DEVICE_CLASS_TIMESTAMP, True],
"nextAlarm": ["Next Alarm Time", None, "mdi:alarm", SensorDeviceClass.TIMESTAMP, True],
}

View File

@@ -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_ha==0.1.13"],
"requirements": ["garminconnect==0.1.50"],
"codeowners": ["@cyberjunky"],
"config_flow": true,
"iot_class": "cloud_polling",
"version": "0.1.1"
"version": "0.2.6"
}

View File

@@ -2,10 +2,16 @@
from __future__ import annotations
import logging
import datetime
import pytz
from homeassistant.components.sensor import SensorEntity
from homeassistant.components.sensor import (
SensorEntity,
SensorStateClass,
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 (
@@ -15,7 +21,6 @@ from homeassistant.helpers.update_coordinator import (
from .alarm_util import calculate_next_active_alarms
from .const import (
ATTRIBUTION,
DATA_COORDINATOR,
DOMAIN as GARMIN_DOMAIN,
GARMIN_ENTITY_LIST,
@@ -83,24 +88,18 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
self._unique_id = unique_id
self._type = sensor_type
self._name = name
self._unit = unit
self._icon = icon
self._device_class = device_class
self._enabled_default = enabled_default
@property
def name(self):
"""Return the name of the sensor."""
return self._name
self._attr_name = name
self._attr_device_class = self._device_class
self._attr_icon = icon
self._attr_native_unit_of_measurement = unit
self._attr_unique_id = f"{self._unique_id}_{self._type}"
self._attr_state_class = SensorStateClass.TOTAL
@property
def icon(self):
"""Return the icon to use in the frontend."""
return self._icon
@property
def state(self):
def native_value(self):
"""Return the state of the sensor."""
if not self.coordinator.data or not self.coordinator.data[self._type]:
return None
@@ -115,25 +114,23 @@ 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")
timezone = pytz.timezone('UTC')
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")
timezone = pytz.timezone('UTC')
timezone_date_time_obj = timezone.localize(date_time_obj)
return timezone_date_time_obj
return round(value, 2)
@property
def unique_id(self) -> str:
"""Return the unique ID for this sensor."""
return f"{self._unique_id}_{self._type}"
@property
def unit_of_measurement(self):
"""Return the unit of measurement."""
return self._unit
@property
def extra_state_attributes(self):
"""Return attributes for sensor."""
@@ -141,9 +138,7 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
return {}
attributes = {
"source": self.coordinator.data["source"],
"last_synced": self.coordinator.data["lastSyncTimestampGMT"],
ATTR_ATTRIBUTION: ATTRIBUTION,
}
if self._type == "nextAlarm":
attributes["next_alarms"] = calculate_next_active_alarms(
@@ -174,8 +169,3 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
and self.coordinator.data
and self._type in self.coordinator.data
)
@property
def device_class(self):
"""Return the device class of the sensor."""
return self._device_class

View File

@@ -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."
}
}
}

View File

@@ -15,9 +15,8 @@
"password": "Password",
"username": "Username"
},
"description": "Enter your credentials.",
"title": "Garmin Connect"
"description": "Enter your credentials."
}
}
}
}
}

View File

@@ -1,7 +1,5 @@
{
"name": "Garmin Connect",
"country": "NL",
"render_readme": true,
"domains": ["sensor"]
}
}