diff --git a/homeassistant/components/cover/deconz.py b/homeassistant/components/cover/deconz.py index 9fe65596336..89b29aa10a5 100644 --- a/homeassistant/components/cover/deconz.py +++ b/homeassistant/components/cover/deconz.py @@ -5,10 +5,10 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/cover.deconz/ """ from homeassistant.components.deconz.const import ( - COVER_TYPES, DOMAIN as DATA_DECONZ, DATA_DECONZ_ID, DATA_DECONZ_UNSUB, - DECONZ_DOMAIN) + COVER_TYPES, DAMPERS, DOMAIN as DATA_DECONZ, DATA_DECONZ_ID, + DATA_DECONZ_UNSUB, DECONZ_DOMAIN, WINDOW_COVERS) from homeassistant.components.cover import ( - ATTR_POSITION, CoverDevice, SUPPORT_CLOSE, SUPPORT_OPEN, + ATTR_POSITION, CoverDevice, SUPPORT_CLOSE, SUPPORT_OPEN, SUPPORT_STOP, SUPPORT_SET_POSITION) from homeassistant.core import callback from homeassistant.helpers.device_registry import CONNECTION_ZIGBEE @@ -16,6 +16,8 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect DEPENDENCIES = ['deconz'] +ZIGBEE_SPEC = ['lumi.curtain'] + async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): @@ -34,7 +36,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities): entities = [] for light in lights: if light.type in COVER_TYPES: - entities.append(DeconzCover(light)) + if light.modelid in ZIGBEE_SPEC: + entities.append(DeconzCoverZigbeeSpec(light)) + else: + entities.append(DeconzCover(light)) async_add_entities(entities, True) hass.data[DATA_DECONZ_UNSUB].append( @@ -49,7 +54,10 @@ class DeconzCover(CoverDevice): def __init__(self, cover): """Set up cover and add update callback to get data from websocket.""" self._cover = cover - self._features = SUPPORT_OPEN | SUPPORT_CLOSE | SUPPORT_SET_POSITION + self._features = SUPPORT_OPEN + self._features |= SUPPORT_CLOSE + self._features |= SUPPORT_STOP + self._features |= SUPPORT_SET_POSITION async def async_added_to_hass(self): """Subscribe to covers events.""" @@ -91,7 +99,11 @@ class DeconzCover(CoverDevice): @property def device_class(self): """Return the class of the cover.""" - return 'damper' + if self._cover.type in DAMPERS: + return 'damper' + if self._cover.type in WINDOW_COVERS: + return 'window' + return None @property def supported_features(self): @@ -127,6 +139,11 @@ class DeconzCover(CoverDevice): data = {ATTR_POSITION: 0} await self.async_set_cover_position(**data) + async def async_stop_cover(self, **kwargs): + """Stop cover.""" + data = {'bri_inc': 0} + await self._cover.async_set_state(data) + @property def device_info(self): """Return a device description for device registry.""" @@ -144,3 +161,26 @@ class DeconzCover(CoverDevice): 'sw_version': self._cover.swversion, 'via_hub': (DECONZ_DOMAIN, bridgeid), } + + +class DeconzCoverZigbeeSpec(DeconzCover): + """Zigbee spec is the inverse of how deCONZ normally reports attributes.""" + + @property + def current_cover_position(self): + """Return the current position of the cover.""" + return 100 - int(self._cover.brightness / 255 * 100) + + @property + def is_closed(self): + """Return if the cover is closed.""" + return self._cover.state + + async def async_set_cover_position(self, **kwargs): + """Move the cover to a specific position.""" + position = kwargs[ATTR_POSITION] + data = {'on': False} + if position < 100: + data['on'] = True + data['bri'] = 255 - int(position / 100 * 255) + await self._cover.async_set_state(data) diff --git a/homeassistant/components/deconz/const.py b/homeassistant/components/deconz/const.py index 617d231f92e..5462b5b61b9 100644 --- a/homeassistant/components/deconz/const.py +++ b/homeassistant/components/deconz/const.py @@ -16,7 +16,9 @@ CONF_ALLOW_DECONZ_GROUPS = 'allow_deconz_groups' ATTR_DARK = 'dark' ATTR_ON = 'on' -COVER_TYPES = ["Level controllable output"] +DAMPERS = ["Level controllable output"] +WINDOW_COVERS = ["Window covering device"] +COVER_TYPES = DAMPERS + WINDOW_COVERS POWER_PLUGS = ["On/Off plug-in unit", "Smart plug"] SIRENS = ["Warning device"] diff --git a/tests/components/cover/test_deconz.py b/tests/components/cover/test_deconz.py index 60de9cffdc1..e9c630823bd 100644 --- a/tests/components/cover/test_deconz.py +++ b/tests/components/cover/test_deconz.py @@ -13,7 +13,15 @@ SUPPORTED_COVERS = { "id": "Cover 1 id", "name": "Cover 1 name", "type": "Level controllable output", - "state": {} + "state": {}, + "modelid": "Not zigbee spec" + }, + "2": { + "id": "Cover 2 id", + "name": "Cover 2 name", + "type": "Window covering device", + "state": {}, + "modelid": "lumi.curtain" } } @@ -62,7 +70,7 @@ async def test_cover(hass): await setup_bridge(hass, {"lights": SUPPORTED_COVERS}) assert "cover.cover_1_name" in hass.data[deconz.DATA_DECONZ_ID] assert len(SUPPORTED_COVERS) == len(COVER_TYPES) - assert len(hass.states.async_all()) == 2 + assert len(hass.states.async_all()) == 3 async def test_add_new_cover(hass):