From 34d4eb7c151e962fdcb5821d37598353c7e18436 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Wed, 11 May 2022 07:12:44 -0400 Subject: [PATCH] Improve eight sleep code quality and fix bug (#71622) --- .../components/eight_sleep/__init__.py | 2 - .../components/eight_sleep/binary_sensor.py | 3 +- .../components/eight_sleep/sensor.py | 100 ++++++------------ 3 files changed, 33 insertions(+), 72 deletions(-) diff --git a/homeassistant/components/eight_sleep/__init__.py b/homeassistant/components/eight_sleep/__init__.py index eece6e69ed5..e986a7f6d60 100644 --- a/homeassistant/components/eight_sleep/__init__.py +++ b/homeassistant/components/eight_sleep/__init__.py @@ -156,14 +156,12 @@ class EightSleepBaseEntity(CoordinatorEntity[DataUpdateCoordinator]): eight: EightSleep, user_id: str | None, sensor: str, - units: str | None = None, ) -> None: """Initialize the data object.""" super().__init__(coordinator) self._eight = eight self._user_id = user_id self._sensor = sensor - self._units = units self._user_obj: EightUser | None = None if self._user_id: self._user_obj = self._eight.users[user_id] diff --git a/homeassistant/components/eight_sleep/binary_sensor.py b/homeassistant/components/eight_sleep/binary_sensor.py index a63389ef3f9..868a5177cfe 100644 --- a/homeassistant/components/eight_sleep/binary_sensor.py +++ b/homeassistant/components/eight_sleep/binary_sensor.py @@ -45,6 +45,8 @@ async def async_setup_platform( class EightHeatSensor(EightSleepBaseEntity, BinarySensorEntity): """Representation of a Eight Sleep heat-based sensor.""" + _attr_device_class = BinarySensorDeviceClass.OCCUPANCY + def __init__( self, coordinator: DataUpdateCoordinator, @@ -54,7 +56,6 @@ class EightHeatSensor(EightSleepBaseEntity, BinarySensorEntity): ) -> None: """Initialize the sensor.""" super().__init__(coordinator, eight, user_id, sensor) - self._attr_device_class = BinarySensorDeviceClass.OCCUPANCY assert self._user_obj _LOGGER.debug( "Presence Sensor: %s, Side: %s, User: %s", diff --git a/homeassistant/components/eight_sleep/sensor.py b/homeassistant/components/eight_sleep/sensor.py index 145292d6728..b405617e276 100644 --- a/homeassistant/components/eight_sleep/sensor.py +++ b/homeassistant/components/eight_sleep/sensor.py @@ -6,8 +6,8 @@ from typing import Any from pyeight.eight import EightSleep -from homeassistant.components.sensor import SensorEntity -from homeassistant.const import PERCENTAGE, TEMP_CELSIUS, TEMP_FAHRENHEIT +from homeassistant.components.sensor import SensorDeviceClass, SensorEntity +from homeassistant.const import PERCENTAGE, TEMP_CELSIUS from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -68,24 +68,19 @@ async def async_setup_platform( heat_coordinator: DataUpdateCoordinator = hass.data[DOMAIN][DATA_HEAT] user_coordinator: DataUpdateCoordinator = hass.data[DOMAIN][DATA_USER] - if hass.config.units.is_metric: - units = "si" - else: - units = "us" - all_sensors: list[SensorEntity] = [] for obj in eight.users.values(): for sensor in EIGHT_USER_SENSORS: all_sensors.append( - EightUserSensor(user_coordinator, eight, obj.userid, sensor, units) + EightUserSensor(user_coordinator, eight, obj.userid, sensor) ) for sensor in EIGHT_HEAT_SENSORS: all_sensors.append( EightHeatSensor(heat_coordinator, eight, obj.userid, sensor) ) for sensor in EIGHT_ROOM_SENSORS: - all_sensors.append(EightRoomSensor(user_coordinator, eight, sensor, units)) + all_sensors.append(EightRoomSensor(user_coordinator, eight, sensor)) async_add_entities(all_sensors) @@ -93,6 +88,8 @@ async def async_setup_platform( class EightHeatSensor(EightSleepBaseEntity, SensorEntity): """Representation of an eight sleep heat-based sensor.""" + _attr_native_unit_of_measurement = PERCENTAGE + def __init__( self, coordinator: DataUpdateCoordinator, @@ -102,7 +99,6 @@ class EightHeatSensor(EightSleepBaseEntity, SensorEntity): ) -> None: """Initialize the sensor.""" super().__init__(coordinator, eight, user_id, sensor) - self._attr_native_unit_of_measurement = PERCENTAGE assert self._user_obj _LOGGER.debug( @@ -139,6 +135,13 @@ def _get_breakdown_percent( return 0 +def _get_rounded_value(attr: dict[str, Any], key: str) -> int | float | None: + """Get rounded value for given key.""" + if (val := attr.get(key)) is None: + return None + return round(val, 2) + + class EightUserSensor(EightSleepBaseEntity, SensorEntity): """Representation of an eight sleep user-based sensor.""" @@ -148,14 +151,17 @@ class EightUserSensor(EightSleepBaseEntity, SensorEntity): eight: EightSleep, user_id: str, sensor: str, - units: str, ) -> None: """Initialize the sensor.""" - super().__init__(coordinator, eight, user_id, sensor, units) + super().__init__(coordinator, eight, user_id, sensor) assert self._user_obj if self._sensor == "bed_temperature": self._attr_icon = "mdi:thermometer" + self._attr_device_class = SensorDeviceClass.TEMPERATURE + self._attr_native_unit_of_measurement = TEMP_CELSIUS + elif self._sensor in ("current_sleep", "last_sleep", "current_sleep_fitness"): + self._attr_native_unit_of_measurement = "Score" _LOGGER.debug( "User Sensor: %s, Side: %s, User: %s", @@ -179,41 +185,13 @@ class EightUserSensor(EightSleepBaseEntity, SensorEntity): return self._user_obj.last_sleep_score if self._sensor == "bed_temperature": - temp = self._user_obj.current_values["bed_temp"] - try: - if self._units == "si": - return round(temp, 2) - return round((temp * 1.8) + 32, 2) - except TypeError: - return None + return self._user_obj.current_values["bed_temp"] if self._sensor == "sleep_stage": return self._user_obj.current_values["stage"] return None - @property - def native_unit_of_measurement(self) -> str | None: - """Return the unit the value is expressed in.""" - if self._sensor in ("current_sleep", "last_sleep", "current_sleep_fitness"): - return "Score" - if self._sensor == "bed_temperature": - if self._units == "si": - return TEMP_CELSIUS - return TEMP_FAHRENHEIT - return None - - def _get_rounded_value( - self, attr: dict[str, Any], key: str, use_units: bool = True - ) -> int | float | None: - """Get rounded value based on units for given key.""" - try: - if self._units == "si" or not use_units: - return round(attr["room_temp"], 2) - return round((attr["room_temp"] * 1.8) + 32, 2) - except TypeError: - return None - @property def extra_state_attributes(self) -> dict[str, Any] | None: """Return device state attributes.""" @@ -255,26 +233,18 @@ class EightUserSensor(EightSleepBaseEntity, SensorEntity): ) state_attr[ATTR_REM_PERC] = _get_breakdown_percent(attr, "rem", sleep_time) - room_temp = self._get_rounded_value(attr, "room_temp") - bed_temp = self._get_rounded_value(attr, "bed_temp") + room_temp = _get_rounded_value(attr, "room_temp") + bed_temp = _get_rounded_value(attr, "bed_temp") if "current" in self._sensor: - state_attr[ATTR_RESP_RATE] = self._get_rounded_value( - attr, "resp_rate", False - ) - state_attr[ATTR_HEART_RATE] = self._get_rounded_value( - attr, "heart_rate", False - ) + state_attr[ATTR_RESP_RATE] = _get_rounded_value(attr, "resp_rate") + state_attr[ATTR_HEART_RATE] = _get_rounded_value(attr, "heart_rate") state_attr[ATTR_SLEEP_STAGE] = attr["stage"] state_attr[ATTR_ROOM_TEMP] = room_temp state_attr[ATTR_BED_TEMP] = bed_temp elif "last" in self._sensor: - state_attr[ATTR_AVG_RESP_RATE] = self._get_rounded_value( - attr, "resp_rate", False - ) - state_attr[ATTR_AVG_HEART_RATE] = self._get_rounded_value( - attr, "heart_rate", False - ) + state_attr[ATTR_AVG_RESP_RATE] = _get_rounded_value(attr, "resp_rate") + state_attr[ATTR_AVG_HEART_RATE] = _get_rounded_value(attr, "heart_rate") state_attr[ATTR_AVG_ROOM_TEMP] = room_temp state_attr[ATTR_AVG_BED_TEMP] = bed_temp @@ -284,28 +254,20 @@ class EightUserSensor(EightSleepBaseEntity, SensorEntity): class EightRoomSensor(EightSleepBaseEntity, SensorEntity): """Representation of an eight sleep room sensor.""" + _attr_icon = "mdi:thermometer" + _attr_device_class = SensorDeviceClass.TEMPERATURE + _attr_native_unit_of_measurement = TEMP_CELSIUS + def __init__( self, coordinator: DataUpdateCoordinator, eight: EightSleep, sensor: str, - units: str, ) -> None: """Initialize the sensor.""" - super().__init__(coordinator, eight, None, sensor, units) - - self._attr_icon = "mdi:thermometer" - self._attr_native_unit_of_measurement: str = ( - TEMP_CELSIUS if self._units == "si" else TEMP_FAHRENHEIT - ) + super().__init__(coordinator, eight, None, sensor) @property def native_value(self) -> int | float | None: """Return the state of the sensor.""" - temp = self._eight.room_temperature() - try: - if self._units == "si": - return round(temp, 2) - return round((temp * 1.8) + 32, 2) - except TypeError: - return None + return self._eight.room_temperature()