Refactor fitbit descriptions to use device classes (#83936)

This commit is contained in:
epenet 2022-12-13 21:49:41 +01:00 committed by GitHub
parent b7b7cdcfcf
commit 62d22d7a2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 73 deletions

View File

@ -4,16 +4,19 @@ from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from typing import Final from typing import Final
from homeassistant.components.sensor import SensorEntityDescription, SensorStateClass from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import ( from homeassistant.const import (
CONF_CLIENT_ID, CONF_CLIENT_ID,
CONF_CLIENT_SECRET, CONF_CLIENT_SECRET,
LENGTH_FEET,
MASS_KILOGRAMS,
MASS_MILLIGRAMS,
PERCENTAGE, PERCENTAGE,
TIME_MILLISECONDS, UnitOfLength,
TIME_MINUTES, UnitOfMass,
UnitOfTime,
UnitOfVolume,
) )
ATTR_ACCESS_TOKEN: Final = "access_token" ATTR_ACCESS_TOKEN: Final = "access_token"
@ -47,226 +50,237 @@ DEFAULT_CLOCK_FORMAT: Final = "24H"
@dataclass @dataclass
class FitbitRequiredKeysMixin: class FitbitSensorEntityDescription(SensorEntityDescription):
"""Mixin for required keys."""
unit_type: str | None
@dataclass
class FitbitSensorEntityDescription(SensorEntityDescription, FitbitRequiredKeysMixin):
"""Describes Fitbit sensor entity.""" """Describes Fitbit sensor entity."""
unit_type: str | None = None
FITBIT_RESOURCES_LIST: Final[tuple[FitbitSensorEntityDescription, ...]] = ( FITBIT_RESOURCES_LIST: Final[tuple[FitbitSensorEntityDescription, ...]] = (
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/activityCalories", key="activities/activityCalories",
name="Activity Calories", name="Activity Calories",
unit_type="cal", native_unit_of_measurement="cal",
icon="mdi:fire", icon="mdi:fire",
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/calories", key="activities/calories",
name="Calories", name="Calories",
unit_type="cal", native_unit_of_measurement="cal",
icon="mdi:fire", icon="mdi:fire",
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/caloriesBMR", key="activities/caloriesBMR",
name="Calories BMR", name="Calories BMR",
unit_type="cal", native_unit_of_measurement="cal",
icon="mdi:fire", icon="mdi:fire",
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/distance", key="activities/distance",
name="Distance", name="Distance",
unit_type="", unit_type="distance",
icon="mdi:map-marker", icon="mdi:map-marker",
device_class=SensorDeviceClass.DISTANCE,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/elevation", key="activities/elevation",
name="Elevation", name="Elevation",
unit_type="", unit_type="elevation",
icon="mdi:walk", icon="mdi:walk",
device_class=SensorDeviceClass.DISTANCE,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/floors", key="activities/floors",
name="Floors", name="Floors",
unit_type="floors", native_unit_of_measurement="floors",
icon="mdi:walk", icon="mdi:walk",
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/heart", key="activities/heart",
name="Resting Heart Rate", name="Resting Heart Rate",
unit_type="bpm", native_unit_of_measurement="bpm",
icon="mdi:heart-pulse", icon="mdi:heart-pulse",
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/minutesFairlyActive", key="activities/minutesFairlyActive",
name="Minutes Fairly Active", name="Minutes Fairly Active",
unit_type=TIME_MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
icon="mdi:walk", icon="mdi:walk",
device_class=SensorDeviceClass.DURATION,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/minutesLightlyActive", key="activities/minutesLightlyActive",
name="Minutes Lightly Active", name="Minutes Lightly Active",
unit_type=TIME_MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
icon="mdi:walk", icon="mdi:walk",
device_class=SensorDeviceClass.DURATION,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/minutesSedentary", key="activities/minutesSedentary",
name="Minutes Sedentary", name="Minutes Sedentary",
unit_type=TIME_MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
icon="mdi:seat-recline-normal", icon="mdi:seat-recline-normal",
device_class=SensorDeviceClass.DURATION,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/minutesVeryActive", key="activities/minutesVeryActive",
name="Minutes Very Active", name="Minutes Very Active",
unit_type=TIME_MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
icon="mdi:run", icon="mdi:run",
device_class=SensorDeviceClass.DURATION,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/steps", key="activities/steps",
name="Steps", name="Steps",
unit_type="steps", native_unit_of_measurement="steps",
icon="mdi:walk", icon="mdi:walk",
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/tracker/activityCalories", key="activities/tracker/activityCalories",
name="Tracker Activity Calories", name="Tracker Activity Calories",
unit_type="cal", native_unit_of_measurement="cal",
icon="mdi:fire", icon="mdi:fire",
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/tracker/calories", key="activities/tracker/calories",
name="Tracker Calories", name="Tracker Calories",
unit_type="cal", native_unit_of_measurement="cal",
icon="mdi:fire", icon="mdi:fire",
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/tracker/distance", key="activities/tracker/distance",
name="Tracker Distance", name="Tracker Distance",
unit_type="", unit_type="distance",
icon="mdi:map-marker", icon="mdi:map-marker",
device_class=SensorDeviceClass.DISTANCE,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/tracker/elevation", key="activities/tracker/elevation",
name="Tracker Elevation", name="Tracker Elevation",
unit_type="", unit_type="elevation",
icon="mdi:walk", icon="mdi:walk",
device_class=SensorDeviceClass.DISTANCE,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/tracker/floors", key="activities/tracker/floors",
name="Tracker Floors", name="Tracker Floors",
unit_type="floors", native_unit_of_measurement="floors",
icon="mdi:walk", icon="mdi:walk",
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/tracker/minutesFairlyActive", key="activities/tracker/minutesFairlyActive",
name="Tracker Minutes Fairly Active", name="Tracker Minutes Fairly Active",
unit_type=TIME_MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
icon="mdi:walk", icon="mdi:walk",
device_class=SensorDeviceClass.DURATION,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/tracker/minutesLightlyActive", key="activities/tracker/minutesLightlyActive",
name="Tracker Minutes Lightly Active", name="Tracker Minutes Lightly Active",
unit_type=TIME_MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
icon="mdi:walk", icon="mdi:walk",
device_class=SensorDeviceClass.DURATION,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/tracker/minutesSedentary", key="activities/tracker/minutesSedentary",
name="Tracker Minutes Sedentary", name="Tracker Minutes Sedentary",
unit_type=TIME_MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
icon="mdi:seat-recline-normal", icon="mdi:seat-recline-normal",
device_class=SensorDeviceClass.DURATION,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/tracker/minutesVeryActive", key="activities/tracker/minutesVeryActive",
name="Tracker Minutes Very Active", name="Tracker Minutes Very Active",
unit_type=TIME_MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
icon="mdi:run", icon="mdi:run",
device_class=SensorDeviceClass.DURATION,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="activities/tracker/steps", key="activities/tracker/steps",
name="Tracker Steps", name="Tracker Steps",
unit_type="steps", native_unit_of_measurement="steps",
icon="mdi:walk", icon="mdi:walk",
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="body/bmi", key="body/bmi",
name="BMI", name="BMI",
unit_type="BMI", native_unit_of_measurement="BMI",
icon="mdi:human", icon="mdi:human",
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="body/fat", key="body/fat",
name="Body Fat", name="Body Fat",
unit_type=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
icon="mdi:human", icon="mdi:human",
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="body/weight", key="body/weight",
name="Weight", name="Weight",
unit_type="", unit_type="weight",
icon="mdi:human", icon="mdi:human",
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.WEIGHT,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="sleep/awakeningsCount", key="sleep/awakeningsCount",
name="Awakenings Count", name="Awakenings Count",
unit_type="times awaken", native_unit_of_measurement="times awaken",
icon="mdi:sleep", icon="mdi:sleep",
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="sleep/efficiency", key="sleep/efficiency",
name="Sleep Efficiency", name="Sleep Efficiency",
unit_type=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
icon="mdi:sleep", icon="mdi:sleep",
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="sleep/minutesAfterWakeup", key="sleep/minutesAfterWakeup",
name="Minutes After Wakeup", name="Minutes After Wakeup",
unit_type=TIME_MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
icon="mdi:sleep", icon="mdi:sleep",
device_class=SensorDeviceClass.DURATION,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="sleep/minutesAsleep", key="sleep/minutesAsleep",
name="Sleep Minutes Asleep", name="Sleep Minutes Asleep",
unit_type=TIME_MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
icon="mdi:sleep", icon="mdi:sleep",
device_class=SensorDeviceClass.DURATION,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="sleep/minutesAwake", key="sleep/minutesAwake",
name="Sleep Minutes Awake", name="Sleep Minutes Awake",
unit_type=TIME_MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
icon="mdi:sleep", icon="mdi:sleep",
device_class=SensorDeviceClass.DURATION,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="sleep/minutesToFallAsleep", key="sleep/minutesToFallAsleep",
name="Sleep Minutes to Fall Asleep", name="Sleep Minutes to Fall Asleep",
unit_type=TIME_MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
icon="mdi:sleep", icon="mdi:sleep",
device_class=SensorDeviceClass.DURATION,
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="sleep/startTime", key="sleep/startTime",
name="Sleep Start Time", name="Sleep Start Time",
unit_type=None,
icon="mdi:clock", icon="mdi:clock",
), ),
FitbitSensorEntityDescription( FitbitSensorEntityDescription(
key="sleep/timeInBed", key="sleep/timeInBed",
name="Sleep Time in Bed", name="Sleep Time in Bed",
unit_type=TIME_MINUTES, native_unit_of_measurement=UnitOfTime.MINUTES,
icon="mdi:hotel", icon="mdi:hotel",
device_class=SensorDeviceClass.DURATION,
), ),
) )
FITBIT_RESOURCE_BATTERY = FitbitSensorEntityDescription( FITBIT_RESOURCE_BATTERY = FitbitSensorEntityDescription(
key="devices/battery", key="devices/battery",
name="Battery", name="Battery",
unit_type=None,
icon="mdi:battery", icon="mdi:battery",
) )
@ -276,35 +290,35 @@ FITBIT_RESOURCES_KEYS: Final[list[str]] = [
FITBIT_MEASUREMENTS: Final[dict[str, dict[str, str]]] = { FITBIT_MEASUREMENTS: Final[dict[str, dict[str, str]]] = {
"en_US": { "en_US": {
ATTR_DURATION: TIME_MILLISECONDS, ATTR_DURATION: UnitOfTime.MILLISECONDS,
ATTR_DISTANCE: "mi", ATTR_DISTANCE: UnitOfLength.MILES,
ATTR_ELEVATION: LENGTH_FEET, ATTR_ELEVATION: UnitOfLength.FEET,
ATTR_HEIGHT: "in", ATTR_HEIGHT: UnitOfLength.INCHES,
ATTR_WEIGHT: "lbs", ATTR_WEIGHT: UnitOfMass.POUNDS,
ATTR_BODY: "in", ATTR_BODY: UnitOfLength.INCHES,
ATTR_LIQUIDS: "fl. oz.", ATTR_LIQUIDS: UnitOfVolume.FLUID_OUNCES,
ATTR_BLOOD_GLUCOSE: f"{MASS_MILLIGRAMS}/dL", ATTR_BLOOD_GLUCOSE: f"{UnitOfMass.MILLIGRAMS}/dL",
ATTR_BATTERY: "", ATTR_BATTERY: "",
}, },
"en_GB": { "en_GB": {
ATTR_DURATION: TIME_MILLISECONDS, ATTR_DURATION: UnitOfTime.MILLISECONDS,
ATTR_DISTANCE: "kilometers", ATTR_DISTANCE: UnitOfLength.KILOMETERS,
ATTR_ELEVATION: "meters", ATTR_ELEVATION: UnitOfLength.METERS,
ATTR_HEIGHT: "centimeters", ATTR_HEIGHT: UnitOfLength.CENTIMETERS,
ATTR_WEIGHT: "stone", ATTR_WEIGHT: UnitOfMass.STONES,
ATTR_BODY: "centimeters", ATTR_BODY: UnitOfLength.CENTIMETERS,
ATTR_LIQUIDS: "milliliters", ATTR_LIQUIDS: UnitOfVolume.MILLILITERS,
ATTR_BLOOD_GLUCOSE: "mmol/L", ATTR_BLOOD_GLUCOSE: "mmol/L",
ATTR_BATTERY: "", ATTR_BATTERY: "",
}, },
"metric": { "metric": {
ATTR_DURATION: TIME_MILLISECONDS, ATTR_DURATION: UnitOfTime.MILLISECONDS,
ATTR_DISTANCE: "kilometers", ATTR_DISTANCE: UnitOfLength.KILOMETERS,
ATTR_ELEVATION: "meters", ATTR_ELEVATION: UnitOfLength.METERS,
ATTR_HEIGHT: "centimeters", ATTR_HEIGHT: UnitOfLength.CENTIMETERS,
ATTR_WEIGHT: MASS_KILOGRAMS, ATTR_WEIGHT: UnitOfMass.KILOGRAMS,
ATTR_BODY: "centimeters", ATTR_BODY: UnitOfLength.CENTIMETERS,
ATTR_LIQUIDS: "milliliters", ATTR_LIQUIDS: UnitOfVolume.MILLILITERS,
ATTR_BLOOD_GLUCOSE: "mmol/L", ATTR_BLOOD_GLUCOSE: "mmol/L",
ATTR_BATTERY: "", ATTR_BATTERY: "",
}, },

View File

@ -365,8 +365,7 @@ class FitbitSensor(SensorEntity):
self._attr_name = f"{self.extra.get('deviceVersion')} Battery" self._attr_name = f"{self.extra.get('deviceVersion')} Battery"
self._attr_unique_id = f"{self._attr_unique_id}_{self.extra.get('id')}" self._attr_unique_id = f"{self._attr_unique_id}_{self.extra.get('id')}"
if (unit_type := description.unit_type) == "": if description.unit_type:
split_resource = description.key.rsplit("/", maxsplit=1)[-1]
try: try:
measurement_system = FITBIT_MEASUREMENTS[self.client.system] measurement_system = FITBIT_MEASUREMENTS[self.client.system]
except KeyError: except KeyError:
@ -374,8 +373,9 @@ class FitbitSensor(SensorEntity):
measurement_system = FITBIT_MEASUREMENTS["metric"] measurement_system = FITBIT_MEASUREMENTS["metric"]
else: else:
measurement_system = FITBIT_MEASUREMENTS["en_US"] measurement_system = FITBIT_MEASUREMENTS["en_US"]
split_resource = description.key.rsplit("/", maxsplit=1)[-1]
unit_type = measurement_system[split_resource] unit_type = measurement_system[split_resource]
self._attr_native_unit_of_measurement = unit_type self._attr_native_unit_of_measurement = unit_type
@property @property
def icon(self) -> str | None: def icon(self) -> str | None: