Created
October 12, 2018 20:01
-
-
Save cnrd/05fd39e3687c50b0494a6417a4627051 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Support for deCONZ covers. | |
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) | |
from homeassistant.components.cover import ( | |
ATTR_POSITION, CoverDevice, SUPPORT_CLOSE, SUPPORT_OPEN, | |
SUPPORT_SET_POSITION) | |
from homeassistant.core import callback | |
from homeassistant.helpers.device_registry import CONNECTION_ZIGBEE | |
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): | |
"""Unsupported way of setting up deCONZ covers.""" | |
pass | |
async def async_setup_entry(hass, config_entry, async_add_entities): | |
"""Set up covers for deCONZ component. | |
Covers are based on same device class as lights in deCONZ. | |
""" | |
@callback | |
def async_add_cover(lights): | |
"""Add cover from deCONZ.""" | |
entities = [] | |
for light in lights: | |
if light.type in COVER_TYPES: | |
entities.append(DeconzCover(light)) | |
async_add_entities(entities, True) | |
hass.data[DATA_DECONZ_UNSUB].append( | |
async_dispatcher_connect(hass, 'deconz_new_light', async_add_cover)) | |
async_add_cover(hass.data[DATA_DECONZ].lights.values()) | |
class DeconzCover(CoverDevice): | |
"""Representation of a deCONZ cover.""" | |
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 | |
async def async_added_to_hass(self): | |
"""Subscribe to covers events.""" | |
self._cover.register_async_callback(self.async_update_callback) | |
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self._cover.deconz_id | |
async def async_will_remove_from_hass(self) -> None: | |
"""Disconnect cover object when removed.""" | |
self._cover.remove_callback(self.async_update_callback) | |
self._cover = None | |
@callback | |
def async_update_callback(self, reason): | |
"""Update the cover's state.""" | |
self.async_schedule_update_ha_state() | |
@property | |
def current_cover_position(self): | |
"""Return the current position of the cover.""" | |
if self.is_closed: | |
return 0 | |
if self._cover.modelid in ZIGBEE_SPEC: | |
return abs(int((self._cover.brightness / 255 * 100) - 100)) | |
return int(self._cover.brightness / 255 * 100) | |
@property | |
def is_closed(self): | |
"""Return if the cover is closed.""" | |
if self._cover.modelid in ZIGBEE_SPEC: | |
return self._cover.state | |
return not self._cover.state | |
@property | |
def name(self): | |
"""Return the name of the cover.""" | |
return self._cover.name | |
@property | |
def unique_id(self): | |
"""Return a unique identifier for this cover.""" | |
return self._cover.uniqueid | |
@property | |
def device_class(self): | |
"""Return the class of the cover.""" | |
if self._cover.type == "Level controllable output": | |
return 'damper' | |
if self._cover.type == "Window covering device": | |
return 'window' | |
return None | |
@property | |
def supported_features(self): | |
"""Flag supported features.""" | |
return self._features | |
@property | |
def available(self): | |
"""Return True if light is available.""" | |
return self._cover.reachable | |
@property | |
def should_poll(self): | |
"""No polling needed.""" | |
return False | |
async def async_set_cover_position(self, **kwargs): | |
"""Move the cover to a specific position.""" | |
position = kwargs[ATTR_POSITION] | |
if self._cover.modelid in ZIGBEE_SPEC: | |
data = {'on': False} | |
if position < 100 and position >= 0: | |
data['on'] = True | |
data['bri'] = int((100 - position) / 100 * 255) | |
else: | |
data = {'on': False} | |
if position > 0: | |
data['on'] = True | |
data['bri'] = int(position / 100 * 255) | |
await self._cover.async_set_state(data) | |
async def async_open_cover(self, **kwargs): | |
"""Open cover.""" | |
data = {ATTR_POSITION: 100} | |
await self.async_set_cover_position(**data) | |
async def async_close_cover(self, **kwargs): | |
"""Close cover.""" | |
data = {ATTR_POSITION: 0} | |
await self.async_set_cover_position(**data) | |
@property | |
def device_info(self): | |
"""Return a device description for device registry.""" | |
if (self._cover.uniqueid is None or | |
self._cover.uniqueid.count(':') != 7): | |
return None | |
serial = self._cover.uniqueid.split('-', 1)[0] | |
bridgeid = self.hass.data[DATA_DECONZ].config.bridgeid | |
return { | |
'connections': {(CONNECTION_ZIGBEE, serial)}, | |
'identifiers': {(DECONZ_DOMAIN, serial)}, | |
'manufacturer': self._cover.manufacturer, | |
'model': self._cover.modelid, | |
'name': self._cover.name, | |
'sw_version': self._cover.swversion, | |
'via_hub': (DECONZ_DOMAIN, bridgeid), | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment