From 5e59c3fd6d749c6885b7735019203ce118411ac9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 18 May 2022 15:36:47 -0500 Subject: [PATCH] Add switch platform to Big Ass Fans (#71954) --- .coveragerc | 1 + homeassistant/components/baf/__init__.py | 2 +- homeassistant/components/baf/switch.py | 148 +++++++++++++++++++++++ 3 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 homeassistant/components/baf/switch.py diff --git a/.coveragerc b/.coveragerc index bd7aa405b94..fbe98e4594f 100644 --- a/.coveragerc +++ b/.coveragerc @@ -97,6 +97,7 @@ omit = homeassistant/components/baf/entity.py homeassistant/components/baf/fan.py homeassistant/components/baf/sensor.py + homeassistant/components/baf/switch.py homeassistant/components/baidu/tts.py homeassistant/components/balboa/__init__.py homeassistant/components/beewi_smartclim/sensor.py diff --git a/homeassistant/components/baf/__init__.py b/homeassistant/components/baf/__init__.py index f6401cbbc40..6e76014f0b7 100644 --- a/homeassistant/components/baf/__init__.py +++ b/homeassistant/components/baf/__init__.py @@ -14,7 +14,7 @@ from homeassistant.exceptions import ConfigEntryNotReady from .const import DOMAIN, QUERY_INTERVAL, RUN_TIMEOUT from .models import BAFData -PLATFORMS: list[Platform] = [Platform.FAN, Platform.SENSOR] +PLATFORMS: list[Platform] = [Platform.FAN, Platform.SENSOR, Platform.SWITCH] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: diff --git a/homeassistant/components/baf/switch.py b/homeassistant/components/baf/switch.py new file mode 100644 index 00000000000..6cefa0db65d --- /dev/null +++ b/homeassistant/components/baf/switch.py @@ -0,0 +1,148 @@ +"""Support for Big Ass Fans switch.""" +from __future__ import annotations + +from collections.abc import Callable +from dataclasses import dataclass +from typing import Any, Optional, cast + +from aiobafi6 import Device + +from homeassistant import config_entries +from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN +from .entity import BAFEntity +from .models import BAFData + + +@dataclass +class BAFSwitchDescriptionMixin: + """Required values for BAF sensors.""" + + value_fn: Callable[[Device], bool | None] + + +@dataclass +class BAFSwitchDescription( + SwitchEntityDescription, + BAFSwitchDescriptionMixin, +): + """Class describing BAF switch entities.""" + + +BASE_SWITCHES = [ + BAFSwitchDescription( + key="legacy_ir_remote_enable", + name="Legacy IR Remote", + entity_category=EntityCategory.CONFIG, + value_fn=lambda device: cast(Optional[bool], device.legacy_ir_remote_enable), + ), + BAFSwitchDescription( + key="led_indicators_enable", + name="Led Indicators", + entity_category=EntityCategory.CONFIG, + value_fn=lambda device: cast(Optional[bool], device.led_indicators_enable), + ), +] + +FAN_SWITCHES = [ + BAFSwitchDescription( + key="comfort_heat_assist_enable", + name="Auto Comfort Heat Assist", + entity_category=EntityCategory.CONFIG, + value_fn=lambda device: cast(Optional[bool], device.comfort_heat_assist_enable), + ), + BAFSwitchDescription( + key="fan_beep_enable", + name="Beep", + entity_category=EntityCategory.CONFIG, + value_fn=lambda device: cast(Optional[bool], device.fan_beep_enable), + ), + BAFSwitchDescription( + key="eco_enable", + name="Eco Mode", + entity_category=EntityCategory.CONFIG, + value_fn=lambda device: cast(Optional[bool], device.eco_enable), + ), + BAFSwitchDescription( + key="motion_sense_enable", + name="Motion Sense", + entity_category=EntityCategory.CONFIG, + value_fn=lambda device: cast(Optional[bool], device.motion_sense_enable), + ), + BAFSwitchDescription( + key="return_to_auto_enable", + name="Return to Auto", + entity_category=EntityCategory.CONFIG, + value_fn=lambda device: cast(Optional[bool], device.return_to_auto_enable), + ), + BAFSwitchDescription( + key="whoosh_enable", + name="Whoosh", + # Not a configuration switch + value_fn=lambda device: cast(Optional[bool], device.whoosh_enable), + ), +] + + +LIGHT_SWITCHES = [ + BAFSwitchDescription( + key="light_dim_to_warm_enable", + name="Dim to Warm", + entity_category=EntityCategory.CONFIG, + value_fn=lambda device: cast(Optional[bool], device.light_dim_to_warm_enable), + ), + BAFSwitchDescription( + key="light_return_to_auto_enable", + name="Light Return to Auto", + entity_category=EntityCategory.CONFIG, + value_fn=lambda device: cast( + Optional[bool], device.light_return_to_auto_enable + ), + ), +] + + +async def async_setup_entry( + hass: HomeAssistant, + entry: config_entries.ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up BAF fan switches.""" + data: BAFData = hass.data[DOMAIN][entry.entry_id] + device = data.device + descriptions: list[BAFSwitchDescription] = [] + descriptions.extend(BASE_SWITCHES) + if device.has_fan: + descriptions.extend(FAN_SWITCHES) + if device.has_light: + descriptions.extend(LIGHT_SWITCHES) + async_add_entities(BAFSwitch(device, description) for description in descriptions) + + +class BAFSwitch(BAFEntity, SwitchEntity): + """BAF switch component.""" + + entity_description: BAFSwitchDescription + + def __init__(self, device: Device, description: BAFSwitchDescription) -> None: + """Initialize the entity.""" + self.entity_description = description + super().__init__(device, f"{device.name} {description.name}") + self._attr_unique_id = f"{self._device.mac_address}-{description.key}" + + @callback + def _async_update_attrs(self) -> None: + """Update attrs from device.""" + self._attr_is_on = self.entity_description.value_fn(self._device) + + async def async_turn_on(self, **kwargs: Any) -> None: + """Turn on the switch.""" + setattr(self._device, self.entity_description.key, True) + + async def async_turn_off(self, **kwargs: Any) -> None: + """Turn off the switch.""" + setattr(self._device, self.entity_description.key, False)