Homekit controller BLE groundwork (part 2) (#20548)

* Only fetch values of characteristics we are tracking.

* Use callbacks on subclasses to update individual values

* Update alarm_control_panel to use update callbacks

* Update climate to use update callbacks

* Update cover to use update callbacks

* Update light to use update callbacks

* Update lock to use update callbacks

* Update switch to use update callbacks

* Remove compatibility code as all entities migrated

* pylint by name rather than code
This commit is contained in:
Jc2k 2019-01-28 20:27:26 +00:00 committed by Martin Hjelmare
parent 41c1997b88
commit abeb875c61
7 changed files with 76 additions and 112 deletions

View file

@ -247,7 +247,7 @@ class HomeKitEntity(Entity):
setup_fn = getattr(self, '_setup_{}'.format(setup_fn_name), None) setup_fn = getattr(self, '_setup_{}'.format(setup_fn_name), None)
if not setup_fn: if not setup_fn:
return return
# pylint: disable=E1102 # pylint: disable=not-callable
setup_fn(char) setup_fn(char)
def update(self): def update(self):
@ -255,19 +255,23 @@ class HomeKitEntity(Entity):
# pylint: disable=import-error # pylint: disable=import-error
from homekit.exceptions import AccessoryDisconnectedError from homekit.exceptions import AccessoryDisconnectedError
try:
pairing = self._accessory.pairing pairing = self._accessory.pairing
data = pairing.list_accessories_and_characteristics()
try:
new_values_dict = pairing.get_characteristics(self._chars_to_poll)
except AccessoryDisconnectedError: except AccessoryDisconnectedError:
return return
for accessory in data:
if accessory['aid'] != self._aid: for (_, iid), result in new_values_dict.items():
if 'value' not in result:
continue continue
for service in accessory['services']: # Callback to update the entity with this characteristic value
if service['iid'] != self._iid: char_name = escape_characteristic_name(self._char_names[iid])
update_fn = getattr(self, '_update_{}'.format(char_name), None)
if not update_fn:
continue continue
self.update_characteristics(service['characteristics']) # pylint: disable=not-callable
break update_fn(result['value'])
@property @property
def unique_id(self): def unique_id(self):
@ -290,7 +294,7 @@ class HomeKitEntity(Entity):
def update_characteristics(self, characteristics): def update_characteristics(self, characteristics):
"""Synchronise a HomeKit device state with Home Assistant.""" """Synchronise a HomeKit device state with Home Assistant."""
raise NotImplementedError pass
def put_characteristics(self, characteristics): def put_characteristics(self, characteristics):
"""Control a HomeKit device state from Home Assistant.""" """Control a HomeKit device state from Home Assistant."""

View file

@ -64,18 +64,11 @@ class HomeKitAlarmControlPanel(HomeKitEntity, AlarmControlPanel):
CharacteristicsTypes.BATTERY_LEVEL, CharacteristicsTypes.BATTERY_LEVEL,
] ]
def update_characteristics(self, characteristics): def _update_security_system_state_current(self, value):
"""Synchronise the Alarm Control Panel state with Home Assistant.""" self._state = CURRENT_STATE_MAP[value]
# pylint: disable=import-error
from homekit.model.characteristics import CharacteristicsTypes
for characteristic in characteristics: def _update_battery_level(self, value):
ctype = characteristic['type'] self._battery_level = value
ctype = CharacteristicsTypes.get_short(ctype)
if ctype == "security-system-state.current":
self._state = CURRENT_STATE_MAP[characteristic['value']]
elif ctype == "battery-level":
self._battery_level = characteristic['value']
@property @property
def icon(self): def icon(self):

View file

@ -72,23 +72,17 @@ class HomeKitClimateDevice(HomeKitEntity, ClimateDevice):
def _setup_temperature_target(self, characteristic): def _setup_temperature_target(self, characteristic):
self._features |= SUPPORT_TARGET_TEMPERATURE self._features |= SUPPORT_TARGET_TEMPERATURE
def update_characteristics(self, characteristics): def _update_heating_cooling_current(self, value):
"""Synchronise device state with Home Assistant.""" self._state = MODE_HOMEKIT_TO_HASS.get(value)
# pylint: disable=import-error
from homekit.model.characteristics import CharacteristicsTypes
for characteristic in characteristics: def _update_heating_cooling_target(self, value):
ctype = CharacteristicsTypes.get_short_uuid(characteristic['type']) self._current_mode = MODE_HOMEKIT_TO_HASS.get(value)
if ctype == CharacteristicsTypes.HEATING_COOLING_CURRENT:
self._state = MODE_HOMEKIT_TO_HASS.get( def _update_temperature_current(self, value):
characteristic['value']) self._current_temp = value
if ctype == CharacteristicsTypes.HEATING_COOLING_TARGET:
self._current_mode = MODE_HOMEKIT_TO_HASS.get( def _update_temperature_target(self, value):
characteristic['value']) self._target_temp = value
elif ctype == CharacteristicsTypes.TEMPERATURE_CURRENT:
self._current_temp = characteristic['value']
elif ctype == CharacteristicsTypes.TEMPERATURE_TARGET:
self._target_temp = characteristic['value']
def set_temperature(self, **kwargs): def set_temperature(self, **kwargs):
"""Set new target temperature.""" """Set new target temperature."""

View file

