From 62d22d7a2dc490554612e3543868db849726e61c Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Tue, 13 Dec 2022 21:49:41 +0100 Subject: [PATCH] Refactor fitbit descriptions to use device classes (#83936) --- homeassistant/components/fitbit/const.py | 154 ++++++++++++---------- homeassistant/components/fitbit/sensor.py | 6 +- 2 files changed, 87 insertions(+), 73 deletions(-) diff --git a/homeassistant/components/fitbit/const.py b/homeassistant/components/fitbit/const.py index 26db1f91659..d746e63ca52 100644 --- a/homeassistant/components/fitbit/const.py +++ b/homeassistant/components/fitbit/const.py @@ -4,16 +4,19 @@ from __future__ import annotations from dataclasses import dataclass from typing import Final -from homeassistant.components.sensor import SensorEntityDescription, SensorStateClass +from homeassistant.components.sensor import ( + SensorDeviceClass, + SensorEntityDescription, + SensorStateClass, +) from homeassistant.const import ( CONF_CLIENT_ID, CONF_CLIENT_SECRET, - LENGTH_FEET, - MASS_KILOGRAMS, - MASS_MILLIGRAMS, PERCENTAGE, - TIME_MILLISECONDS, - TIME_MINUTES, + UnitOfLength, + UnitOfMass, + UnitOfTime, + UnitOfVolume, ) ATTR_ACCESS_TOKEN: Final = "access_token" @@ -47,226 +50,237 @@ DEFAULT_CLOCK_FORMAT: Final = "24H" @dataclass -class FitbitRequiredKeysMixin: - """Mixin for required keys.""" - - unit_type: str | None - - -@dataclass -class FitbitSensorEntityDescription(SensorEntityDescription, FitbitRequiredKeysMixin): +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", - unit_type="cal", + native_unit_of_measurement="cal", icon="mdi:fire", ), FitbitSensorEntityDescription( key="activities/calories", name="Calories", - unit_type="cal", + native_unit_of_measurement="cal", icon="mdi:fire", ), FitbitSensorEntityDescription( key="activities/caloriesBMR", name="Calories BMR", - unit_type="cal", + native_unit_of_measurement="cal", icon="mdi:fire", ), FitbitSensorEntityDescription( key="activities/distance", name="Distance", - unit_type="", + unit_type="distance", icon="mdi:map-marker", + device_class=SensorDeviceClass.DISTANCE, ), FitbitSensorEntityDescription( key="activities/elevation", name="Elevation", - unit_type="", + unit_type="elevation", icon="mdi:walk", + device_class=SensorDeviceClass.DISTANCE, ), FitbitSensorEntityDescription( key="activities/floors", name="Floors", - unit_type="floors", + native_unit_of_measurement="floors", icon="mdi:walk", ), FitbitSensorEntityDescription( key="activities/heart", name="Resting Heart Rate", - unit_type="bpm", + native_unit_of_measurement="bpm", icon="mdi:heart-pulse", ), FitbitSensorEntityDescription( key="activities/minutesFairlyActive", name="Minutes Fairly Active", - unit_type=TIME_MINUTES, + native_unit_of_measurement=UnitOfTime.MINUTES, icon="mdi:walk", + device_class=SensorDeviceClass.DURATION, ), FitbitSensorEntityDescription( key="activities/minutesLightlyActive", name="Minutes Lightly Active", - unit_type=TIME_MINUTES, + native_unit_of_measurement=UnitOfTime.MINUTES, icon="mdi:walk", + device_class=SensorDeviceClass.DURATION, ), FitbitSensorEntityDescription( key="activities/minutesSedentary", name="Minutes Sedentary", - unit_type=TIME_MINUTES, + native_unit_of_measurement=UnitOfTime.MINUTES, icon="mdi:seat-recline-normal", + device_class=SensorDeviceClass.DURATION, ), FitbitSensorEntityDescription( key="activities/minutesVeryActive", name="Minutes Very Active", - unit_type=TIME_MINUTES, + native_unit_of_measurement=UnitOfTime.MINUTES, icon="mdi:run", + device_class=SensorDeviceClass.DURATION, ), FitbitSensorEntityDescription( key="activities/steps", name="Steps", - unit_type="steps", + native_unit_of_measurement="steps", icon="mdi:walk", ), FitbitSensorEntityDescription( key="activities/tracker/activityCalories", name="Tracker Activity Calories", - unit_type="cal", + native_unit_of_measurement="cal", icon="mdi:fire", ), FitbitSensorEntityDescription( key="activities/tracker/calories", name="Tracker Calories", - unit_type="cal", + native_unit_of_measurement="cal", icon="mdi:fire", ), FitbitSensorEntityDescription( key="activities/tracker/distance", name="Tracker Distance", - unit_type="", + unit_type="distance", icon="mdi:map-marker", + device_class=SensorDeviceClass.DISTANCE, ), FitbitSensorEntityDescription( key="activities/tracker/elevation", name="Tracker Elevation", - unit_type="", + unit_type="elevation", icon="mdi:walk", + device_class=SensorDeviceClass.DISTANCE, ), FitbitSensorEntityDescription( key="activities/tracker/floors", name="Tracker Floors", - unit_type="floors", + native_unit_of_measurement="floors", icon="mdi:walk", ), FitbitSensorEntityDescription( key="activities/tracker/minutesFairlyActive", name="Tracker Minutes Fairly Active", - unit_type=TIME_MINUTES, + native_unit_of_measurement=UnitOfTime.MINUTES, icon="mdi:walk", + device_class=SensorDeviceClass.DURATION, ), FitbitSensorEntityDescription( key="activities/tracker/minutesLightlyActive", name="Tracker Minutes Lightly Active", - unit_type=TIME_MINUTES, + native_unit_of_measurement=UnitOfTime.MINUTES, icon="mdi:walk", + device_class=SensorDeviceClass.DURATION, ), FitbitSensorEntityDescription( key="activities/tracker/minutesSedentary", name="Tracker Minutes Sedentary", - unit_type=TIME_MINUTES, + 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", - unit_type=TIME_MINUTES, + native_unit_of_measurement=UnitOfTime.MINUTES, icon="mdi:run", + device_class=SensorDeviceClass.DURATION, ), FitbitSensorEntityDescription( key="activities/tracker/steps", name="Tracker Steps", - unit_type="steps", + native_unit_of_measurement="steps", icon="mdi:walk", ), FitbitSensorEntityDescription( key="body/bmi", name="BMI", - unit_type="BMI", + native_unit_of_measurement="BMI", icon="mdi:human", state_class=SensorStateClass.MEASUREMENT, ), FitbitSensorEntityDescription( key="body/fat", name="Body Fat", - unit_type=PERCENTAGE, + native_unit_of_measurement=PERCENTAGE, icon="mdi:human", state_class=SensorStateClass.MEASUREMENT, ), FitbitSensorEntityDescription( key="body/weight", name="Weight", - unit_type="", + unit_type="weight", icon="mdi:human", state_class=SensorStateClass.MEASUREMENT, + device_class=SensorDeviceClass.WEIGHT, ), FitbitSensorEntityDescription( key="sleep/awakeningsCount", name="Awakenings Count", - unit_type="times awaken", + native_unit_of_measurement="times awaken", icon="mdi:sleep", ), FitbitSensorEntityDescription( key="sleep/efficiency", name="Sleep Efficiency", - unit_type=PERCENTAGE, + native_unit_of_measurement=PERCENTAGE, icon="mdi:sleep", state_class=SensorStateClass.MEASUREMENT, ), FitbitSensorEntityDescription( key="sleep/minutesAfterWakeup", name="Minutes After Wakeup", - unit_type=TIME_MINUTES, + native_unit_of_measurement=UnitOfTime.MINUTES, icon="mdi:sleep", + device_class=SensorDeviceClass.DURATION, ), FitbitSensorEntityDescription( key="sleep/minutesAsleep", name="Sleep Minutes Asleep", - unit_type=TIME_MINUTES, + native_unit_of_measurement=UnitOfTime.MINUTES, icon="mdi:sleep", + device_class=SensorDeviceClass.DURATION, ), FitbitSensorEntityDescription( key="sleep/minutesAwake", name="Sleep Minutes Awake", - unit_type=TIME_MINUTES, + native_unit_of_measurement=UnitOfTime.MINUTES, icon="mdi:sleep", + device_class=SensorDeviceClass.DURATION, ), FitbitSensorEntityDescription( key="sleep/minutesToFallAsleep", name="Sleep Minutes to Fall Asleep", - unit_type=TIME_MINUTES, + native_unit_of_measurement=UnitOfTime.MINUTES, icon="mdi:sleep", + device_class=SensorDeviceClass.DURATION, ), FitbitSensorEntityDescription( key="sleep/startTime", name="Sleep Start Time", - unit_type=None, icon="mdi:clock", ), FitbitSensorEntityDescription( key="sleep/timeInBed", name="Sleep Time in Bed", - unit_type=TIME_MINUTES, + native_unit_of_measurement=UnitOfTime.MINUTES, icon="mdi:hotel", + device_class=SensorDeviceClass.DURATION, ), ) FITBIT_RESOURCE_BATTERY = FitbitSensorEntityDescription( key="devices/battery", name="Battery", - unit_type=None, icon="mdi:battery", ) @@ -276,35 +290,35 @@ FITBIT_RESOURCES_KEYS: Final[list[str]] = [ FITBIT_MEASUREMENTS: Final[dict[str, dict[str, str]]] = { "en_US": { - ATTR_DURATION: TIME_MILLISECONDS, - ATTR_DISTANCE: "mi", - ATTR_ELEVATION: LENGTH_FEET, - ATTR_HEIGHT: "in", - ATTR_WEIGHT: "lbs", - ATTR_BODY: "in", - ATTR_LIQUIDS: "fl. oz.", - ATTR_BLOOD_GLUCOSE: f"{MASS_MILLIGRAMS}/dL", + ATTR_DURATION: UnitOfTime.MILLISECONDS, + ATTR_DISTANCE: UnitOfLength.MILES, + ATTR_ELEVATION: UnitOfLength.FEET, + ATTR_HEIGHT: UnitOfLength.INCHES, + ATTR_WEIGHT: UnitOfMass.POUNDS, + ATTR_BODY: UnitOfLength.INCHES, + ATTR_LIQUIDS: UnitOfVolume.FLUID_OUNCES, + ATTR_BLOOD_GLUCOSE: f"{UnitOfMass.MILLIGRAMS}/dL", ATTR_BATTERY: "", }, "en_GB": { - ATTR_DURATION: TIME_MILLISECONDS, - ATTR_DISTANCE: "kilometers", - ATTR_ELEVATION: "meters", - ATTR_HEIGHT: "centimeters", - ATTR_WEIGHT: "stone", - ATTR_BODY: "centimeters", - ATTR_LIQUIDS: "milliliters", + ATTR_DURATION: UnitOfTime.MILLISECONDS, + ATTR_DISTANCE: UnitOfLength.KILOMETERS, + ATTR_ELEVATION: UnitOfLength.METERS, + ATTR_HEIGHT: UnitOfLength.CENTIMETERS, + ATTR_WEIGHT: UnitOfMass.STONES, + ATTR_BODY: UnitOfLength.CENTIMETERS, + ATTR_LIQUIDS: UnitOfVolume.MILLILITERS, ATTR_BLOOD_GLUCOSE: "mmol/L", ATTR_BATTERY: "", }, "metric": { - ATTR_DURATION: TIME_MILLISECONDS, - ATTR_DISTANCE: "kilometers", - ATTR_ELEVATION: "meters", - ATTR_HEIGHT: "centimeters", - ATTR_WEIGHT: MASS_KILOGRAMS, - ATTR_BODY: "centimeters", - ATTR_LIQUIDS: "milliliters", + ATTR_DURATION: UnitOfTime.MILLISECONDS, + ATTR_DISTANCE: UnitOfLength.KILOMETERS, + ATTR_ELEVATION: UnitOfLength.METERS, + ATTR_HEIGHT: UnitOfLength.CENTIMETERS, + ATTR_WEIGHT: UnitOfMass.KILOGRAMS, + ATTR_BODY: UnitOfLength.CENTIMETERS, + ATTR_LIQUIDS: UnitOfVolume.MILLILITERS, ATTR_BLOOD_GLUCOSE: "mmol/L", ATTR_BATTERY: "", }, diff --git a/homeassistant/components/fitbit/sensor.py b/homeassistant/components/fitbit/sensor.py index 78929307c02..fc0f7fca082 100644 --- a/homeassistant/components/fitbit/sensor.py +++ b/homeassistant/components/fitbit/sensor.py @@ -365,8 +365,7 @@ class FitbitSensor(SensorEntity): self._attr_name = f"{self.extra.get('deviceVersion')} Battery" self._attr_unique_id = f"{self._attr_unique_id}_{self.extra.get('id')}" - if (unit_type := description.unit_type) == "": - split_resource = description.key.rsplit("/", maxsplit=1)[-1] + if description.unit_type: try: measurement_system = FITBIT_MEASUREMENTS[self.client.system] except KeyError: @@ -374,8 +373,9 @@ class FitbitSensor(SensorEntity): measurement_system = FITBIT_MEASUREMENTS["metric"] else: measurement_system = FITBIT_MEASUREMENTS["en_US"] + split_resource = description.key.rsplit("/", maxsplit=1)[-1] unit_type = measurement_system[split_resource] - self._attr_native_unit_of_measurement = unit_type + self._attr_native_unit_of_measurement = unit_type @property def icon(self) -> str | None: