Implement Switchbot Blind Tilt (#86591)

Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: BelowAverageDeveloper <90269575+BelowAverageDev@users.noreply.github.com>
This commit is contained in:
Jesse Hills 2023-02-17 16:06:02 +13:00 committed by GitHub
parent 6cab27f378
commit a26d41f260
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 94 additions and 4 deletions

View File

@ -50,6 +50,11 @@ PLATFORMS_BY_TYPE = {
Platform.LOCK,
Platform.SENSOR,
],
SupportedModels.BLIND_TILT.value: [
Platform.COVER,
Platform.BINARY_SENSOR,
Platform.SENSOR,
],
}
CLASS_BY_DEVICE = {
SupportedModels.CEILING_LIGHT.value: switchbot.SwitchbotCeilingLight,
@ -60,6 +65,7 @@ CLASS_BY_DEVICE = {
SupportedModels.LIGHT_STRIP.value: switchbot.SwitchbotLightStrip,
SupportedModels.HUMIDIFIER.value: switchbot.SwitchbotHumidifier,
SupportedModels.LOCK.value: switchbot.SwitchbotLock,
SupportedModels.BLIND_TILT.value: switchbot.SwitchbotBlindTilt,
}

View File

@ -25,6 +25,7 @@ class SupportedModels(StrEnum):
MOTION = "motion"
HUMIDIFIER = "humidifier"
LOCK = "lock"
BLIND_TILT = "blind_tilt"
CONNECTABLE_SUPPORTED_MODEL_TYPES = {
@ -36,6 +37,7 @@ CONNECTABLE_SUPPORTED_MODEL_TYPES = {
SwitchbotModel.CEILING_LIGHT: SupportedModels.CEILING_LIGHT,
SwitchbotModel.HUMIDIFIER: SupportedModels.HUMIDIFIER,
SwitchbotModel.LOCK: SupportedModels.LOCK,
SwitchbotModel.BLIND_TILT: SupportedModels.BLIND_TILT,
}
NON_CONNECTABLE_SUPPORTED_MODEL_TYPES = {

View File

@ -8,7 +8,9 @@ import switchbot
from homeassistant.components.cover import (
ATTR_CURRENT_POSITION,
ATTR_CURRENT_TILT_POSITION,
ATTR_POSITION,
ATTR_TILT_POSITION,
CoverDeviceClass,
CoverEntity,
CoverEntityFeature,
@ -32,7 +34,10 @@ async def async_setup_entry(
) -> None:
"""Set up Switchbot curtain based on a config entry."""
coordinator: SwitchbotDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
async_add_entities([SwitchBotCurtainEntity(coordinator)])
if isinstance(coordinator.device, switchbot.SwitchbotBlindTilt):
async_add_entities([SwitchBotBlindTiltEntity(coordinator)])
else:
async_add_entities([SwitchBotCurtainEntity(coordinator)])
class SwitchBotCurtainEntity(SwitchbotEntity, CoverEntity, RestoreEntity):
@ -102,3 +107,80 @@ class SwitchBotCurtainEntity(SwitchbotEntity, CoverEntity, RestoreEntity):
self._attr_is_closed = self.parsed_data["position"] <= 20
self._attr_is_opening = self.parsed_data["inMotion"]
self.async_write_ha_state()
class SwitchBotBlindTiltEntity(SwitchbotEntity, CoverEntity, RestoreEntity):
"""Representation of a Switchbot."""
_device: switchbot.SwitchbotBlindTilt
_attr_device_class = CoverDeviceClass.BLIND
_attr_supported_features = (
CoverEntityFeature.OPEN_TILT
| CoverEntityFeature.CLOSE_TILT
| CoverEntityFeature.STOP_TILT
| CoverEntityFeature.SET_TILT_POSITION
)
CLOSED_UP_THRESHOLD = 80
CLOSED_DOWN_THRESHOLD = 20
def __init__(self, coordinator: SwitchbotDataUpdateCoordinator) -> None:
"""Initialize the Switchbot."""
super().__init__(coordinator)
self._attr_is_closed = None
async def async_added_to_hass(self) -> None:
"""Run when entity about to be added."""
await super().async_added_to_hass()
last_state = await self.async_get_last_state()
if not last_state or ATTR_CURRENT_TILT_POSITION not in last_state.attributes:
return
self._attr_current_cover_tilt_position = last_state.attributes.get(
ATTR_CURRENT_TILT_POSITION
)
self._last_run_success = last_state.attributes.get("last_run_success")
if (_tilt := self._attr_current_cover_position) is not None:
self._attr_is_closed = (_tilt < self.CLOSED_DOWN_THRESHOLD) or (
_tilt > self.CLOSED_UP_THRESHOLD
)
async def async_open_cover_tilt(self, **kwargs: Any) -> None:
"""Open the tilt."""
_LOGGER.debug("Switchbot to open blind tilt %s", self._address)
self._last_run_success = bool(await self._device.open())
self.async_write_ha_state()
async def async_close_cover_tilt(self, **kwargs: Any) -> None:
"""Close the tilt."""
_LOGGER.debug("Switchbot to close the blind tilt %s", self._address)
self._last_run_success = bool(await self._device.close())
self.async_write_ha_state()
async def async_stop_cover_tilt(self, **kwargs: Any) -> None:
"""Stop the moving of this device."""
_LOGGER.debug("Switchbot to stop %s", self._address)
self._last_run_success = bool(await self._device.stop())
self.async_write_ha_state()
async def async_set_cover_tilt_position(self, **kwargs: Any) -> None:
"""Move the cover tilt to a specific position."""
position = kwargs.get(ATTR_TILT_POSITION)
_LOGGER.debug("Switchbot to move at %d %s", position, self._address)
self._last_run_success = bool(await self._device.set_position(position))
self.async_write_ha_state()
@callback
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
_tilt = self.parsed_data["tilt"]
self._attr_current_cover_tilt_position = _tilt
self._attr_is_closed = (_tilt < self.CLOSED_DOWN_THRESHOLD) or (
_tilt > self.CLOSED_UP_THRESHOLD
)
self._attr_is_opening = self.parsed_data["motionDirection"]["opening"]
self._attr_is_closing = self.parsed_data["motionDirection"]["closing"]
self.async_write_ha_state()

View File

@ -40,5 +40,5 @@
"documentation": "https://www.home-assistant.io/integrations/switchbot",
"iot_class": "local_push",
"loggers": ["switchbot"],
"requirements": ["PySwitchbot==0.36.4"]
"requirements": ["PySwitchbot==0.37.1"]
}

View File

@ -40,7 +40,7 @@ PyRMVtransport==0.3.3
PySocks==1.7.1
# homeassistant.components.switchbot
PySwitchbot==0.36.4
PySwitchbot==0.37.1
# homeassistant.components.transport_nsw
PyTransportNSW==0.1.1

View File

@ -36,7 +36,7 @@ PyRMVtransport==0.3.3
PySocks==1.7.1
# homeassistant.components.switchbot
PySwitchbot==0.36.4
PySwitchbot==0.37.1
# homeassistant.components.transport_nsw
PyTransportNSW==0.1.1