mirror of
https://github.com/cyberjunky/home-assistant-garmin_connect.git
synced 2026-01-07 20:13:57 -05:00
Merge pull request #312 from cyberjunky/coderabbitai/docstrings/u59f
📝 Add docstrings to `mfa`
This commit is contained in:
@@ -62,9 +62,9 @@ class GarminConnectDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
|
||||
def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None:
|
||||
"""
|
||||
Initializes the Garmin Connect data update coordinator.
|
||||
|
||||
Sets up the integration's API client, determines if the user is in China, configures the time zone, and establishes the update interval for data synchronization.
|
||||
Initialize the Garmin Connect data update coordinator for Home Assistant.
|
||||
|
||||
Configures the Garmin API client, determines if the user is located in China, sets the time zone, and establishes the data update interval for the integration.
|
||||
"""
|
||||
self.entry = entry
|
||||
self.hass = hass
|
||||
@@ -86,13 +86,13 @@ class GarminConnectDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
|
||||
async def async_login(self) -> bool:
|
||||
"""
|
||||
Asynchronously logs into Garmin Connect using a stored authentication token.
|
||||
|
||||
Attempts to authenticate with Garmin Connect via the token stored in the configuration entry. Handles authentication failures, rate limiting, connection errors, and missing tokens by raising appropriate Home Assistant exceptions or returning False on recoverable errors.
|
||||
|
||||
Asynchronously authenticates with Garmin Connect using a stored token.
|
||||
|
||||
Attempts to log in with the token from the configuration entry, handling authentication failures, rate limiting, connection errors, and missing tokens by raising Home Assistant exceptions or returning False for recoverable errors.
|
||||
|
||||
Returns:
|
||||
True if login is successful, False if rate limited or an unknown error occurs.
|
||||
|
||||
bool: True if login succeeds; False if rate limited or an unknown error occurs.
|
||||
|
||||
Raises:
|
||||
ConfigEntryAuthFailed: If authentication fails or the token is missing.
|
||||
ConfigEntryNotReady: If a connection error occurs.
|
||||
@@ -140,12 +140,12 @@ class GarminConnectDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
|
||||
async def _async_update_data(self) -> dict:
|
||||
"""
|
||||
Asynchronously fetches and aggregates user data from Garmin Connect.
|
||||
|
||||
Retrieves user summary, body composition, recent activities, badges, alarms, activity types, sleep data, HRV data, fitness age, hydration, and gear information. Calculates user points, user level, and determines the next active alarms. Handles authentication, connection, and rate limiting errors by raising Home Assistant exceptions or returning False as appropriate.
|
||||
|
||||
Fetches and aggregates comprehensive user data from Garmin Connect for the current day.
|
||||
|
||||
This asynchronous method retrieves and consolidates user summary, body composition, recent activities, badges, alarms, activity types, sleep metrics, HRV data, fitness age, hydration, and gear information. It calculates user points and level, determines the next scheduled alarms, and extracts key sleep and HRV metrics. Handles authentication, connection, and rate limiting errors by raising Home Assistant exceptions or returning empty results as appropriate.
|
||||
|
||||
Returns:
|
||||
A dictionary containing consolidated Garmin Connect data, including user summary, body composition, activities, badges, alarms, activity types, sleep metrics, HRV status, fitness age, hydration, gear details, and calculated fields such as user points, user level, next alarms, sleep score, and sleep time.
|
||||
dict: A dictionary containing consolidated Garmin Connect data, including user summary, body composition, activities, badges, alarms, activity types, sleep metrics, HRV status, fitness age, hydration, gear details, user points, user level, next alarms, sleep score, and sleep time.
|
||||
"""
|
||||
summary = {}
|
||||
body = {}
|
||||
@@ -412,14 +412,14 @@ class GarminConnectDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
|
||||
def calculate_next_active_alarms(alarms, time_zone):
|
||||
"""
|
||||
Calculates the next active Garmin alarms based on alarm settings and the current time.
|
||||
|
||||
Filters alarms set to "ON" and computes the next scheduled datetime for each alarm day, considering both one-time and recurring alarms. Returns a sorted list of ISO-formatted datetimes for upcoming alarms, or None if no active alarms are found.
|
||||
|
||||
Args:
|
||||
Calculate the next scheduled active Garmin alarms based on alarm settings and the current time.
|
||||
|
||||
Filters alarms that are enabled and computes the next scheduled datetime for each alarm day, handling both one-time and recurring alarms. Returns a sorted list of ISO-formatted datetimes for upcoming alarms, or None if no active alarms are scheduled.
|
||||
|
||||
Parameters:
|
||||
alarms: List of alarm setting dictionaries from Garmin devices.
|
||||
time_zone: Time zone string used to localize alarm times.
|
||||
|
||||
|
||||
Returns:
|
||||
A sorted list of ISO-formatted datetimes for the next active alarms, or None if none are scheduled.
|
||||
"""
|
||||
|
||||
@@ -27,9 +27,9 @@ class GarminConnectConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""
|
||||
Initializes the Garmin Connect configuration flow handler.
|
||||
Initialize schemas and internal state for the Garmin Connect configuration flow handler.
|
||||
|
||||
Sets up schemas for user credentials and MFA input, and initializes internal state variables for API client, login results, MFA code, credentials, and region flag.
|
||||
Sets up validation schemas for user credentials and MFA input, and initializes variables for API client, login results, MFA code, credentials, and region detection.
|
||||
"""
|
||||
self.data_schema = {
|
||||
vol.Required(CONF_USERNAME): str,
|
||||
@@ -49,9 +49,15 @@ class GarminConnectConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
async def _async_garmin_connect_login(self, step_id: str) -> ConfigFlowResult:
|
||||
"""
|
||||
Attempts to authenticate the user with Garmin Connect and handles login errors or MFA requirements.
|
||||
Authenticate the user with Garmin Connect and handle login errors or multi-factor authentication requirements.
|
||||
|
||||
If the user is located in China, configures the API client accordingly. Initiates the login process and, if multi-factor authentication is required, transitions to the MFA step. Handles specific authentication and connection errors, returning appropriate error messages to the user. On successful authentication, proceeds to create the configuration entry.
|
||||
If the user is located in China, configures the API client for the region. Initiates the login process and, if multi-factor authentication is needed, transitions to the MFA step. Handles specific authentication and connection errors, returning appropriate error messages to the user. On successful authentication, proceeds to create or update the configuration entry.
|
||||
|
||||
Parameters:
|
||||
step_id (str): The current step identifier in the configuration flow.
|
||||
|
||||
Returns:
|
||||
ConfigFlowResult: The result of the configuration flow step, which may be a form with errors, a transition to MFA, or entry creation.
|
||||
"""
|
||||
errors = {}
|
||||
|
||||
@@ -95,9 +101,9 @@ class GarminConnectConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
async def _async_garmin_connect_mfa_login(self) -> ConfigFlowResult:
|
||||
"""
|
||||
Completes the Garmin Connect login process using the provided MFA code.
|
||||
Complete the Garmin Connect authentication process using the stored multi-factor authentication (MFA) code.
|
||||
|
||||
Attempts to resume the login session with the stored MFA code. If the MFA code is invalid or an error occurs, prompts the user to re-enter the code. On success, creates the configuration entry.
|
||||
If the MFA code is invalid or an error occurs, prompts the user to re-enter the code. On successful authentication, creates or updates the configuration entry.
|
||||
"""
|
||||
try:
|
||||
await self.hass.async_add_executor_job(self._api.resume_login, self._login_result2, self._mfa_code)
|
||||
@@ -114,9 +120,9 @@ class GarminConnectConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
async def _async_create_entry(self) -> ConfigFlowResult:
|
||||
"""
|
||||
Creates or updates the configuration entry for the Garmin Connect integration.
|
||||
Create or update the configuration entry for the Garmin Connect integration using the current user's credentials and API token.
|
||||
|
||||
If an entry with the same username exists, updates its data and reloads it; otherwise, creates a new entry with the username as the unique ID and stores the serialized API token.
|
||||
If an entry with the same username exists, its data is updated and the entry is reloaded; otherwise, a new entry is created with the username as the unique ID and the serialized API token.
|
||||
"""
|
||||
config_data = {
|
||||
CONF_ID: self._username,
|
||||
@@ -136,9 +142,9 @@ class GarminConnectConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""
|
||||
Handles the initial step of the configuration flow triggered by the user.
|
||||
Handle the initial user step of the configuration flow.
|
||||
|
||||
If no input is provided, displays a form requesting username and password. Otherwise, stores the provided credentials and attempts to authenticate with Garmin Connect.
|
||||
If no input is provided, displays a form to collect username and password. If credentials are submitted, stores them and attempts authentication with Garmin Connect.
|
||||
"""
|
||||
if user_input is None:
|
||||
return self.async_show_form(
|
||||
@@ -154,9 +160,9 @@ class GarminConnectConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""
|
||||
Handles the multi-factor authentication (MFA) step during the configuration flow.
|
||||
Handle the multi-factor authentication (MFA) step in the configuration flow.
|
||||
|
||||
If no user input is provided, displays a form requesting the MFA code. If input is received, stores the MFA code for further authentication processing.
|
||||
If user input is not provided, displays a form to collect the MFA code. If input is provided, stores the MFA code and proceeds with MFA authentication.
|
||||
"""
|
||||
if user_input is None:
|
||||
return self.async_show_form(
|
||||
@@ -172,9 +178,9 @@ class GarminConnectConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
self, entry_data: Mapping[str, Any]
|
||||
) -> ConfigFlowResult:
|
||||
"""
|
||||
Initiates the reauthorization flow using existing entry data.
|
||||
Start the reauthorization process using existing configuration entry data.
|
||||
|
||||
Extracts the username from the provided entry data and proceeds to the reauthorization confirmation step.
|
||||
Extracts the username from the entry data and advances to the reauthorization confirmation step.
|
||||
"""
|
||||
self._username = entry_data[CONF_USERNAME]
|
||||
|
||||
@@ -184,9 +190,9 @@ class GarminConnectConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""
|
||||
Handles the confirmation step for reauthorizing the Garmin Connect integration.
|
||||
Prompt the user to re-enter their username and password to confirm reauthorization of the Garmin Connect integration.
|
||||
|
||||
Prompts the user to re-enter their username and password. Upon receiving input, attempts to log in with the provided credentials to complete the reauthorization process.
|
||||
If credentials are provided, attempts to log in and complete the reauthorization process.
|
||||
"""
|
||||
if user_input is None:
|
||||
return self.async_show_form(
|
||||
|
||||
@@ -188,9 +188,9 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
|
||||
@property
|
||||
def native_value(self):
|
||||
"""
|
||||
Returns the current state value for the sensor, formatted and converted as appropriate for its type.
|
||||
Return the current value of the sensor, applying type-specific formatting and conversions.
|
||||
|
||||
Handles special cases for activity, badge, HRV status, duration, mass, alarm, and stress qualifier sensor types, including value conversions and formatting. Returns None if data is unavailable.
|
||||
For activity and badge sensors, returns the count. For last activity, returns the activity name. HRV status and stress qualifier values are capitalized. Duration and seconds values are converted from seconds to minutes, and mass values from grams to kilograms. For alarms, returns the next active alarm if available. Timestamp values are converted to timezone-aware datetime objects. Returns None if data is unavailable.
|
||||
"""
|
||||
if not self.coordinator.data:
|
||||
return None
|
||||
@@ -236,9 +236,9 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""
|
||||
Returns additional state attributes for the sensor entity.
|
||||
Return additional state attributes for the sensor entity.
|
||||
|
||||
Includes attributes such as the last sync timestamp and, depending on the sensor type, recent activities, badges, alarms, or HRV status details. Limits the number of returned activities and badges for performance.
|
||||
Includes the last sync timestamp and, depending on the sensor type, recent activities (up to 5), badges (up to 10), alarms, or HRV status details (excluding the status string). Returns an empty dictionary if no coordinator data is available.
|
||||
"""
|
||||
if not self.coordinator.data:
|
||||
return {}
|
||||
@@ -288,29 +288,16 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return True if entity is available."""
|
||||
"""
|
||||
Indicates whether the sensor entity is available based on coordinator data presence and the sensor type.
|
||||
"""
|
||||
return super().available and self.coordinator.data and self._type in self.coordinator.data
|
||||
|
||||
async def add_body_composition(self, **kwargs):
|
||||
"""
|
||||
Adds a new body composition record to Garmin Connect.
|
||||
Add a new body composition measurement to Garmin Connect.
|
||||
|
||||
Extracts body composition metrics from the provided keyword arguments and submits them to the Garmin Connect API. Ensures the user is logged in before attempting to add the record.
|
||||
|
||||
Args:
|
||||
weight: The user's weight to record.
|
||||
timestamp: Optional timestamp for the measurement.
|
||||
percent_fat: Optional body fat percentage.
|
||||
percent_hydration: Optional body hydration percentage.
|
||||
visceral_fat_mass: Optional visceral fat mass.
|
||||
bone_mass: Optional bone mass.
|
||||
muscle_mass: Optional muscle mass.
|
||||
basal_met: Optional basal metabolic rate.
|
||||
active_met: Optional active metabolic rate.
|
||||
physique_rating: Optional physique rating.
|
||||
metabolic_age: Optional metabolic age.
|
||||
visceral_fat_rating: Optional visceral fat rating.
|
||||
bmi: Optional body mass index.
|
||||
Extracts body composition metrics from keyword arguments and submits them to the Garmin Connect API. Ensures the user is logged in before attempting to add the record.
|
||||
|
||||
Raises:
|
||||
IntegrationError: If login to Garmin Connect fails.
|
||||
@@ -354,9 +341,9 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
|
||||
|
||||
async def add_blood_pressure(self, **kwargs):
|
||||
"""
|
||||
Adds a blood pressure measurement to Garmin Connect via a service call.
|
||||
Add a blood pressure measurement to Garmin Connect using the provided values.
|
||||
|
||||
Args:
|
||||
Parameters:
|
||||
systolic: Systolic blood pressure value.
|
||||
diastolic: Diastolic blood pressure value.
|
||||
pulse: Pulse rate.
|
||||
@@ -364,7 +351,7 @@ class GarminConnectSensor(CoordinatorEntity, SensorEntity):
|
||||
notes: Optional notes for the measurement.
|
||||
|
||||
Raises:
|
||||
IntegrationError: If login to Garmin Connect fails.
|
||||
IntegrationError: If unable to log in to Garmin Connect.
|
||||
"""
|
||||
timestamp = kwargs.get("timestamp")
|
||||
systolic = kwargs.get("systolic")
|
||||
@@ -433,9 +420,9 @@ class GarminConnectGearSensor(CoordinatorEntity, SensorEntity):
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""
|
||||
Returns additional state attributes for the gear sensor entity.
|
||||
Return additional state attributes for the gear sensor entity.
|
||||
|
||||
Includes metadata such as last sync time, total activities, creation and update dates, gear details, maximum distance, and the activity types for which this gear is set as default.
|
||||
Includes metadata such as last sync time, total activities, creation and update dates, gear make/model/status, custom model, maximum distance, and a comma-separated list of activity types for which this gear is set as default. Returns an empty dictionary if required data is missing.
|
||||
"""
|
||||
gear = self._gear()
|
||||
stats = self._stats()
|
||||
@@ -504,7 +491,12 @@ class GarminConnectGearSensor(CoordinatorEntity, SensorEntity):
|
||||
return gear_item
|
||||
|
||||
def _gear_defaults(self):
|
||||
"""Get gear defaults"""
|
||||
"""
|
||||
Return a list of default gear settings for this gear UUID.
|
||||
|
||||
Returns:
|
||||
List of gear default dictionaries where this gear is set as the default.
|
||||
"""
|
||||
return list(
|
||||
filter(
|
||||
lambda d: d[Gear.UUID] == self.uuid and d["defaultGear"] is True,
|
||||
@@ -514,14 +506,14 @@ class GarminConnectGearSensor(CoordinatorEntity, SensorEntity):
|
||||
|
||||
async def set_active_gear(self, **kwargs):
|
||||
"""
|
||||
Sets the active gear for a specified activity type in Garmin Connect.
|
||||
Set this gear as active or default for a specified activity type in Garmin Connect.
|
||||
|
||||
Args:
|
||||
activity_type: The activity type for which to set the active gear.
|
||||
setting: The desired gear setting, determining whether to set as default or only default.
|
||||
Parameters:
|
||||
activity_type (str): The activity type key for which to update the gear setting.
|
||||
setting (str): The desired gear setting, indicating whether to set as default or as the only default.
|
||||
|
||||
Raises:
|
||||
IntegrationError: If login to Garmin Connect fails.
|
||||
IntegrationError: If unable to log in to Garmin Connect.
|
||||
"""
|
||||
activity_type = kwargs.get("activity_type")
|
||||
setting = kwargs.get("setting")
|
||||
|
||||
Reference in New Issue
Block a user