This commit is contained in:
Paulus Schoutsen 2019-07-31 12:25:30 -07:00
parent da05dfe708
commit 4de97abc3a
2676 changed files with 163166 additions and 140084 deletions

View file

@ -21,34 +21,34 @@ def get_accessory_information(accessory):
from homekit.model.characteristics import CharacteristicsTypes
result = {}
for service in accessory['services']:
stype = service['type'].upper()
if ServicesTypes.get_short(stype) != 'accessory-information':
for service in accessory["services"]:
stype = service["type"].upper()
if ServicesTypes.get_short(stype) != "accessory-information":
continue
for characteristic in service['characteristics']:
ctype = CharacteristicsTypes.get_short(characteristic['type'])
if 'value' in characteristic:
result[ctype] = characteristic['value']
for characteristic in service["characteristics"]:
ctype = CharacteristicsTypes.get_short(characteristic["type"])
if "value" in characteristic:
result[ctype] = characteristic["value"]
return result
def get_bridge_information(accessories):
"""Return the accessory info for the bridge."""
for accessory in accessories:
if accessory['aid'] == 1:
if accessory["aid"] == 1:
return get_accessory_information(accessory)
return get_accessory_information(accessories[0])
def get_accessory_name(accessory_info):
"""Return the name field of an accessory."""
for field in ('name', 'model', 'manufacturer'):
for field in ("name", "model", "manufacturer"):
if field in accessory_info:
return accessory_info[field]
return None
class HKDevice():
class HKDevice:
"""HomeKit device."""
def __init__(self, hass, config_entry, pairing_data):
@ -87,11 +87,7 @@ class HKDevice():
self.available = True
self.signal_state_updated = '_'.join((
DOMAIN,
self.unique_id,
'state_updated',
))
self.signal_state_updated = "_".join((DOMAIN, self.unique_id, "state_updated"))
# Current values of all characteristics homekit_controller is tracking.
# Key is a (accessory_id, characteristic_id) tuple.
@ -110,16 +106,13 @@ class HKDevice():
def remove_pollable_characteristics(self, accessory_id):
"""Remove all pollable characteristics by accessory id."""
self.pollable_characteristics = [
char for char in self.pollable_characteristics
if char[0] != accessory_id
char for char in self.pollable_characteristics if char[0] != accessory_id
]
def async_set_unavailable(self):
"""Mark state of all entities on this connection as unavailable."""
self.available = False
self.hass.helpers.dispatcher.async_dispatcher_send(
self.signal_state_updated,
)
self.hass.helpers.dispatcher.async_dispatcher_send(self.signal_state_updated)
async def async_setup(self):
"""Prepare to use a paired HomeKit device in homeassistant."""
@ -127,19 +120,17 @@ class HKDevice():
if not cache:
if await self.async_refresh_entity_map(self.config_num):
self._polling_interval_remover = async_track_time_interval(
self.hass,
self.async_update,
DEFAULT_SCAN_INTERVAL
self.hass, self.async_update, DEFAULT_SCAN_INTERVAL
)
return True
return False
self.accessories = cache['accessories']
self.config_num = cache['config_num']
self.accessories = cache["accessories"]
self.config_num = cache["config_num"]
# Ensure the Pairing object has access to the latest version of the
# entity map.
self.pairing.pairing_data['accessories'] = self.accessories
self.pairing.pairing_data["accessories"] = self.accessories
self.async_load_platforms()
@ -148,9 +139,7 @@ class HKDevice():
await self.async_update()
self._polling_interval_remover = async_track_time_interval(
self.hass,
self.async_update,
DEFAULT_SCAN_INTERVAL
self.hass, self.async_update, DEFAULT_SCAN_INTERVAL
)
return True
@ -164,8 +153,7 @@ class HKDevice():
for platform in self.platforms:
unloads.append(
self.hass.config_entries.async_forward_entry_unload(
self.config_entry,
platform
self.config_entry, platform
)
)
@ -189,16 +177,14 @@ class HKDevice():
return
self.hass.data[ENTITY_MAP].async_create_or_update_map(
self.unique_id,
config_num,
self.accessories,
self.unique_id, config_num, self.accessories
)
self.config_num = config_num
# For BLE, the Pairing instance relies on the entity map to map
# aid/iid to GATT characteristics. So push it to there as well.
self.pairing.pairing_data['accessories'] = self.accessories
self.pairing.pairing_data["accessories"] = self.accessories
self.async_load_platforms()
@ -222,11 +208,11 @@ class HKDevice():
from homekit.model.services import ServicesTypes
for accessory in self.accessories:
aid = accessory['aid']
for service in accessory['services']:
iid = service['iid']
stype = ServicesTypes.get_short(service['type'].upper())
service['stype'] = stype
aid = accessory["aid"]
for service in accessory["services"]:
iid = service["iid"]
stype = ServicesTypes.get_short(service["type"].upper())
service["stype"] = stype
if (aid, iid) in self.entities:
# Don't add the same entity again
@ -242,8 +228,8 @@ class HKDevice():
from homekit.model.services import ServicesTypes
for accessory in self.accessories:
for service in accessory['services']:
stype = ServicesTypes.get_short(service['type'].upper())
for service in accessory["services"]:
stype = ServicesTypes.get_short(service["type"].upper())
if stype not in HOMEKIT_ACCESSORY_DISPATCH:
continue
@ -253,8 +239,7 @@ class HKDevice():
self.hass.async_create_task(
self.hass.config_entries.async_forward_entry_setup(
self.config_entry,
platform,
self.config_entry, platform
)
)
self.platforms.add(platform)
@ -263,20 +248,20 @@ class HKDevice():
"""Poll state of all entities attached to this bridge/accessory."""
# pylint: disable=import-error
from homekit.exceptions import (
AccessoryDisconnectedError, AccessoryNotFoundError,
EncryptionError)
AccessoryDisconnectedError,
AccessoryNotFoundError,
EncryptionError,
)
if not self.pollable_characteristics:
_LOGGER.debug(
"HomeKit connection not polling any characteristics."
)
_LOGGER.debug("HomeKit connection not polling any characteristics.")
return
_LOGGER.debug("Starting HomeKit controller update")
try:
new_values_dict = await self.get_characteristics(
self.pollable_characteristics,
self.pollable_characteristics
)
except AccessoryNotFoundError:
# Not only did the connection fail, but also the accessory is not
@ -294,9 +279,7 @@ class HKDevice():
accessory = self.current_state.setdefault(aid, {})
accessory[cid] = value
self.hass.helpers.dispatcher.async_dispatcher_send(
self.signal_state_updated,
)
self.hass.helpers.dispatcher.async_dispatcher_send(self.signal_state_updated)
_LOGGER.debug("Finished HomeKit controller update")
@ -304,9 +287,7 @@ class HKDevice():
"""Read latest state from homekit accessory."""
async with self.pairing_lock:
chars = await self.hass.async_add_executor_job(
self.pairing.get_characteristics,
*args,
**kwargs,
self.pairing.get_characteristics, *args, **kwargs
)
return chars
@ -314,16 +295,11 @@ class HKDevice():
"""Control a HomeKit device state from Home Assistant."""
chars = []
for row in characteristics:
chars.append((
row['aid'],
row['iid'],
row['value'],
))
chars.append((row["aid"], row["iid"], row["value"]))
async with self.pairing_lock:
await self.hass.async_add_executor_job(
self.pairing.put_characteristics,
chars
self.pairing.put_characteristics, chars
)
@property
@ -333,7 +309,7 @@ class HKDevice():
This id is random and will change if a device undergoes a hard reset.
"""
return self.pairing_data['AccessoryPairingID']
return self.pairing_data["AccessoryPairingID"]
@property
def connection_info(self):