From 8bae7a45a509fe198af9b7c600a7dbe46488ab4c Mon Sep 17 00:00:00 2001 From: Markus Jankowski Date: Wed, 17 Jul 2019 03:05:58 +0200 Subject: [PATCH] Add HMIP-FCI / HMIP-FBL / HmIP-BBL (#25188) --- .../homematicip_cloud/binary_sensor.py | 36 ++++++++++++---- .../components/homematicip_cloud/cover.py | 41 +++++++++++++++++-- 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/homematicip_cloud/binary_sensor.py b/homeassistant/components/homematicip_cloud/binary_sensor.py index ba30591dc6d..696b00883ae 100644 --- a/homeassistant/components/homematicip_cloud/binary_sensor.py +++ b/homeassistant/components/homematicip_cloud/binary_sensor.py @@ -2,19 +2,20 @@ import logging from homematicip.aio.device import ( - AsyncDevice, AsyncMotionDetectorIndoor, AsyncMotionDetectorOutdoor, - AsyncMotionDetectorPushButton, AsyncPresenceDetectorIndoor, - AsyncRotaryHandleSensor, AsyncShutterContact, AsyncSmokeDetector, - AsyncWaterSensor, AsyncWeatherSensor, AsyncWeatherSensorPlus, - AsyncWeatherSensorPro) + AsyncDevice, AsyncFullFlushContactInterface, AsyncMotionDetectorIndoor, + AsyncMotionDetectorOutdoor, AsyncMotionDetectorPushButton, + AsyncPresenceDetectorIndoor, AsyncRotaryHandleSensor, AsyncShutterContact, + AsyncSmokeDetector, AsyncWaterSensor, AsyncWeatherSensor, + AsyncWeatherSensorPlus, AsyncWeatherSensorPro) from homematicip.aio.group import AsyncSecurityGroup, AsyncSecurityZoneGroup from homematicip.aio.home import AsyncHome from homematicip.base.enums import SmokeDetectorAlarmType, WindowState from homeassistant.components.binary_sensor import ( DEVICE_CLASS_BATTERY, DEVICE_CLASS_DOOR, DEVICE_CLASS_LIGHT, - DEVICE_CLASS_MOISTURE, DEVICE_CLASS_MOTION, DEVICE_CLASS_PRESENCE, - DEVICE_CLASS_SAFETY, DEVICE_CLASS_SMOKE, BinarySensorDevice) + DEVICE_CLASS_MOISTURE, DEVICE_CLASS_MOTION, DEVICE_CLASS_OPENING, + DEVICE_CLASS_PRESENCE, DEVICE_CLASS_SAFETY, DEVICE_CLASS_SMOKE, + BinarySensorDevice) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @@ -46,6 +47,8 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home devices = [] for device in home.devices: + if isinstance(device, AsyncFullFlushContactInterface): + devices.append(HomematicipContactInterface(home, device)) if isinstance(device, (AsyncShutterContact, AsyncRotaryHandleSensor)): devices.append(HomematicipShutterContact(home, device)) if isinstance(device, (AsyncMotionDetectorIndoor, @@ -78,6 +81,25 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities(devices) +class HomematicipContactInterface(HomematicipGenericDevice, + BinarySensorDevice): + """Representation of a HomematicIP Cloud contact interface.""" + + @property + def device_class(self) -> str: + """Return the class of this sensor.""" + return DEVICE_CLASS_OPENING + + @property + def is_on(self) -> bool: + """Return true if the contact interface is on/open.""" + if hasattr(self._device, 'sabotage') and self._device.sabotage: + return True + if self._device.windowState is None: + return None + return self._device.windowState != WindowState.CLOSED + + class HomematicipShutterContact(HomematicipGenericDevice, BinarySensorDevice): """Representation of a HomematicIP Cloud shutter contact.""" diff --git a/homeassistant/components/homematicip_cloud/cover.py b/homeassistant/components/homematicip_cloud/cover.py index fc75d78119d..ca102b626c7 100644 --- a/homeassistant/components/homematicip_cloud/cover.py +++ b/homeassistant/components/homematicip_cloud/cover.py @@ -2,9 +2,10 @@ import logging from typing import Optional -from homematicip.aio.device import AsyncFullFlushShutter +from homematicip.aio.device import AsyncFullFlushBlind, AsyncFullFlushShutter -from homeassistant.components.cover import ATTR_POSITION, CoverDevice +from homeassistant.components.cover import ( + ATTR_POSITION, ATTR_TILT_POSITION, CoverDevice) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @@ -14,6 +15,8 @@ _LOGGER = logging.getLogger(__name__) HMIP_COVER_OPEN = 0 HMIP_COVER_CLOSED = 1 +HMIP_SLATS_OPEN = 0 +HMIP_SLATS_CLOSED = 1 async def async_setup_platform( @@ -28,7 +31,9 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home devices = [] for device in home.devices: - if isinstance(device, AsyncFullFlushShutter): + if isinstance(device, AsyncFullFlushBlind): + devices.append(HomematicipCoverSlats(home, device)) + elif isinstance(device, AsyncFullFlushShutter): devices.append(HomematicipCoverShutter(home, device)) if devices: @@ -36,7 +41,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, class HomematicipCoverShutter(HomematicipGenericDevice, CoverDevice): - """Representation of a HomematicIP Cloud cover device.""" + """Representation of a HomematicIP Cloud cover shutter device.""" @property def current_cover_position(self) -> int: @@ -68,3 +73,31 @@ class HomematicipCoverShutter(HomematicipGenericDevice, CoverDevice): async def async_stop_cover(self, **kwargs): """Stop the device if in motion.""" await self._device.set_shutter_stop() + + +class HomematicipCoverSlats(HomematicipCoverShutter, CoverDevice): + """Representation of a HomematicIP Cloud cover slats device.""" + + @property + def current_cover_tilt_position(self) -> int: + """Return current tilt position of cover.""" + return int((1 - self._device.slatsLevel) * 100) + + async def async_set_cover_tilt_position(self, **kwargs): + """Move the cover to a specific tilt position.""" + position = kwargs[ATTR_TILT_POSITION] + # HmIP slats is closed:1 -> open:0 + level = 1 - position / 100.0 + await self._device.set_slats_level(level) + + async def async_open_cover_tilt(self, **kwargs): + """Open the slats.""" + await self._device.set_slats_level(HMIP_SLATS_OPEN) + + async def async_close_cover_tilt(self, **kwargs): + """Close the slats.""" + await self._device.set_slats_level(HMIP_SLATS_CLOSED) + + async def async_stop_cover_tilt(self, **kwargs): + """Stop the device if in motion.""" + await self._device.set_shutter_stop()