core/homeassistant/components/homekit/covers.py

85 lines
3.1 KiB
Python

"""Class to hold all cover accessories."""
import logging
from homeassistant.components.cover import ATTR_CURRENT_POSITION
from homeassistant.helpers.event import async_track_state_change
from . import TYPES
from .accessories import HomeAccessory
from .const import (
SERVICES_WINDOW_COVERING, CHAR_CURRENT_POSITION,
CHAR_TARGET_POSITION, CHAR_POSITION_STATE)
_LOGGER = logging.getLogger(__name__)
@TYPES.register('Window')
class Window(HomeAccessory):
"""Generate a Window accessory for a cover entity.
The cover entity must support: set_cover_position.
"""
def __init__(self, hass, entity_id, display_name):
"""Initialize a Window accessory object."""
super().__init__(display_name)
self.set_category(self.ALL_CATEGORIES.WINDOW)
self.set_accessory_info(entity_id)
self.add_preload_service(SERVICES_WINDOW_COVERING)
self._hass = hass
self._entity_id = entity_id
self.current_position = None
self.homekit_target = None
self.service_cover = self.get_service(SERVICES_WINDOW_COVERING)
self.char_current_position = self.service_cover. \
get_characteristic(CHAR_CURRENT_POSITION)
self.char_target_position = self.service_cover. \
get_characteristic(CHAR_TARGET_POSITION)
self.char_position_state = self.service_cover. \
get_characteristic(CHAR_POSITION_STATE)
self.char_target_position.setter_callback = self.move_cover
def run(self):
"""Method called be object after driver is started."""
state = self._hass.states.get(self._entity_id)
self.update_cover_position(new_state=state)
async_track_state_change(
self._hass, self._entity_id, self.update_cover_position)
def move_cover(self, value):
"""Move cover to value if call came from homekit."""
if value != self.current_position:
_LOGGER.debug("%s: Set position to %d", self._entity_id, value)
self.homekit_target = value
if value > self.current_position:
self.char_position_state.set_value(1)
elif value < self.current_position:
self.char_position_state.set_value(0)
self._hass.services.call(
'cover', 'set_cover_position',
{'entity_id': self._entity_id, 'position': value})
def update_cover_position(self, entity_id=None, old_state=None,
new_state=None):
"""Update cover position after state changed."""
if new_state is None:
return
current_position = new_state.attributes[ATTR_CURRENT_POSITION]
if current_position is None:
return
self.current_position = int(current_position)
self.char_current_position.set_value(self.current_position)
if self.homekit_target is None or \
abs(self.current_position - self.homekit_target) < 6:
self.char_target_position.set_value(self.current_position)
self.char_position_state.set_value(2)
self.homekit_target = None