@ -85,18 +85,14 @@ class HomeKitGarageDoorCover(HomeKitEntity, CoverDevice):
def _setup_name(self, char): def _setup_name(self, char):
self._name = char['value'] self._name = char['value']
def update_characteristics(self, characteristics): def _update_door_state_current(self, value):
"""Synchronise the Cover state with Home Assistant.""" self._state = CURRENT_GARAGE_STATE_MAP[value]
# pylint: disable=import-error
from homekit.model.characteristics import CharacteristicsTypes
for characteristic in characteristics: def _update_obstruction_detected(self, value):
ctype = characteristic['type'] self._obstruction_detected = value
ctype = CharacteristicsTypes.get_short(ctype)
if ctype == "door-state.current": def _update_name(self, value):
self._state = CURRENT_GARAGE_STATE_MAP[characteristic['value']] self._name = value
elif ctype == "obstruction-detected":
self._obstruction_detected = characteristic['value']
@property @property
def available(self): def available(self):
@ -187,31 +183,26 @@ class HomeKitWindowCover(HomeKitEntity, CoverDevice):
def _setup_name(self, char): def _setup_name(self, char):
self._name = char['value'] self._name = char['value']
def update_characteristics(self, characteristics): def _update_position_state(self, value):
"""Synchronise the Cover state with Home Assistant.""" self._state = CURRENT_WINDOW_STATE_MAP[value]
# pylint: disable=import-error
from homekit.model.characteristics import CharacteristicsTypes
for characteristic in characteristics: def _update_position_current(self, value):
ctype = characteristic['type'] self._position = value
ctype = CharacteristicsTypes.get_short(ctype)
if ctype == "position.state": def _update_position_hold(self, value):
if 'value' in characteristic: self._hold = value
self._state = \
CURRENT_WINDOW_STATE_MAP[characteristic['value']] def _update_vertical_tilt_current(self, value):
elif ctype == "position.current": self._tilt_position = value
self._position = characteristic['value']
elif ctype == "position.hold": def _update_horizontal_tilt_current(self, value):
if 'value' in characteristic: self._tilt_position = value
self._hold = characteristic['value']
elif ctype == "vertical-tilt.current": def _update_obstruction_detected(self, value):
if characteristic['value'] is not None: self._obstruction_detected = value
self._tilt_position = characteristic['value']
elif ctype == "horizontal-tilt.current": def _update_name(self, value):
if characteristic['value'] is not None: self._hold = value
self._tilt_position = characteristic['value']
elif ctype == "obstruction-detected":
self._obstruction_detected = characteristic['value']
@property @property
def supported_features(self): def supported_features(self):

View file

@ -60,24 +60,20 @@ class HomeKitLight(HomeKitEntity, Light):
def _setup_saturation(self, char): def _setup_saturation(self, char):
self._features |= SUPPORT_COLOR self._features |= SUPPORT_COLOR
def update_characteristics(self, characteristics): def _update_on(self, value):
"""Synchronise light state with Home Assistant.""" self._on = value
# pylint: disable=import-error
from homekit.model.characteristics import CharacteristicsTypes
for characteristic in characteristics: def _update_brightness(self, value):
ctype = characteristic['type'] self._brightness = value
ctype = CharacteristicsTypes.get_short(ctype)
if ctype == "on": def _update_color_temperature(self, value):
self._on = characteristic['value'] self._color_temperature = value
elif ctype == 'brightness':
self._brightness = characteristic['value'] def _update_hue(self, value):
elif ctype == 'color-temperature': self._hue = value
self._color_temperature = characteristic['value']
elif ctype == "hue": def _update_saturation(self, value):
self._hue = characteristic['value'] self._saturation = value
elif ctype == "saturation":
self._saturation = characteristic['value']
@property @property
def is_on(self): def is_on(self):

View file

@ -61,18 +61,11 @@ class HomeKitLock(HomeKitEntity, LockDevice):
CharacteristicsTypes.BATTERY_LEVEL, CharacteristicsTypes.BATTERY_LEVEL,
] ]
def update_characteristics(self, characteristics): def _update_lock_mechanism_current_state(self, value):
"""Synchronise the Lock state with Home Assistant.""" self._state = CURRENT_STATE_MAP[value]
# pylint: disable=import-error
from homekit.model.characteristics import CharacteristicsTypes
for characteristic in characteristics: def _update_battery_level(self, value):
ctype = characteristic['type'] self._battery_level = value
ctype = CharacteristicsTypes.get_short(ctype)
if ctype == "lock-mechanism.current-state":
self._state = CURRENT_STATE_MAP[characteristic['value']]
elif ctype == "battery-level":
self._battery_level = characteristic['value']
@property @property
def name(self): def name(self):

View file

@ -42,18 +42,11 @@ class HomeKitSwitch(HomeKitEntity, SwitchDevice):
CharacteristicsTypes.OUTLET_IN_USE, CharacteristicsTypes.OUTLET_IN_USE,
] ]
def update_characteristics(self, characteristics): def _update_on(self, value):
"""Synchronise the switch state with Home Assistant.""" self._on = value
# pylint: disable=import-error
from homekit.model.characteristics import CharacteristicsTypes
for characteristic in characteristics: def _update_outlet_in_use(self, value):
ctype = characteristic['type'] self._outlet_in_use = value
ctype = CharacteristicsTypes.get_short(ctype)
if ctype == "on":
self._on = characteristic['value']
elif ctype == "outlet-in-use":
self._outlet_in_use = characteristic['value']
@property @property
def is_on(self): def is_on(self):