mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 09:17:53 +00:00
Remove garmin_connect integration (#52808)
Co-authored-by: Franck Nijhof <git@frenck.dev>
This commit is contained in:
parent
e04b2c2e35
commit
3488053648
@ -361,10 +361,6 @@ omit =
|
||||
homeassistant/components/garages_amsterdam/__init__.py
|
||||
homeassistant/components/garages_amsterdam/binary_sensor.py
|
||||
homeassistant/components/garages_amsterdam/sensor.py
|
||||
homeassistant/components/garmin_connect/__init__.py
|
||||
homeassistant/components/garmin_connect/const.py
|
||||
homeassistant/components/garmin_connect/sensor.py
|
||||
homeassistant/components/garmin_connect/alarm_util.py
|
||||
homeassistant/components/gc100/*
|
||||
homeassistant/components/geniushub/*
|
||||
homeassistant/components/generic_hygrostat/*
|
||||
|
@ -179,7 +179,6 @@ homeassistant/components/fritzbox/* @mib1185
|
||||
homeassistant/components/fronius/* @nielstron
|
||||
homeassistant/components/frontend/* @home-assistant/frontend
|
||||
homeassistant/components/garages_amsterdam/* @klaasnicolaas
|
||||
homeassistant/components/garmin_connect/* @cyberjunky
|
||||
homeassistant/components/gdacs/* @exxamalte
|
||||
homeassistant/components/generic_hygrostat/* @Shulyaka
|
||||
homeassistant/components/geniushub/* @zxdavb
|
||||
|
@ -1,107 +0,0 @@
|
||||
"""The Garmin Connect integration."""
|
||||
from datetime import date
|
||||
import logging
|
||||
|
||||
from garminconnect_ha import (
|
||||
Garmin,
|
||||
GarminConnectAuthenticationError,
|
||||
GarminConnectConnectionError,
|
||||
GarminConnectTooManyRequestsError,
|
||||
)
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.util import Throttle
|
||||
|
||||
from .const import DEFAULT_UPDATE_INTERVAL, DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PLATFORMS = ["sensor"]
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up Garmin Connect from a config entry."""
|
||||
|
||||
username: str = entry.data[CONF_USERNAME]
|
||||
password: str = entry.data[CONF_PASSWORD]
|
||||
|
||||
api = Garmin(username, password)
|
||||
|
||||
try:
|
||||
await hass.async_add_executor_job(api.login)
|
||||
except (
|
||||
GarminConnectAuthenticationError,
|
||||
GarminConnectTooManyRequestsError,
|
||||
) as err:
|
||||
_LOGGER.error("Error occurred during Garmin Connect login request: %s", err)
|
||||
return False
|
||||
except (GarminConnectConnectionError) as err:
|
||||
_LOGGER.error(
|
||||
"Connection error occurred during Garmin Connect login request: %s", err
|
||||
)
|
||||
raise ConfigEntryNotReady from err
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unknown error occurred during Garmin Connect login request")
|
||||
return False
|
||||
|
||||
garmin_data = GarminConnectData(hass, api)
|
||||
hass.data.setdefault(DOMAIN, {})
|
||||
hass.data[DOMAIN][entry.entry_id] = garmin_data
|
||||
|
||||
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||
"""Unload a config entry."""
|
||||
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
if unload_ok:
|
||||
hass.data[DOMAIN].pop(entry.entry_id)
|
||||
return unload_ok
|
||||
|
||||
|
||||
class GarminConnectData:
|
||||
"""Define an object to hold sensor data."""
|
||||
|
||||
def __init__(self, hass, client):
|
||||
"""Initialize."""
|
||||
self.hass = hass
|
||||
self.client = client
|
||||
self.data = None
|
||||
|
||||
@Throttle(DEFAULT_UPDATE_INTERVAL)
|
||||
async def async_update(self):
|
||||
"""Update data via API wrapper."""
|
||||
today = date.today()
|
||||
|
||||
try:
|
||||
summary = await self.hass.async_add_executor_job(
|
||||
self.client.get_user_summary, today.isoformat()
|
||||
)
|
||||
body = await self.hass.async_add_executor_job(
|
||||
self.client.get_body_composition, today.isoformat()
|
||||
)
|
||||
|
||||
self.data = {
|
||||
**summary,
|
||||
**body["totalAverage"],
|
||||
}
|
||||
self.data["nextAlarm"] = await self.hass.async_add_executor_job(
|
||||
self.client.get_device_alarms
|
||||
)
|
||||
except (
|
||||
GarminConnectAuthenticationError,
|
||||
GarminConnectTooManyRequestsError,
|
||||
GarminConnectConnectionError,
|
||||
) as err:
|
||||
_LOGGER.error(
|
||||
"Error occurred during Garmin Connect update requests: %s", err
|
||||
)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception(
|
||||
"Unknown error occurred during Garmin Connect update requests"
|
||||
)
|
@ -1,50 +0,0 @@
|
||||
"""Utility method for converting Garmin Connect alarms to python datetime."""
|
||||
from datetime import date, datetime, timedelta
|
||||
import logging
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DAY_TO_NUMBER = {
|
||||
"Mo": 1,
|
||||
"M": 1,
|
||||
"Tu": 2,
|
||||
"We": 3,
|
||||
"W": 3,
|
||||
"Th": 4,
|
||||
"Fr": 5,
|
||||
"F": 5,
|
||||
"Sa": 6,
|
||||
"Su": 7,
|
||||
}
|
||||
|
||||
|
||||
def calculate_next_active_alarms(alarms):
|
||||
"""
|
||||
Calculate garmin next active alarms from settings.
|
||||
|
||||
Alarms are sorted by time
|
||||
"""
|
||||
active_alarms = []
|
||||
_LOGGER.debug(alarms)
|
||||
|
||||
for alarm_setting in alarms:
|
||||
if alarm_setting["alarmMode"] != "ON":
|
||||
continue
|
||||
for day in alarm_setting["alarmDays"]:
|
||||
alarm_time = alarm_setting["alarmTime"]
|
||||
if day == "ONCE":
|
||||
midnight = datetime.combine(date.today(), datetime.min.time())
|
||||
alarm = midnight + timedelta(minutes=alarm_time)
|
||||
if alarm < datetime.now():
|
||||
alarm += timedelta(days=1)
|
||||
else:
|
||||
start_of_week = datetime.combine(
|
||||
date.today() - timedelta(days=datetime.today().isoweekday() % 7),
|
||||
datetime.min.time(),
|
||||
)
|
||||
days_to_add = DAY_TO_NUMBER[day] % 7
|
||||
alarm = start_of_week + timedelta(minutes=alarm_time, days=days_to_add)
|
||||
if alarm < datetime.now():
|
||||
alarm += timedelta(days=7)
|
||||
active_alarms.append(alarm.isoformat())
|
||||
return sorted(active_alarms) if active_alarms else None
|
@ -1,72 +0,0 @@
|
||||
"""Config flow for Garmin Connect integration."""
|
||||
import logging
|
||||
|
||||
from garminconnect_ha import (
|
||||
Garmin,
|
||||
GarminConnectAuthenticationError,
|
||||
GarminConnectConnectionError,
|
||||
GarminConnectTooManyRequestsError,
|
||||
)
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.const import CONF_ID, CONF_PASSWORD, CONF_USERNAME
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GarminConnectConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for Garmin Connect."""
|
||||
|
||||
VERSION = 1
|
||||
|
||||
async def _show_setup_form(self, errors=None):
|
||||
"""Show the setup form to the user."""
|
||||
return self.async_show_form(
|
||||
step_id="user",
|
||||
data_schema=vol.Schema(
|
||||
{vol.Required(CONF_USERNAME): str, vol.Required(CONF_PASSWORD): str}
|
||||
),
|
||||
errors=errors or {},
|
||||
)
|
||||
|
||||
async def async_step_user(self, user_input=None):
|
||||
"""Handle the initial step."""
|
||||
if user_input is None:
|
||||
return await self._show_setup_form()
|
||||
|
||||
username = user_input[CONF_USERNAME]
|
||||
password = user_input[CONF_PASSWORD]
|
||||
|
||||
api = Garmin(username, password)
|
||||
|
||||
errors = {}
|
||||
try:
|
||||
await self.hass.async_add_executor_job(api.login)
|
||||
except GarminConnectConnectionError:
|
||||
errors["base"] = "cannot_connect"
|
||||
return await self._show_setup_form(errors)
|
||||
except GarminConnectAuthenticationError:
|
||||
errors["base"] = "invalid_auth"
|
||||
return await self._show_setup_form(errors)
|
||||
except GarminConnectTooManyRequestsError:
|
||||
errors["base"] = "too_many_requests"
|
||||
return await self._show_setup_form(errors)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unexpected exception")
|
||||
errors["base"] = "unknown"
|
||||
return await self._show_setup_form(errors)
|
||||
|
||||
await self.async_set_unique_id(username)
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
return self.async_create_entry(
|
||||
title=username,
|
||||
data={
|
||||
CONF_ID: username,
|
||||
CONF_USERNAME: username,
|
||||
CONF_PASSWORD: password,
|
||||
},
|
||||
)
|
@ -1,355 +0,0 @@
|
||||
"""Constants for the Garmin Connect integration."""
|
||||
from datetime import timedelta
|
||||
|
||||
from homeassistant.const import (
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
LENGTH_METERS,
|
||||
MASS_KILOGRAMS,
|
||||
PERCENTAGE,
|
||||
TIME_MINUTES,
|
||||
)
|
||||
|
||||
DOMAIN = "garmin_connect"
|
||||
ATTRIBUTION = "connect.garmin.com"
|
||||
DEFAULT_UPDATE_INTERVAL = timedelta(minutes=10)
|
||||
|
||||
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],
|
||||
"remainingKilocalories": [
|
||||
"Remaining KiloCalories",
|
||||
"kcal",
|
||||
"mdi:food",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"netRemainingKilocalories": [
|
||||
"Net Remaining KiloCalories",
|
||||
"kcal",
|
||||
"mdi:food",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"netCalorieGoal": ["Net Calorie Goal", "cal", "mdi:food", None, False],
|
||||
"totalDistanceMeters": [
|
||||
"Total Distance Mtr",
|
||||
LENGTH_METERS,
|
||||
"mdi:walk",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"wellnessStartTimeLocal": [
|
||||
"Wellness Start Time",
|
||||
None,
|
||||
"mdi:clock",
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
False,
|
||||
],
|
||||
"wellnessEndTimeLocal": [
|
||||
"Wellness End Time",
|
||||
None,
|
||||
"mdi:clock",
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
False,
|
||||
],
|
||||
"wellnessDescription": ["Wellness Description", "", "mdi:clock", None, False],
|
||||
"wellnessDistanceMeters": [
|
||||
"Wellness Distance Mtr",
|
||||
LENGTH_METERS,
|
||||
"mdi:walk",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"wellnessActiveKilocalories": [
|
||||
"Wellness Active KiloCalories",
|
||||
"kcal",
|
||||
"mdi:food",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"wellnessKilocalories": ["Wellness KiloCalories", "kcal", "mdi:food", None, False],
|
||||
"highlyActiveSeconds": [
|
||||
"Highly Active Time",
|
||||
TIME_MINUTES,
|
||||
"mdi:fire",
|
||||
None,
|
||||
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],
|
||||
"measurableAwakeDuration": [
|
||||
"Awake Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:sleep",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"measurableAsleepDuration": [
|
||||
"Sleep Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:sleep",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"floorsAscendedInMeters": [
|
||||
"Floors Ascended Mtr",
|
||||
LENGTH_METERS,
|
||||
"mdi:stairs",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"floorsDescendedInMeters": [
|
||||
"Floors Descended Mtr",
|
||||
LENGTH_METERS,
|
||||
"mdi:stairs",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"floorsAscended": ["Floors Ascended", "floors", "mdi:stairs", None, True],
|
||||
"floorsDescended": ["Floors Descended", "floors", "mdi:stairs", None, True],
|
||||
"userFloorsAscendedGoal": [
|
||||
"Floors Ascended Goal",
|
||||
"floors",
|
||||
"mdi:stairs",
|
||||
None,
|
||||
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],
|
||||
"abnormalHeartRateAlertsCount": [
|
||||
"Abnormal HR Counts",
|
||||
"",
|
||||
"mdi:heart-pulse",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"lastSevenDaysAvgRestingHeartRate": [
|
||||
"Last 7 Days Avg Heart Rate",
|
||||
"bpm",
|
||||
"mdi:heart-pulse",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"averageStressLevel": ["Avg Stress Level", "", "mdi:flash-alert", None, True],
|
||||
"maxStressLevel": ["Max Stress Level", "", "mdi:flash-alert", None, True],
|
||||
"stressQualifier": ["Stress Qualifier", "", "mdi:flash-alert", None, False],
|
||||
"stressDuration": ["Stress Duration", TIME_MINUTES, "mdi:flash-alert", None, False],
|
||||
"restStressDuration": [
|
||||
"Rest Stress Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"activityStressDuration": [
|
||||
"Activity Stress Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"uncategorizedStressDuration": [
|
||||
"Uncat. Stress Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"totalStressDuration": [
|
||||
"Total Stress Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"lowStressDuration": [
|
||||
"Low Stress Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"mediumStressDuration": [
|
||||
"Medium Stress Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"highStressDuration": [
|
||||
"High Stress Duration",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"stressPercentage": [
|
||||
"Stress Percentage",
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"restStressPercentage": [
|
||||
"Rest Stress Percentage",
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"activityStressPercentage": [
|
||||
"Activity Stress Percentage",
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"uncategorizedStressPercentage": [
|
||||
"Uncat. Stress Percentage",
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"lowStressPercentage": [
|
||||
"Low Stress Percentage",
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"mediumStressPercentage": [
|
||||
"Medium Stress Percentage",
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"highStressPercentage": [
|
||||
"High Stress Percentage",
|
||||
PERCENTAGE,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"moderateIntensityMinutes": [
|
||||
"Moderate Intensity",
|
||||
TIME_MINUTES,
|
||||
"mdi:flash-alert",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"vigorousIntensityMinutes": [
|
||||
"Vigorous Intensity",
|
||||
TIME_MINUTES,
|
||||
"mdi:run-fast",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"intensityMinutesGoal": [
|
||||
"Intensity Goal",
|
||||
TIME_MINUTES,
|
||||
"mdi:run-fast",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"bodyBatteryChargedValue": [
|
||||
"Body Battery Charged",
|
||||
PERCENTAGE,
|
||||
"mdi:battery-charging-100",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"bodyBatteryDrainedValue": [
|
||||
"Body Battery Drained",
|
||||
PERCENTAGE,
|
||||
"mdi:battery-alert-variant-outline",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"bodyBatteryHighestValue": [
|
||||
"Body Battery Highest",
|
||||
PERCENTAGE,
|
||||
"mdi:battery-heart",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"bodyBatteryLowestValue": [
|
||||
"Body Battery Lowest",
|
||||
PERCENTAGE,
|
||||
"mdi:battery-heart-outline",
|
||||
None,
|
||||
True,
|
||||
],
|
||||
"bodyBatteryMostRecentValue": [
|
||||
"Body Battery Most Recent",
|
||||
PERCENTAGE,
|
||||
"mdi:battery-positive",
|
||||
None,
|
||||
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],
|
||||
"latestSpo2ReadingTimeLocal": [
|
||||
"Latest SPO2 Time",
|
||||
None,
|
||||
"mdi:diabetes",
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
False,
|
||||
],
|
||||
"averageMonitoringEnvironmentAltitude": [
|
||||
"Average Altitude",
|
||||
PERCENTAGE,
|
||||
"mdi:image-filter-hdr",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"highestRespirationValue": [
|
||||
"Highest Respiration",
|
||||
"brpm",
|
||||
"mdi:progress-clock",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"lowestRespirationValue": [
|
||||
"Lowest Respiration",
|
||||
"brpm",
|
||||
"mdi:progress-clock",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"latestRespirationValue": [
|
||||
"Latest Respiration",
|
||||
"brpm",
|
||||
"mdi:progress-clock",
|
||||
None,
|
||||
False,
|
||||
],
|
||||
"latestRespirationTimeGMT": [
|
||||
"Latest Respiration Update",
|
||||
None,
|
||||
"mdi:progress-clock",
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
False,
|
||||
],
|
||||
"weight": ["Weight", MASS_KILOGRAMS, "mdi:weight-kilogram", None, False],
|
||||
"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],
|
||||
"physiqueRating": ["Physique Rating", "", "mdi:numeric", None, False],
|
||||
"visceralFat": ["Visceral Fat", "", "mdi:food", None, False],
|
||||
"metabolicAge": ["Metabolic Age", "", "mdi:calendar-heart", None, False],
|
||||
"nextAlarm": ["Next Alarm Time", None, "mdi:alarm", DEVICE_CLASS_TIMESTAMP, True],
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"domain": "garmin_connect",
|
||||
"name": "Garmin Connect",
|
||||
"documentation": "https://www.home-assistant.io/integrations/garmin_connect",
|
||||
"requirements": ["garminconnect_ha==0.1.6"],
|
||||
"codeowners": ["@cyberjunky"],
|
||||
"config_flow": true,
|
||||
"iot_class": "cloud_polling"
|
||||
}
|
@ -1,199 +0,0 @@
|
||||
"""Platform for Garmin Connect integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from garminconnect_ha import (
|
||||
GarminConnectAuthenticationError,
|
||||
GarminConnectConnectionError,
|
||||
GarminConnectTooManyRequestsError,
|
||||
)
|
||||
|
||||
from homeassistant.components.sensor import SensorEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import ATTR_ATTRIBUTION, CONF_ID
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
|
||||
from .alarm_util import calculate_next_active_alarms
|
||||
from .const import ATTRIBUTION, DOMAIN, GARMIN_ENTITY_LIST
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities
|
||||
) -> None:
|
||||
"""Set up Garmin Connect sensor based on a config entry."""
|
||||
garmin_data = hass.data[DOMAIN][entry.entry_id]
|
||||
unique_id = entry.data[CONF_ID]
|
||||
|
||||
try:
|
||||
await garmin_data.async_update()
|
||||
except (
|
||||
GarminConnectConnectionError,
|
||||
GarminConnectAuthenticationError,
|
||||
GarminConnectTooManyRequestsError,
|
||||
) as err:
|
||||
_LOGGER.error("Error occurred during Garmin Connect Client update: %s", err)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unknown error occurred during Garmin Connect Client update")
|
||||
|
||||
entities = []
|
||||
for (
|
||||
sensor_type,
|
||||
(name, unit, icon, device_class, enabled_by_default),
|
||||
) in GARMIN_ENTITY_LIST.items():
|
||||
|
||||
_LOGGER.debug(
|
||||
"Registering entity: %s, %s, %s, %s, %s, %s",
|
||||
sensor_type,
|
||||
name,
|
||||
unit,
|
||||
icon,
|
||||
device_class,
|
||||
enabled_by_default,
|
||||
)
|
||||
entities.append(
|
||||
GarminConnectSensor(
|
||||
garmin_data,
|
||||
unique_id,
|
||||
sensor_type,
|
||||
name,
|
||||
unit,
|
||||
icon,
|
||||
device_class,
|
||||
enabled_by_default,
|
||||
)
|
||||
)
|
||||
|
||||
async_add_entities(entities, True)
|
||||
|
||||
|
||||
class GarminConnectSensor(SensorEntity):
|
||||
"""Representation of a Garmin Connect Sensor."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
data,
|
||||
unique_id,
|
||||
sensor_type,
|
||||
name,
|
||||
unit,
|
||||
icon,
|
||||
device_class,
|
||||
enabled_default: bool = True,
|
||||
):
|
||||
"""Initialize."""
|
||||
self._data = data
|
||||
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
|
||||
self._available = True
|
||||
self._state = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon to use in the frontend."""
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
@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."""
|
||||
if not self._data.data:
|
||||
return {}
|
||||
attributes = {
|
||||
"source": self._data.data["source"],
|
||||
"last_synced": self._data.data["lastSyncTimestampGMT"],
|
||||
ATTR_ATTRIBUTION: ATTRIBUTION,
|
||||
}
|
||||
if self._type == "nextAlarm":
|
||||
attributes["next_alarms"] = calculate_next_active_alarms(
|
||||
self._data.data[self._type]
|
||||
)
|
||||
return attributes
|
||||
|
||||
@property
|
||||
def device_info(self) -> DeviceInfo:
|
||||
"""Return device information."""
|
||||
return {
|
||||
"identifiers": {(DOMAIN, self._unique_id)},
|
||||
"name": "Garmin Connect",
|
||||
"manufacturer": "Garmin Connect",
|
||||
}
|
||||
|
||||
@property
|
||||
def entity_registry_enabled_default(self) -> bool:
|
||||
"""Return if the entity should be enabled when first added to the entity registry."""
|
||||
return self._enabled_default
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return True if entity is available."""
|
||||
return self._available
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the device class of the sensor."""
|
||||
return self._device_class
|
||||
|
||||
async def async_update(self):
|
||||
"""Update the data from Garmin Connect."""
|
||||
if not self.enabled:
|
||||
return
|
||||
|
||||
await self._data.async_update()
|
||||
data = self._data.data
|
||||
if not data:
|
||||
_LOGGER.error("Didn't receive data from Garmin Connect")
|
||||
return
|
||||
if data.get(self._type) is None:
|
||||
_LOGGER.debug("Entity type %s not set in fetched data", self._type)
|
||||
self._available = False
|
||||
return
|
||||
self._available = True
|
||||
|
||||
if "Duration" in self._type or "Seconds" in self._type:
|
||||
self._state = data[self._type] // 60
|
||||
elif "Mass" in self._type or self._type == "weight":
|
||||
self._state = round((data[self._type] / 1000), 2)
|
||||
elif (
|
||||
self._type == "bodyFat" or self._type == "bodyWater" or self._type == "bmi"
|
||||
):
|
||||
self._state = round(data[self._type], 2)
|
||||
elif self._type == "nextAlarm":
|
||||
active_alarms = calculate_next_active_alarms(data[self._type])
|
||||
if active_alarms:
|
||||
self._state = active_alarms[0]
|
||||
else:
|
||||
self._available = False
|
||||
else:
|
||||
self._state = data[self._type]
|
||||
|
||||
_LOGGER.debug(
|
||||
"Entity %s set to state %s %s", self._type, self._state, self._unit
|
||||
)
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
|
||||
"too_many_requests": "Too many requests, retry later.",
|
||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "[%key:common::config_flow::data::password%]",
|
||||
"username": "[%key:common::config_flow::data::username%]"
|
||||
},
|
||||
"description": "Enter your credentials.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key::common::config_flow::abort::already_configured_account%]"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Ha fallat la connexi\u00f3",
|
||||
"invalid_auth": "Autenticaci\u00f3 inv\u00e0lida",
|
||||
"too_many_requests": "Massa sol\u00b7licituds, torna-ho a intentar m\u00e9s tard.",
|
||||
"unknown": "Error inesperat"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Contrasenya",
|
||||
"username": "Nom d'usuari"
|
||||
},
|
||||
"description": "Introdueix les teves credencials.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u00da\u010det je ji\u017e nastaven"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Nepoda\u0159ilo se p\u0159ipojit",
|
||||
"invalid_auth": "Neplatn\u00e9 ov\u011b\u0159en\u00ed",
|
||||
"too_many_requests": "P\u0159\u00edli\u0161 mnoho po\u017eadavk\u016f, opakujte to pozd\u011bji.",
|
||||
"unknown": "Neo\u010dek\u00e1van\u00e1 chyba"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Heslo",
|
||||
"username": "U\u017eivatelsk\u00e9 jm\u00e9no"
|
||||
},
|
||||
"description": "Zadejte sv\u00e9 p\u0159ihla\u0161ovac\u00ed \u00fadaje.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Denne konto er allerede konfigureret."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Kunne ikke oprette forbindelse - pr\u00f8v igen.",
|
||||
"invalid_auth": "Ugyldig godkendelse.",
|
||||
"too_many_requests": "For mange anmodninger - pr\u00f8v igen senere.",
|
||||
"unknown": "Uventet fejl."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Adgangskode",
|
||||
"username": "Brugernavn"
|
||||
},
|
||||
"description": "Indtast dine legitimationsoplysninger.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Konto wurde bereits konfiguriert"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Verbindung fehlgeschlagen",
|
||||
"invalid_auth": "Ung\u00fcltige Authentifizierung",
|
||||
"too_many_requests": "Zu viele Anfragen, versuche es sp\u00e4ter erneut.",
|
||||
"unknown": "Unerwarteter Fehler"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Passwort",
|
||||
"username": "Benutzername"
|
||||
},
|
||||
"description": "Gib deine Zugangsdaten ein.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Account is already configured"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Failed to connect",
|
||||
"invalid_auth": "Invalid authentication",
|
||||
"too_many_requests": "Too many requests, retry later.",
|
||||
"unknown": "Unexpected error"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Password",
|
||||
"username": "Username"
|
||||
},
|
||||
"description": "Enter your credentials.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Esta cuenta ya est\u00e1 configurada."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "No se pudo conectar, intente nuevamente.",
|
||||
"invalid_auth": "Autenticaci\u00f3n inv\u00e1lida",
|
||||
"too_many_requests": "Demasiadas solicitudes, vuelva a intentarlo m\u00e1s tarde.",
|
||||
"unknown": "Error inesperado."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Contrase\u00f1a",
|
||||
"username": "Nombre de usuario"
|
||||
},
|
||||
"description": "Ingrese sus credenciales.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "La cuenta ya ha sido configurada"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "No se pudo conectar",
|
||||
"invalid_auth": "Autenticaci\u00f3n no v\u00e1lida",
|
||||
"too_many_requests": "Demasiadas solicitudes, vuelva a intentarlo m\u00e1s tarde.",
|
||||
"unknown": "Error inesperado"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Contrase\u00f1a",
|
||||
"username": "Usuario"
|
||||
},
|
||||
"description": "Introduzca sus credenciales.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Konto on juba seadistatud"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u00dchendamine nurjus",
|
||||
"invalid_auth": "Tuvastamine nurjus",
|
||||
"too_many_requests": "Liiga palju taotlusi, proovi hiljem uuesti.",
|
||||
"unknown": "Tundmatu viga"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Salas\u00f5na",
|
||||
"username": "Kasutajanimi"
|
||||
},
|
||||
"description": "Sisesta oma mandaat.",
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Ce compte est d\u00e9j\u00e0 configur\u00e9."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Impossible de se connecter, veuillez r\u00e9essayer.",
|
||||
"invalid_auth": "Authentification non valide.",
|
||||
"too_many_requests": "Trop de demandes, r\u00e9essayez plus tard.",
|
||||
"unknown": "Erreur inattendue."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Mot de passe",
|
||||
"username": "Nom d'utilisateur"
|
||||
},
|
||||
"description": "Entrez vos informations d'identification.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u05ea\u05e6\u05d5\u05e8\u05ea \u05d4\u05d7\u05e9\u05d1\u05d5\u05df \u05db\u05d1\u05e8 \u05e0\u05e7\u05d1\u05e2\u05d4"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u05d4\u05d4\u05ea\u05d7\u05d1\u05e8\u05d5\u05ea \u05e0\u05db\u05e9\u05dc\u05d4",
|
||||
"invalid_auth": "\u05d0\u05d9\u05de\u05d5\u05ea \u05dc\u05d0 \u05d7\u05d5\u05e7\u05d9",
|
||||
"too_many_requests": "\u05d1\u05e7\u05e9\u05d5\u05ea \u05e8\u05d1\u05d5\u05ea \u05de\u05d3\u05d9, \u05e0\u05d0 \u05dc\u05e0\u05e1\u05d5\u05ea \u05e9\u05e0\u05d9\u05ea \u05de\u05d0\u05d5\u05d7\u05e8 \u05d9\u05d5\u05ea\u05e8.",
|
||||
"unknown": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05dc\u05ea\u05d9 \u05e6\u05e4\u05d5\u05d9\u05d4"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "\u05e1\u05d9\u05e1\u05de\u05d4",
|
||||
"username": "\u05e9\u05dd \u05de\u05e9\u05ea\u05de\u05e9"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "A fi\u00f3k m\u00e1r konfigur\u00e1lva van"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Sikertelen csatlakoz\u00e1s",
|
||||
"invalid_auth": "\u00c9rv\u00e9nytelen hiteles\u00edt\u00e9s",
|
||||
"too_many_requests": "T\u00fal sok k\u00e9r\u00e9s, pr\u00f3b\u00e1lkozzon k\u00e9s\u0151bb \u00fajra.",
|
||||
"unknown": "V\u00e1ratlan hiba t\u00f6rt\u00e9nt"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Jelsz\u00f3",
|
||||
"username": "Felhaszn\u00e1l\u00f3n\u00e9v"
|
||||
},
|
||||
"description": "Adja meg a hiteles\u00edt\u0151 adatait.",
|
||||
"title": "Garmin Csatlakoz\u00e1s"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Akun sudah dikonfigurasi"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Gagal terhubung",
|
||||
"invalid_auth": "Autentikasi tidak valid",
|
||||
"too_many_requests": "Terlalu banyak permintaan, coba lagi nanti.",
|
||||
"unknown": "Kesalahan yang tidak diharapkan"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Kata Sandi",
|
||||
"username": "Nama Pengguna"
|
||||
},
|
||||
"description": "Masukkan kredensial Anda.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "L'account \u00e8 gi\u00e0 configurato"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Impossibile connettersi",
|
||||
"invalid_auth": "Autenticazione non valida",
|
||||
"too_many_requests": "Troppe richieste, riprovare pi\u00f9 tardi.",
|
||||
"unknown": "Errore imprevisto"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Password",
|
||||
"username": "Nome utente"
|
||||
},
|
||||
"description": "Inserisci le tue credenziali",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\uacc4\uc815\uc774 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\uc5f0\uacb0\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4",
|
||||
"invalid_auth": "\uc778\uc99d\uc774 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4",
|
||||
"too_many_requests": "\uc694\uccad\uc774 \ub108\ubb34 \ub9ce\uc2b5\ub2c8\ub2e4. \ub098\uc911\uc5d0 \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694.",
|
||||
"unknown": "\uc608\uc0c1\uce58 \ubabb\ud55c \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "\ube44\ubc00\ubc88\ud638",
|
||||
"username": "\uc0ac\uc6a9\uc790 \uc774\ub984"
|
||||
},
|
||||
"description": "\uc790\uaca9 \uc99d\uba85\uc744 \uc785\ub825\ud574\uc8fc\uc138\uc694",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Kont ass scho konfigur\u00e9iert"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Feeler beim verbannen",
|
||||
"invalid_auth": "Ong\u00eblteg Authentifikatioun",
|
||||
"too_many_requests": "Ze vill Ufroen, prob\u00e9iert sp\u00e9ider nach emol.",
|
||||
"unknown": "Onerwaarte Feeler"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Passwuert",
|
||||
"username": "Benotzernumm"
|
||||
},
|
||||
"description": "F\u00ebllt \u00e4r Umeldungs Informatiounen aus.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Parole",
|
||||
"username": "Lietot\u0101jv\u0101rds"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Account is al geconfigureerd"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Kan geen verbinding maken",
|
||||
"invalid_auth": "Ongeldige authenticatie",
|
||||
"too_many_requests": "Te veel aanvragen, probeer het later opnieuw.",
|
||||
"unknown": "Onverwachte fout"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Wachtwoord",
|
||||
"username": "Gebruikersnaam"
|
||||
},
|
||||
"description": "Voer uw gegevens in",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Kontoen er allerede konfigurert"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Tilkobling mislyktes",
|
||||
"invalid_auth": "Ugyldig godkjenning",
|
||||
"too_many_requests": "For mange foresp\u00f8rsler, pr\u00f8v p\u00e5 nytt senere.",
|
||||
"unknown": "Uventet feil"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Passord",
|
||||
"username": "Brukernavn"
|
||||
},
|
||||
"description": "Fyll inn legitimasjonen din.",
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Konto jest ju\u017c skonfigurowane"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Nie mo\u017cna nawi\u0105za\u0107 po\u0142\u0105czenia",
|
||||
"invalid_auth": "Niepoprawne uwierzytelnienie",
|
||||
"too_many_requests": "Zbyt wiele \u017c\u0105da\u0144, spr\u00f3buj ponownie p\u00f3\u017aniej",
|
||||
"unknown": "Nieoczekiwany b\u0142\u0105d"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Has\u0142o",
|
||||
"username": "Nazwa u\u017cytkownika"
|
||||
},
|
||||
"description": "Wprowad\u017a dane uwierzytelniaj\u0105ce",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"description": "Digite suas credenciais.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Conta j\u00e1 configurada"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Falha na liga\u00e7\u00e3o",
|
||||
"invalid_auth": "Autentica\u00e7\u00e3o inv\u00e1lida",
|
||||
"unknown": "Erro inesperado"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Palavra-passe",
|
||||
"username": "Nome de Utilizador"
|
||||
},
|
||||
"description": "Introduza as suas credenciais.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u042d\u0442\u0430 \u0443\u0447\u0451\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 Home Assistant."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f.",
|
||||
"invalid_auth": "\u041e\u0448\u0438\u0431\u043a\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.",
|
||||
"too_many_requests": "\u0421\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u043f\u043e\u0437\u0436\u0435.",
|
||||
"unknown": "\u041d\u0435\u043f\u0440\u0435\u0434\u0432\u0438\u0434\u0435\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
|
||||
"username": "\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f"
|
||||
},
|
||||
"description": "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0412\u0430\u0448\u0438 \u0443\u0447\u0451\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Ta ra\u010dun je \u017ee konfiguriran."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Povezava ni uspela, poskusite znova.",
|
||||
"invalid_auth": "Neveljavna avtentikacija.",
|
||||
"too_many_requests": "Preve\u010d zahtev, poskusite pozneje.",
|
||||
"unknown": "Nepri\u010dakovana napaka."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Geslo",
|
||||
"username": "Uporabni\u0161ko ime"
|
||||
},
|
||||
"description": "Vnesite svoje poverilnice.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Det h\u00e4r kontot har redan konfigurerats."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Kunde inte ansluta, var god f\u00f6rs\u00f6k igen.",
|
||||
"invalid_auth": "Ogiltig autentisering.",
|
||||
"too_many_requests": "F\u00f6r m\u00e5nga f\u00f6rfr\u00e5gningar, f\u00f6rs\u00f6k igen senare.",
|
||||
"unknown": "Ov\u00e4ntat fel."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "L\u00f6senord",
|
||||
"username": "Anv\u00e4ndarnamn"
|
||||
},
|
||||
"description": "Ange dina anv\u00e4ndaruppgifter.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Hesap zaten yap\u0131land\u0131r\u0131lm\u0131\u015f"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Ba\u011flanma hatas\u0131",
|
||||
"invalid_auth": "Ge\u00e7ersiz kimlik do\u011frulama",
|
||||
"unknown": "Beklenmeyen hata"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Parola",
|
||||
"username": "Kullan\u0131c\u0131 Ad\u0131"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u0426\u0435\u0439 \u043e\u0431\u043b\u0456\u043a\u043e\u0432\u0438\u0439 \u0437\u0430\u043f\u0438\u0441 \u0432\u0436\u0435 \u0434\u043e\u0434\u0430\u043d\u043e \u0432 Home Assistant."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u0442\u0438\u0441\u044f",
|
||||
"invalid_auth": "\u041d\u0435\u0432\u0456\u0440\u043d\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f.",
|
||||
"too_many_requests": "\u0417\u0430\u043d\u0430\u0434\u0442\u043e \u0431\u0430\u0433\u0430\u0442\u043e \u0437\u0430\u043f\u0438\u0442\u0456\u0432, \u0441\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0449\u0435 \u0440\u0430\u0437 \u043f\u0456\u0437\u043d\u0456\u0448\u0435.",
|
||||
"unknown": "\u041d\u0435\u043e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
|
||||
"username": "\u0406\u043c'\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430"
|
||||
},
|
||||
"description": "\u0412\u0432\u0435\u0434\u0456\u0442\u044c \u0412\u0430\u0448\u0456 \u043e\u0431\u043b\u0456\u043a\u043e\u0432\u0456 \u0434\u0430\u043d\u0456.",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"username": "\u7528\u6237\u540d"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u5e33\u865f\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u9023\u7dda\u5931\u6557",
|
||||
"invalid_auth": "\u9a57\u8b49\u78bc\u7121\u6548",
|
||||
"too_many_requests": "\u8acb\u6c42\u6b21\u6578\u904e\u591a\uff0c\u8acb\u7a0d\u5f8c\u91cd\u8a66\u3002",
|
||||
"unknown": "\u672a\u9810\u671f\u932f\u8aa4"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "\u5bc6\u78bc",
|
||||
"username": "\u4f7f\u7528\u8005\u540d\u7a31"
|
||||
},
|
||||
"description": "\u8f38\u5165\u6191\u8b49\u3002",
|
||||
"title": "Garmin Connect"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -91,7 +91,6 @@ FLOWS = [
|
||||
"fritzbox",
|
||||
"fritzbox_callmonitor",
|
||||
"garages_amsterdam",
|
||||
"garmin_connect",
|
||||
"gdacs",
|
||||
"geofency",
|
||||
"geonetnz_quakes",
|
||||
|
3
mypy.ini
3
mypy.ini
@ -1310,9 +1310,6 @@ ignore_errors = true
|
||||
[mypy-homeassistant.components.freebox.*]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.garmin_connect.*]
|
||||
ignore_errors = true
|
||||
|
||||
[mypy-homeassistant.components.geniushub.*]
|
||||
ignore_errors = true
|
||||
|
||||
|
@ -654,9 +654,6 @@ gTTS==2.2.3
|
||||
# homeassistant.components.garages_amsterdam
|
||||
garages-amsterdam==2.1.1
|
||||
|
||||
# homeassistant.components.garmin_connect
|
||||
garminconnect_ha==0.1.6
|
||||
|
||||
# homeassistant.components.geniushub
|
||||
geniushub-client==0.6.30
|
||||
|
||||
|
@ -366,9 +366,6 @@ gTTS==2.2.3
|
||||
# homeassistant.components.garages_amsterdam
|
||||
garages-amsterdam==2.1.1
|
||||
|
||||
# homeassistant.components.garmin_connect
|
||||
garminconnect_ha==0.1.6
|
||||
|
||||
# homeassistant.components.geo_json_events
|
||||
# homeassistant.components.usgs_earthquakes_feed
|
||||
geojson_client==0.6
|
||||
|
@ -51,7 +51,6 @@ IGNORED_MODULES: Final[list[str]] = [
|
||||
"homeassistant.components.fortios.*",
|
||||
"homeassistant.components.foscam.*",
|
||||
"homeassistant.components.freebox.*",
|
||||
"homeassistant.components.garmin_connect.*",
|
||||
"homeassistant.components.geniushub.*",
|
||||
"homeassistant.components.glances.*",
|
||||
"homeassistant.components.google_assistant.*",
|
||||
|
@ -1 +0,0 @@
|
||||
"""Tests for the Garmin Connect component."""
|
@ -1,112 +0,0 @@
|
||||
"""Test the Garmin Connect config flow."""
|
||||
from unittest.mock import patch
|
||||
|
||||
from garminconnect_ha import (
|
||||
GarminConnectAuthenticationError,
|
||||
GarminConnectConnectionError,
|
||||
GarminConnectTooManyRequestsError,
|
||||
)
|
||||
|
||||
from homeassistant import config_entries, data_entry_flow
|
||||
from homeassistant.components.garmin_connect.const import DOMAIN
|
||||
from homeassistant.const import CONF_ID, CONF_PASSWORD, CONF_USERNAME
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
MOCK_CONF = {
|
||||
CONF_ID: "my@email.address",
|
||||
CONF_USERNAME: "my@email.address",
|
||||
CONF_PASSWORD: "mypassw0rd",
|
||||
}
|
||||
|
||||
|
||||
async def test_show_form(hass):
|
||||
"""Test that the form is served with no input."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == config_entries.SOURCE_USER
|
||||
|
||||
|
||||
async def test_step_user(hass):
|
||||
"""Test registering an integration and finishing flow works."""
|
||||
with patch(
|
||||
"homeassistant.components.garmin_connect.async_setup_entry", return_value=True
|
||||
), patch(
|
||||
"homeassistant.components.garmin_connect.config_flow.Garmin",
|
||||
) as garmin:
|
||||
garmin.return_value.login.return_value = MOCK_CONF[CONF_ID]
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_CONF
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert result["data"] == MOCK_CONF
|
||||
|
||||
|
||||
async def test_connection_error(hass):
|
||||
"""Test for connection error."""
|
||||
with patch(
|
||||
"homeassistant.components.garmin_connect.Garmin.login",
|
||||
side_effect=GarminConnectConnectionError("errormsg"),
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": "user"}, data=MOCK_CONF
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["errors"] == {"base": "cannot_connect"}
|
||||
|
||||
|
||||
async def test_authentication_error(hass):
|
||||
"""Test for authentication error."""
|
||||
with patch(
|
||||
"homeassistant.components.garmin_connect.Garmin.login",
|
||||
side_effect=GarminConnectAuthenticationError("errormsg"),
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": "user"}, data=MOCK_CONF
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["errors"] == {"base": "invalid_auth"}
|
||||
|
||||
|
||||
async def test_toomanyrequest_error(hass):
|
||||
"""Test for toomanyrequests error."""
|
||||
with patch(
|
||||
"homeassistant.components.garmin_connect.Garmin.login",
|
||||
side_effect=GarminConnectTooManyRequestsError("errormsg"),
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": "user"}, data=MOCK_CONF
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["errors"] == {"base": "too_many_requests"}
|
||||
|
||||
|
||||
async def test_unknown_error(hass):
|
||||
"""Test for unknown error."""
|
||||
with patch(
|
||||
"homeassistant.components.garmin_connect.Garmin.login",
|
||||
side_effect=Exception,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": "user"}, data=MOCK_CONF
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["errors"] == {"base": "unknown"}
|
||||
|
||||
|
||||
async def test_abort_if_already_setup(hass):
|
||||
"""Test abort if already setup."""
|
||||
with patch(
|
||||
"homeassistant.components.garmin_connect.config_flow.Garmin",
|
||||
):
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN, data=MOCK_CONF, unique_id=MOCK_CONF[CONF_ID]
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": "user"}, data=MOCK_CONF
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||
assert result["reason"] == "already_configured"
|
Loading…
x
Reference in New Issue
Block a user