diff --git a/homeassistant/components/fitbit/const.py b/homeassistant/components/fitbit/const.py index d746e63ca52..1578359356d 100644 --- a/homeassistant/components/fitbit/const.py +++ b/homeassistant/components/fitbit/const.py @@ -1,18 +1,11 @@ """Constants for the Fitbit platform.""" from __future__ import annotations -from dataclasses import dataclass from typing import Final -from homeassistant.components.sensor import ( - SensorDeviceClass, - SensorEntityDescription, - SensorStateClass, -) from homeassistant.const import ( CONF_CLIENT_ID, CONF_CLIENT_SECRET, - PERCENTAGE, UnitOfLength, UnitOfMass, UnitOfTime, @@ -49,245 +42,6 @@ DEFAULT_CONFIG: Final[dict[str, str]] = { DEFAULT_CLOCK_FORMAT: Final = "24H" -@dataclass -class FitbitSensorEntityDescription(SensorEntityDescription): - """Describes Fitbit sensor entity.""" - - unit_type: str | None = None - - -FITBIT_RESOURCES_LIST: Final[tuple[FitbitSensorEntityDescription, ...]] = ( - FitbitSensorEntityDescription( - key="activities/activityCalories", - name="Activity Calories", - native_unit_of_measurement="cal", - icon="mdi:fire", - ), - FitbitSensorEntityDescription( - key="activities/calories", - name="Calories", - native_unit_of_measurement="cal", - icon="mdi:fire", - ), - FitbitSensorEntityDescription( - key="activities/caloriesBMR", - name="Calories BMR", - native_unit_of_measurement="cal", - icon="mdi:fire", - ), - FitbitSensorEntityDescription( - key="activities/distance", - name="Distance", - unit_type="distance", - icon="mdi:map-marker", - device_class=SensorDeviceClass.DISTANCE, - ), - FitbitSensorEntityDescription( - key="activities/elevation", - name="Elevation", - unit_type="elevation", - icon="mdi:walk", - device_class=SensorDeviceClass.DISTANCE, - ), - FitbitSensorEntityDescription( - key="activities/floors", - name="Floors", - native_unit_of_measurement="floors", - icon="mdi:walk", - ), - FitbitSensorEntityDescription( - key="activities/heart", - name="Resting Heart Rate", - native_unit_of_measurement="bpm", - icon="mdi:heart-pulse", - ), - FitbitSensorEntityDescription( - key="activities/minutesFairlyActive", - name="Minutes Fairly Active", - native_unit_of_measurement=UnitOfTime.MINUTES, - icon="mdi:walk", - device_class=SensorDeviceClass.DURATION, - ), - FitbitSensorEntityDescription( - key="activities/minutesLightlyActive", - name="Minutes Lightly Active", - native_unit_of_measurement=UnitOfTime.MINUTES, - icon="mdi:walk", - device_class=SensorDeviceClass.DURATION, - ), - FitbitSensorEntityDescription( - key="activities/minutesSedentary", - name="Minutes Sedentary", - native_unit_of_measurement=UnitOfTime.MINUTES, - icon="mdi:seat-recline-normal", - device_class=SensorDeviceClass.DURATION, - ), - FitbitSensorEntityDescription( - key="activities/minutesVeryActive", - name="Minutes Very Active", - native_unit_of_measurement=UnitOfTime.MINUTES, - icon="mdi:run", - device_class=SensorDeviceClass.DURATION, - ), - FitbitSensorEntityDescription( - key="activities/steps", - name="Steps", - native_unit_of_measurement="steps", - icon="mdi:walk", - ), - FitbitSensorEntityDescription( - key="activities/tracker/activityCalories", - name="Tracker Activity Calories", - native_unit_of_measurement="cal", - icon="mdi:fire", - ), - FitbitSensorEntityDescription( - key="activities/tracker/calories", - name="Tracker Calories", - native_unit_of_measurement="cal", - icon="mdi:fire", - ), - FitbitSensorEntityDescription( - key="activities/tracker/distance", - name="Tracker Distance", - unit_type="distance", - icon="mdi:map-marker", - device_class=SensorDeviceClass.DISTANCE, - ), - FitbitSensorEntityDescription( - key="activities/tracker/elevation", - name="Tracker Elevation", - unit_type="elevation", - icon="mdi:walk", - device_class=SensorDeviceClass.DISTANCE, - ), - FitbitSensorEntityDescription( - key="activities/tracker/floors", - name="Tracker Floors", - native_unit_of_measurement="floors", - icon="mdi:walk", - ), - FitbitSensorEntityDescription( - key="activities/tracker/minutesFairlyActive", - name="Tracker Minutes Fairly Active", - native_unit_of_measurement=UnitOfTime.MINUTES, - icon="mdi:walk", - device_class=SensorDeviceClass.DURATION, - ), - FitbitSensorEntityDescription( - key="activities/tracker/minutesLightlyActive", - name="Tracker Minutes Lightly Active", - native_unit_of_measurement=UnitOfTime.MINUTES, - icon="mdi:walk", - device_class=SensorDeviceClass.DURATION, - ), - FitbitSensorEntityDescription( - key="activities/tracker/minutesSedentary", - name="Tracker Minutes Sedentary", - native_unit_of_measurement=UnitOfTime.MINUTES, - icon="mdi:seat-recline-normal", - device_class=SensorDeviceClass.DURATION, - ), - FitbitSensorEntityDescription( - key="activities/tracker/minutesVeryActive", - name="Tracker Minutes Very Active", - native_unit_of_measurement=UnitOfTime.MINUTES, - icon="mdi:run", - device_class=SensorDeviceClass.DURATION, - ), - FitbitSensorEntityDescription( - key="activities/tracker/steps", - name="Tracker Steps", - native_unit_of_measurement="steps", - icon="mdi:walk", - ), - FitbitSensorEntityDescription( - key="body/bmi", - name="BMI", - native_unit_of_measurement="BMI", - icon="mdi:human", - state_class=SensorStateClass.MEASUREMENT, - ), - FitbitSensorEntityDescription( - key="body/fat", - name="Body Fat", - native_unit_of_measurement=PERCENTAGE, - icon="mdi:human", - state_class=SensorStateClass.MEASUREMENT, - ), - FitbitSensorEntityDescription( - key="body/weight", - name="Weight", - unit_type="weight", - icon="mdi:human", - state_class=SensorStateClass.MEASUREMENT, - device_class=SensorDeviceClass.WEIGHT, - ), - FitbitSensorEntityDescription( - key="sleep/awakeningsCount", - name="Awakenings Count", - native_unit_of_measurement="times awaken", - icon="mdi:sleep", - ), - FitbitSensorEntityDescription( - key="sleep/efficiency", - name="Sleep Efficiency", - native_unit_of_measurement=PERCENTAGE, - icon="mdi:sleep", - state_class=SensorStateClass.MEASUREMENT, - ), - FitbitSensorEntityDescription( - key="sleep/minutesAfterWakeup", - name="Minutes After Wakeup", - native_unit_of_measurement=UnitOfTime.MINUTES, - icon="mdi:sleep", - device_class=SensorDeviceClass.DURATION, - ), - FitbitSensorEntityDescription( - key="sleep/minutesAsleep", - name="Sleep Minutes Asleep", - native_unit_of_measurement=UnitOfTime.MINUTES, - icon="mdi:sleep", - device_class=SensorDeviceClass.DURATION, - ), - FitbitSensorEntityDescription( - key="sleep/minutesAwake", - name="Sleep Minutes Awake", - native_unit_of_measurement=UnitOfTime.MINUTES, - icon="mdi:sleep", - device_class=SensorDeviceClass.DURATION, - ), - FitbitSensorEntityDescription( - key="sleep/minutesToFallAsleep", - name="Sleep Minutes to Fall Asleep", - native_unit_of_measurement=UnitOfTime.MINUTES, - icon="mdi:sleep", - device_class=SensorDeviceClass.DURATION, - ), - FitbitSensorEntityDescription( - key="sleep/startTime", - name="Sleep Start Time", - icon="mdi:clock", - ), - FitbitSensorEntityDescription( - key="sleep/timeInBed", - name="Sleep Time in Bed", - native_unit_of_measurement=UnitOfTime.MINUTES, - icon="mdi:hotel", - device_class=SensorDeviceClass.DURATION, - ), -) - -FITBIT_RESOURCE_BATTERY = FitbitSensorEntityDescription( - key="devices/battery", - name="Battery", - icon="mdi:battery", -) - -FITBIT_RESOURCES_KEYS: Final[list[str]] = [ - desc.key for desc in (*FITBIT_RESOURCES_LIST, FITBIT_RESOURCE_BATTERY) -] - FITBIT_MEASUREMENTS: Final[dict[str, dict[str, str]]] = { "en_US": { ATTR_DURATION: UnitOfTime.MILLISECONDS, diff --git a/homeassistant/components/fitbit/sensor.py b/homeassistant/components/fitbit/sensor.py index 11946c42173..6c93fbe35c1 100644 --- a/homeassistant/components/fitbit/sensor.py +++ b/homeassistant/components/fitbit/sensor.py @@ -1,6 +1,7 @@ """Support for the Fitbit API.""" from __future__ import annotations +from dataclasses import dataclass import datetime import logging import os @@ -17,9 +18,18 @@ from homeassistant.components import configurator from homeassistant.components.http import HomeAssistantView from homeassistant.components.sensor import ( PLATFORM_SCHEMA as PARENT_PLATFORM_SCHEMA, + SensorDeviceClass, SensorEntity, + SensorEntityDescription, + SensorStateClass, +) +from homeassistant.const import ( + CONF_CLIENT_ID, + CONF_CLIENT_SECRET, + CONF_UNIT_SYSTEM, + PERCENTAGE, + UnitOfTime, ) -from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_UNIT_SYSTEM from homeassistant.core import HomeAssistant import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity_platform import AddEntitiesCallback @@ -45,10 +55,6 @@ from .const import ( FITBIT_CONFIG_FILE, FITBIT_DEFAULT_RESOURCES, FITBIT_MEASUREMENTS, - FITBIT_RESOURCE_BATTERY, - FITBIT_RESOURCES_KEYS, - FITBIT_RESOURCES_LIST, - FitbitSensorEntityDescription, ) _LOGGER: Final = logging.getLogger(__name__) @@ -57,6 +63,246 @@ _CONFIGURING: dict[str, str] = {} SCAN_INTERVAL: Final = datetime.timedelta(minutes=30) + +@dataclass +class FitbitSensorEntityDescription(SensorEntityDescription): + """Describes Fitbit sensor entity.""" + + unit_type: str | None = None + + +FITBIT_RESOURCES_LIST: Final[tuple[FitbitSensorEntityDescription, ...]] = ( + FitbitSensorEntityDescription( + key="activities/activityCalories", + name="Activity Calories", + native_unit_of_measurement="cal", + icon="mdi:fire", + ), + FitbitSensorEntityDescription( + key="activities/calories", + name="Calories", + native_unit_of_measurement="cal", + icon="mdi:fire", + ), + FitbitSensorEntityDescription( + key="activities/caloriesBMR", + name="Calories BMR", + native_unit_of_measurement="cal", + icon="mdi:fire", + ), + FitbitSensorEntityDescription( + key="activities/distance", + name="Distance", + unit_type="distance", + icon="mdi:map-marker", + device_class=SensorDeviceClass.DISTANCE, + ), + FitbitSensorEntityDescription( + key="activities/elevation", + name="Elevation", + unit_type="elevation", + icon="mdi:walk", + device_class=SensorDeviceClass.DISTANCE, + ), + FitbitSensorEntityDescription( + key="activities/floors", + name="Floors", + native_unit_of_measurement="floors", + icon="mdi:walk", + ), + FitbitSensorEntityDescription( + key="activities/heart", + name="Resting Heart Rate", + native_unit_of_measurement="bpm", + icon="mdi:heart-pulse", + ), + FitbitSensorEntityDescription( + key="activities/minutesFairlyActive", + name="Minutes Fairly Active", + native_unit_of_measurement=UnitOfTime.MINUTES, + icon="mdi:walk", + device_class=SensorDeviceClass.DURATION, + ), + FitbitSensorEntityDescription( + key="activities/minutesLightlyActive", + name="Minutes Lightly Active", + native_unit_of_measurement=UnitOfTime.MINUTES, + icon="mdi:walk", + device_class=SensorDeviceClass.DURATION, + ), + FitbitSensorEntityDescription( + key="activities/minutesSedentary", + name="Minutes Sedentary", + native_unit_of_measurement=UnitOfTime.MINUTES, + icon="mdi:seat-recline-normal", + device_class=SensorDeviceClass.DURATION, + ), + FitbitSensorEntityDescription( + key="activities/minutesVeryActive", + name="Minutes Very Active", + native_unit_of_measurement=UnitOfTime.MINUTES, + icon="mdi:run", + device_class=SensorDeviceClass.DURATION, + ), + FitbitSensorEntityDescription( + key="activities/steps", + name="Steps", + native_unit_of_measurement="steps", + icon="mdi:walk", + ), + FitbitSensorEntityDescription( + key="activities/tracker/activityCalories", + name="Tracker Activity Calories", + native_unit_of_measurement="cal", + icon="mdi:fire", + ), + FitbitSensorEntityDescription( + key="activities/tracker/calories", + name="Tracker Calories", + native_unit_of_measurement="cal", + icon="mdi:fire", + ), + FitbitSensorEntityDescription( + key="activities/tracker/distance", + name="Tracker Distance", + unit_type="distance", + icon="mdi:map-marker", + device_class=SensorDeviceClass.DISTANCE, + ), + FitbitSensorEntityDescription( + key="activities/tracker/elevation", + name="Tracker Elevation", + unit_type="elevation", + icon="mdi:walk", + device_class=SensorDeviceClass.DISTANCE, + ), + FitbitSensorEntityDescription( + key="activities/tracker/floors", + name="Tracker Floors", + native_unit_of_measurement="floors", + icon="mdi:walk", + ), + FitbitSensorEntityDescription( + key="activities/tracker/minutesFairlyActive", + name="Tracker Minutes Fairly Active", + native_unit_of_measurement=UnitOfTime.MINUTES, + icon="mdi:walk", + device_class=SensorDeviceClass.DURATION, + ), + FitbitSensorEntityDescription( + key="activities/tracker/minutesLightlyActive", + name="Tracker Minutes Lightly Active", + native_unit_of_measurement=UnitOfTime.MINUTES, + icon="mdi:walk", + device_class=SensorDeviceClass.DURATION, + ), + FitbitSensorEntityDescription( + key="activities/tracker/minutesSedentary", + name="Tracker Minutes Sedentary", + native_unit_of_measurement=UnitOfTime.MINUTES, + icon="mdi:seat-recline-normal", + device_class=SensorDeviceClass.DURATION, + ), + FitbitSensorEntityDescription( + key="activities/tracker/minutesVeryActive", + name="Tracker Minutes Very Active", + native_unit_of_measurement=UnitOfTime.MINUTES, + icon="mdi:run", + device_class=SensorDeviceClass.DURATION, + ), + FitbitSensorEntityDescription( + key="activities/tracker/steps", + name="Tracker Steps", + native_unit_of_measurement="steps", + icon="mdi:walk", + ), + FitbitSensorEntityDescription( + key="body/bmi", + name="BMI", + native_unit_of_measurement="BMI", + icon="mdi:human", + state_class=SensorStateClass.MEASUREMENT, + ), + FitbitSensorEntityDescription( + key="body/fat", + name="Body Fat", + native_unit_of_measurement=PERCENTAGE, + icon="mdi:human", + state_class=SensorStateClass.MEASUREMENT, + ), + FitbitSensorEntityDescription( + key="body/weight", + name="Weight", + unit_type="weight", + icon="mdi:human", + state_class=SensorStateClass.MEASUREMENT, + device_class=SensorDeviceClass.WEIGHT, + ), + FitbitSensorEntityDescription( + key="sleep/awakeningsCount", + name="Awakenings Count", + native_unit_of_measurement="times awaken", + icon="mdi:sleep", + ), + FitbitSensorEntityDescription( + key="sleep/efficiency", + name="Sleep Efficiency", + native_unit_of_measurement=PERCENTAGE, + icon="mdi:sleep", + state_class=SensorStateClass.MEASUREMENT, + ), + FitbitSensorEntityDescription( + key="sleep/minutesAfterWakeup", + name="Minutes After Wakeup", + native_unit_of_measurement=UnitOfTime.MINUTES, + icon="mdi:sleep", + device_class=SensorDeviceClass.DURATION, + ), + FitbitSensorEntityDescription( + key="sleep/minutesAsleep", + name="Sleep Minutes Asleep", + native_unit_of_measurement=UnitOfTime.MINUTES, + icon="mdi:sleep", + device_class=SensorDeviceClass.DURATION, + ), + FitbitSensorEntityDescription( + key="sleep/minutesAwake", + name="Sleep Minutes Awake", + native_unit_of_measurement=UnitOfTime.MINUTES, + icon="mdi:sleep", + device_class=SensorDeviceClass.DURATION, + ), + FitbitSensorEntityDescription( + key="sleep/minutesToFallAsleep", + name="Sleep Minutes to Fall Asleep", + native_unit_of_measurement=UnitOfTime.MINUTES, + icon="mdi:sleep", + device_class=SensorDeviceClass.DURATION, + ), + FitbitSensorEntityDescription( + key="sleep/startTime", + name="Sleep Start Time", + icon="mdi:clock", + ), + FitbitSensorEntityDescription( + key="sleep/timeInBed", + name="Sleep Time in Bed", + native_unit_of_measurement=UnitOfTime.MINUTES, + icon="mdi:hotel", + device_class=SensorDeviceClass.DURATION, + ), +) + +FITBIT_RESOURCE_BATTERY = FitbitSensorEntityDescription( + key="devices/battery", + name="Battery", + icon="mdi:battery", +) + +FITBIT_RESOURCES_KEYS: Final[list[str]] = [ + desc.key for desc in (*FITBIT_RESOURCES_LIST, FITBIT_RESOURCE_BATTERY) +] + PLATFORM_SCHEMA: Final = PARENT_PLATFORM_SCHEMA.extend( { vol.Optional(