From 5b6361080c00a94fbe5ea235d9555fe39ca2b491 Mon Sep 17 00:00:00 2001 From: Federico D'Amico <48856240+FedDam@users.noreply.github.com> Date: Fri, 22 Mar 2024 14:31:09 +0100 Subject: [PATCH] Add cover platform to microBees (#111135) --- .coveragerc | 1 + homeassistant/components/microbees/const.py | 1 + homeassistant/components/microbees/cover.py | 116 ++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 homeassistant/components/microbees/cover.py diff --git a/.coveragerc b/.coveragerc index f7f619a1756..c58601b2245 100644 --- a/.coveragerc +++ b/.coveragerc @@ -780,6 +780,7 @@ omit = homeassistant/components/microbees/button.py homeassistant/components/microbees/const.py homeassistant/components/microbees/coordinator.py + homeassistant/components/microbees/cover.py homeassistant/components/microbees/entity.py homeassistant/components/microbees/light.py homeassistant/components/microbees/sensor.py diff --git a/homeassistant/components/microbees/const.py b/homeassistant/components/microbees/const.py index 869b4e59a89..ab8637f0f75 100644 --- a/homeassistant/components/microbees/const.py +++ b/homeassistant/components/microbees/const.py @@ -8,6 +8,7 @@ OAUTH2_TOKEN = "https://dev.microbees.com/oauth/token" PLATFORMS = [ Platform.BINARY_SENSOR, Platform.BUTTON, + Platform.COVER, Platform.LIGHT, Platform.SENSOR, Platform.SWITCH, diff --git a/homeassistant/components/microbees/cover.py b/homeassistant/components/microbees/cover.py new file mode 100644 index 00000000000..5caf57403de --- /dev/null +++ b/homeassistant/components/microbees/cover.py @@ -0,0 +1,116 @@ +"""Cover integration microBees.""" +from typing import Any + +from microBeesPy import Actuator + +from homeassistant.components.cover import ( + CoverDeviceClass, + CoverEntity, + CoverEntityFeature, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError +from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.event import async_call_later + +from .const import DOMAIN +from .coordinator import MicroBeesUpdateCoordinator +from .entity import MicroBeesEntity + + +async def async_setup_entry( + hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback +) -> None: + """Set up the microBees cover platform.""" + coordinator: MicroBeesUpdateCoordinator = hass.data[DOMAIN][ + entry.entry_id + ].coordinator + + async_add_entities( + MBCover( + coordinator, + bee_id, + next(filter(lambda x: x.deviceID == 551, bee.actuators)).id, + next(filter(lambda x: x.deviceID == 552, bee.actuators)).id, + ) + for bee_id, bee in coordinator.data.bees.items() + if bee.productID == 47 + ) + + +class MBCover(MicroBeesEntity, CoverEntity): + """Representation of a microBees cover.""" + + _attr_device_class = CoverDeviceClass.SHUTTER + _attr_supported_features = ( + CoverEntityFeature.OPEN | CoverEntityFeature.STOP | CoverEntityFeature.CLOSE + ) + + def __init__(self, coordinator, bee_id, actuator_up_id, actuator_down_id) -> None: + """Initialize the microBees cover.""" + super().__init__(coordinator, bee_id) + self.actuator_up_id = actuator_up_id + self.actuator_down_id = actuator_down_id + self._attr_is_closed = None + + @property + def name(self) -> str: + """Name of the cover.""" + return self.bee.name + + @property + def actuator_up(self) -> Actuator: + """Return the rolling up actuator.""" + return self.coordinator.data.actuators[self.actuator_up_id] + + @property + def actuator_down(self) -> Actuator: + """Return the rolling down actuator.""" + return self.coordinator.data.actuators[self.actuator_down_id] + + def _reset_open_close(self, *_: Any) -> None: + """Reset the opening and closing state.""" + self._attr_is_opening = False + self._attr_is_closing = False + self.async_write_ha_state() + + async def async_open_cover(self, **kwargs: Any) -> None: + """Open the cover.""" + sendCommand = await self.coordinator.microbees.sendCommand( + self.actuator_up_id, + self.actuator_up.configuration.actuator_timing * 1000, + ) + + if not sendCommand: + raise HomeAssistantError(f"Failed to open {self.name}") + + self._attr_is_opening = True + async_call_later( + self.hass, + self.actuator_down.configuration.actuator_timing, + self._reset_open_close, + ) + + async def async_close_cover(self, **kwargs: Any) -> None: + """Close the cover.""" + sendCommand = await self.coordinator.microbees.sendCommand( + self.actuator_down_id, + self.actuator_down.configuration.actuator_timing * 1000, + ) + if not sendCommand: + raise HomeAssistantError(f"Failed to close {self.name}") + + self._attr_is_closing = True + async_call_later( + self.hass, + self.actuator_down.configuration.actuator_timing, + self._reset_open_close, + ) + + async def async_stop_cover(self, **kwargs: Any) -> None: + """Stop the cover.""" + if self.is_opening: + await self.coordinator.microbees.sendCommand(self.actuator_up_id, 0) + if self.is_closing: + await self.coordinator.microbees.sendCommand(self.actuator_down_id, 0)