From b064a2412397ebc86e6bb3c13e5e44d2140fed24 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 13 Jan 2022 17:04:52 -1000 Subject: [PATCH] Add select platform to senseme (#64086) Co-authored-by: Martin Hjelmare --- homeassistant/components/senseme/const.py | 8 +- homeassistant/components/senseme/fan.py | 8 -- .../components/senseme/manifest.json | 4 +- homeassistant/components/senseme/select.py | 90 +++++++++++++++++++ requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 6 files changed, 101 insertions(+), 13 deletions(-) create mode 100644 homeassistant/components/senseme/select.py diff --git a/homeassistant/components/senseme/const.py b/homeassistant/components/senseme/const.py index eb7bc64a747..5660fc1d177 100644 --- a/homeassistant/components/senseme/const.py +++ b/homeassistant/components/senseme/const.py @@ -20,4 +20,10 @@ PRESET_MODE_WHOOSH = "Whoosh" SENSEME_DIRECTION_FORWARD = "FWD" SENSEME_DIRECTION_REVERSE = "REV" -PLATFORMS = [Platform.BINARY_SENSOR, Platform.FAN, Platform.SWITCH] +PLATFORMS = [ + Platform.BINARY_SENSOR, + Platform.FAN, + Platform.LIGHT, + Platform.SELECT, + Platform.SWITCH, +] diff --git a/homeassistant/components/senseme/fan.py b/homeassistant/components/senseme/fan.py index 71b13ff4a17..8f826536d66 100644 --- a/homeassistant/components/senseme/fan.py +++ b/homeassistant/components/senseme/fan.py @@ -76,14 +76,6 @@ class HASensemeFan(SensemeEntity, FanEntity): self._attr_preset_mode = whoosh if whoosh else None super()._async_update_attrs() - @property - def extra_state_attributes(self) -> dict: - """Get the current device state attributes.""" - return { - "auto_comfort": self._device.fan_autocomfort.capitalize(), - "smartmode": self._device.fan_smartmode.capitalize(), - } - async def async_set_percentage(self, percentage: int) -> None: """Set the speed of the fan, as a percentage.""" self._device.fan_speed = math.ceil( diff --git a/homeassistant/components/senseme/manifest.json b/homeassistant/components/senseme/manifest.json index a5ac179d9a0..03094265ffd 100644 --- a/homeassistant/components/senseme/manifest.json +++ b/homeassistant/components/senseme/manifest.json @@ -4,10 +4,10 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/senseme", "requirements": [ - "aiosenseme==0.5.5" + "aiosenseme==0.6.0" ], "codeowners": [ "@mikelawrence", "@bdraco" ], "iot_class": "local_push" -} \ No newline at end of file +} diff --git a/homeassistant/components/senseme/select.py b/homeassistant/components/senseme/select.py new file mode 100644 index 00000000000..1fedc7f75d4 --- /dev/null +++ b/homeassistant/components/senseme/select.py @@ -0,0 +1,90 @@ +"""Support for Big Ass Fans SenseME selects.""" +from __future__ import annotations + +from collections.abc import Callable +from dataclasses import dataclass + +from aiosenseme import SensemeFan +from aiosenseme.device import SensemeDevice + +from homeassistant import config_entries +from homeassistant.components.select import SelectEntity, SelectEntityDescription +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN +from .entity import SensemeEntity + +SMART_MODE_TO_HASS = { + "OFF": "Off", + "COOLING": "Cooling", + "HEATING": "Heating", + "FOLLOWTSTAT": "Follow Thermostat", +} +HASS_TO_SMART_MODE = {v: k for k, v in SMART_MODE_TO_HASS.items()} + + +@dataclass +class SenseMESelectEntityDescriptionMixin: + """Mixin for required keys.""" + + value_fn: Callable[[SensemeFan], str] + set_fn: Callable[[SensemeFan, str], None] + + +@dataclass +class SenseMESelectEntityDescription( + SelectEntityDescription, SenseMESelectEntityDescriptionMixin +): + """Describes SenseME select entity.""" + + +def _set_smart_mode(device: SensemeDevice, value: str) -> None: + device.fan_smartmode = HASS_TO_SMART_MODE[value] + + +FAN_SELECTS = [ + SenseMESelectEntityDescription( + key="smart_mode", + name="Smart Mode", + value_fn=lambda device: SMART_MODE_TO_HASS[device.fan_smartmode], + set_fn=_set_smart_mode, + ), +] + + +async def async_setup_entry( + hass: HomeAssistant, + entry: config_entries.ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up SenseME fan selects.""" + device = hass.data[DOMAIN][entry.entry_id] + if device.is_fan: + async_add_entities( + HASensemeSelect(device, description) for description in FAN_SELECTS + ) + + +class HASensemeSelect(SensemeEntity, SelectEntity): + """SenseME select component.""" + + entity_description: SenseMESelectEntityDescription + _attr_options = list(SMART_MODE_TO_HASS.values()) + + def __init__( + self, device: SensemeFan, description: SenseMESelectEntityDescription + ) -> None: + """Initialize the entity.""" + self.entity_description = description + super().__init__(device, f"{device.name} {description.name}") + self._attr_unique_id = f"{self._device.uuid}-{description.key}" + + @property + def current_option(self) -> str: + """Return the current value.""" + return self.entity_description.value_fn(self._device) + + async def async_select_option(self, option: str) -> None: + """Set the option.""" + self.entity_description.set_fn(self._device, option) diff --git a/requirements_all.txt b/requirements_all.txt index 954ac7802ee..767e005a115 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -254,7 +254,7 @@ aiorecollect==1.0.8 aioridwell==2021.12.2 # homeassistant.components.senseme -aiosenseme==0.5.5 +aiosenseme==0.6.0 # homeassistant.components.shelly aioshelly==1.0.7 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index b7adbb40e20..6a44c0b80be 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -186,7 +186,7 @@ aiorecollect==1.0.8 aioridwell==2021.12.2 # homeassistant.components.senseme -aiosenseme==0.5.5 +aiosenseme==0.6.0 # homeassistant.components.shelly aioshelly==1.0.7