Refactor how entities are created for homekit_controller services (#43242)

This commit is contained in:
Jc2k 2020-11-16 23:11:39 +00:00 committed by GitHub
parent d11d1343a8
commit 3e1f2a5103
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 94 additions and 116 deletions

View file

@ -1,5 +1,6 @@
"""Support for HomeKit Controller air quality sensors."""
from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes
from homeassistant.components.air_quality import AirQualityEntity
from homeassistant.core import callback
@ -85,10 +86,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
conn = hass.data[KNOWN_DEVICES][hkid]
@callback
def async_add_service(aid, service):
if service["stype"] != "air-quality":
def async_add_service(service):
if service.short_type != ServicesTypes.AIR_QUALITY_SENSOR:
return False
info = {"aid": aid, "iid": service["iid"]}
info = {"aid": service.accessory.aid, "iid": service.iid}
async_add_entities([HomeAirQualitySensor(conn, info)], True)
return True

View file

@ -1,5 +1,6 @@
"""Support for Homekit Alarm Control Panel."""
from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes
from homeassistant.components.alarm_control_panel import AlarmControlPanelEntity
from homeassistant.components.alarm_control_panel.const import (
@ -43,10 +44,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
conn = hass.data[KNOWN_DEVICES][hkid]
@callback
def async_add_service(aid, service):
if service["stype"] != "security-system":
def async_add_service(service):
if service.short_type != ServicesTypes.SECURITY_SYSTEM:
return False
info = {"aid": aid, "iid": service["iid"]}
info = {"aid": service.accessory.aid, "iid": service.iid}
async_add_entities([HomeKitAlarmControlPanelEntity(conn, info)], True)
return True

View file

@ -1,5 +1,6 @@
"""Support for Homekit motion sensors."""
from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes
from homeassistant.components.binary_sensor import (
DEVICE_CLASS_GAS,
@ -124,12 +125,12 @@ class HomeKitLeakSensor(HomeKitEntity, BinarySensorEntity):
ENTITY_TYPES = {
"motion": HomeKitMotionSensor,
"contact": HomeKitContactSensor,
"smoke": HomeKitSmokeSensor,
"carbon-monoxide": HomeKitCarbonMonoxideSensor,
"occupancy": HomeKitOccupancySensor,
"leak": HomeKitLeakSensor,
ServicesTypes.MOTION_SENSOR: HomeKitMotionSensor,
ServicesTypes.CONTACT_SENSOR: HomeKitContactSensor,
ServicesTypes.SMOKE_SENSOR: HomeKitSmokeSensor,
ServicesTypes.CARBON_MONOXIDE_SENSOR: HomeKitCarbonMonoxideSensor,
ServicesTypes.OCCUPANCY_SENSOR: HomeKitOccupancySensor,
ServicesTypes.LEAK_SENSOR: HomeKitLeakSensor,
}
@ -139,11 +140,11 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
conn = hass.data[KNOWN_DEVICES][hkid]
@callback
def async_add_service(aid, service):
entity_class = ENTITY_TYPES.get(service["stype"])
def async_add_service(service):
entity_class = ENTITY_TYPES.get(service.short_type)
if not entity_class:
return False
info = {"aid": aid, "iid": service["iid"]}
info = {"aid": service.accessory.aid, "iid": service.iid}
async_add_entities([entity_class(conn, info)], True)
return True

View file

@ -10,6 +10,7 @@ from aiohomekit.model.characteristics import (
SwingModeValues,
TargetHeaterCoolerStateValues,
)
from aiohomekit.model.services import ServicesTypes
from aiohomekit.utils import clamp_enum_to_char
from homeassistant.components.climate import (
@ -87,11 +88,11 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
conn = hass.data[KNOWN_DEVICES][hkid]
@callback
def async_add_service(aid, service):
entity_class = ENTITY_TYPES.get(service["stype"])
def async_add_service(service):
entity_class = ENTITY_TYPES.get(service.short_type)
if not entity_class:
return False
info = {"aid": aid, "iid": service["iid"]}
info = {"aid": service.accessory.aid, "iid": service.iid}
async_add_entities([entity_class(conn, info)], True)
return True
@ -454,6 +455,6 @@ class HomeKitClimateEntity(HomeKitEntity, ClimateEntity):
ENTITY_TYPES = {
"heater-cooler": HomeKitHeaterCoolerEntity,
"thermostat": HomeKitClimateEntity,
ServicesTypes.HEATER_COOLER: HomeKitHeaterCoolerEntity,
ServicesTypes.THERMOSTAT: HomeKitClimateEntity,
}

View file

@ -317,19 +317,17 @@ class HKDevice:
self._add_new_entities_for_accessory(self.accessory_factories)
def _add_new_entities(self, callbacks):
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
for accessory in self.entity_map.accessories:
aid = accessory.aid
for service in accessory.services:
iid = service.iid
if (aid, iid) in self.entities:
# Don't add the same entity again
continue
for listener in callbacks:
if listener(aid, service):
if listener(service):
self.entities.append((aid, iid))
break

View file

@ -1,5 +1,6 @@
"""Support for Homekit covers."""
from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes
from homeassistant.components.cover import (
ATTR_POSITION,
@ -39,17 +40,13 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
conn = hass.data[KNOWN_DEVICES][hkid]
@callback
def async_add_service(aid, service):
info = {"aid": aid, "iid": service["iid"]}
if service["stype"] == "garage-door-opener":
async_add_entities([HomeKitGarageDoorCover(conn, info)], True)
return True
if service["stype"] in ("window-covering", "window"):
async_add_entities([HomeKitWindowCover(conn, info)], True)
return True
return False
def async_add_service(service):
entity_class = ENTITY_TYPES.get(service.short_type)
if not entity_class:
return False
info = {"aid": service.accessory.aid, "iid": service.iid}
async_add_entities([entity_class(conn, info)], True)
return True
conn.add_listener(async_add_service)
@ -246,3 +243,9 @@ class HomeKitWindowCover(HomeKitEntity, CoverEntity):
if not obstruction_detected:
return {}
return {"obstruction-detected": obstruction_detected}
ENTITY_TYPES = {
ServicesTypes.GARAGE_DOOR_OPENER: HomeKitGarageDoorCover,
ServicesTypes.WINDOW_COVERING: HomeKitWindowCover,
}

View file

@ -174,9 +174,9 @@ def enumerate_doorbell(service):
TRIGGER_FINDERS = {
"service-label": enumerate_stateless_switch_group,
"stateless-programmable-switch": enumerate_stateless_switch,
"doorbell": enumerate_doorbell,
ServicesTypes.SERVICE_LABEL: enumerate_stateless_switch_group,
ServicesTypes.STATELESS_PROGRAMMABLE_SWITCH: enumerate_stateless_switch,
ServicesTypes.DOORBELL: enumerate_doorbell,
}
@ -186,8 +186,9 @@ async def async_setup_triggers_for_entry(hass: HomeAssistant, config_entry):
conn = hass.data[KNOWN_DEVICES][hkid]
@callback
def async_add_service(aid, service_dict):
service_type = service_dict["stype"]
def async_add_service(service):
aid = service.accessory.aid
service_type = service.short_type
# If not a known service type then we can't handle any stateless events for it
if service_type not in TRIGGER_FINDERS:
@ -201,11 +202,6 @@ async def async_setup_triggers_for_entry(hass: HomeAssistant, config_entry):
if device_id in hass.data[TRIGGERS]:
return False
# At the moment add_listener calls us with the raw service dict, rather than
# a service model. So turn it into a service ourselves.
accessory = conn.entity_map.aid(aid)
service = accessory.services.iid(service_dict["iid"])
# Just because we recognise the service type doesn't mean we can actually
# extract any triggers - so only proceed if we can
triggers = TRIGGER_FINDERS[service_type](service)

View file

@ -1,5 +1,6 @@
"""Support for Homekit fans."""
from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes
from homeassistant.components.fan import (
DIRECTION_FORWARD,
@ -161,8 +162,8 @@ class HomeKitFanV2(BaseHomeKitFan):
ENTITY_TYPES = {
"fan": HomeKitFanV1,
"fanv2": HomeKitFanV2,
ServicesTypes.FAN: HomeKitFanV1,
ServicesTypes.FAN_V2: HomeKitFanV2,
}
@ -172,11 +173,11 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
conn = hass.data[KNOWN_DEVICES][hkid]
@callback
def async_add_service(aid, service):
entity_class = ENTITY_TYPES.get(service["stype"])
def async_add_service(service):
entity_class = ENTITY_TYPES.get(service.short_type)
if not entity_class:
return False
info = {"aid": aid, "iid": service["iid"]}
info = {"aid": service.accessory.aid, "iid": service.iid}
async_add_entities([entity_class(conn, info)], True)
return True

View file

@ -2,6 +2,7 @@
from typing import List, Optional
from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes
from homeassistant.components.humidifier import HumidifierEntity
from homeassistant.components.humidifier.const import (
@ -253,51 +254,22 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
hkid = config_entry.data["AccessoryPairingID"]
conn = hass.data[KNOWN_DEVICES][hkid]
def get_accessory(conn, aid):
for acc in conn.accessories:
if acc.get("aid") == aid:
return acc
return None
def get_service(acc, iid):
for serv in acc.get("services"):
if serv.get("iid") == iid:
return serv
return None
def get_char(serv, iid):
try:
type_name = CharacteristicsTypes[iid]
type_uuid = CharacteristicsTypes.get_uuid(type_name)
for char in serv.get("characteristics"):
if char.get("type") == type_uuid:
return char
except KeyError:
return None
return None
@callback
def async_add_service(aid, service):
if service["stype"] != "humidifier-dehumidifier":
def async_add_service(service):
if service.short_type != ServicesTypes.HUMIDIFIER_DEHUMIDIFIER:
return False
info = {"aid": aid, "iid": service["iid"]}
acc = get_accessory(conn, aid)
serv = get_service(acc, service["iid"])
info = {"aid": service.accessory.aid, "iid": service.iid}
if (
get_char(serv, CharacteristicsTypes.RELATIVE_HUMIDITY_HUMIDIFIER_THRESHOLD)
is not None
):
async_add_entities([HomeKitHumidifier(conn, info)], True)
entities = []
if (
get_char(
serv, CharacteristicsTypes.RELATIVE_HUMIDITY_DEHUMIDIFIER_THRESHOLD
)
is not None
):
async_add_entities([HomeKitDehumidifier(conn, info)], True)
if service.has(CharacteristicsTypes.RELATIVE_HUMIDITY_HUMIDIFIER_THRESHOLD):
entities.append(HomeKitHumidifier(conn, info))
if service.has(CharacteristicsTypes.RELATIVE_HUMIDITY_DEHUMIDIFIER_THRESHOLD):
entities.append(HomeKitDehumidifier(conn, info))
async_add_entities(entities, True)
return True

View file

@ -1,5 +1,6 @@
"""Support for Homekit lights."""
from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
@ -21,10 +22,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
conn = hass.data[KNOWN_DEVICES][hkid]
@callback
def async_add_service(aid, service):
if service["stype"] != "lightbulb":
def async_add_service(service):
if service.short_type != ServicesTypes.LIGHTBULB:
return False
info = {"aid": aid, "iid": service["iid"]}
info = {"aid": service.accessory.aid, "iid": service.iid}
async_add_entities([HomeKitLight(conn, info)], True)
return True

View file

@ -1,5 +1,6 @@
"""Support for HomeKit Controller locks."""
from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes
from homeassistant.components.lock import LockEntity
from homeassistant.const import ATTR_BATTERY_LEVEL, STATE_LOCKED, STATE_UNLOCKED
@ -20,10 +21,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
conn = hass.data[KNOWN_DEVICES][hkid]
@callback
def async_add_service(aid, service):
if service["stype"] != "lock-mechanism":
def async_add_service(service):
if service.short_type != ServicesTypes.LOCK_MECHANISM:
return False
info = {"aid": aid, "iid": service["iid"]}
info = {"aid": service.accessory.aid, "iid": service.iid}
async_add_entities([HomeKitLock(conn, info)], True)
return True

View file

@ -44,10 +44,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
conn = hass.data[KNOWN_DEVICES][hkid]
@callback
def async_add_service(aid, service):
if service["stype"] != "television":
def async_add_service(service):
if service.short_type != ServicesTypes.TELEVISION:
return False
info = {"aid": aid, "iid": service["iid"]}
info = {"aid": service.accessory.aid, "iid": service.iid}
async_add_entities([HomeKitTelevision(conn, info)], True)
return True

View file

@ -1,5 +1,6 @@
"""Support for Homekit sensors."""
from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes
from homeassistant.const import (
CONCENTRATION_PARTS_PER_MILLION,
@ -216,11 +217,11 @@ class HomeKitBatterySensor(HomeKitEntity):
ENTITY_TYPES = {
"humidity": HomeKitHumiditySensor,
"temperature": HomeKitTemperatureSensor,
"light": HomeKitLightSensor,
"carbon-dioxide": HomeKitCarbonDioxideSensor,
"battery": HomeKitBatterySensor,
ServicesTypes.HUMIDITY_SENSOR: HomeKitHumiditySensor,
ServicesTypes.TEMPERATURE_SENSOR: HomeKitTemperatureSensor,
ServicesTypes.LIGHT_SENSOR: HomeKitLightSensor,
ServicesTypes.CARBON_DIOXIDE_SENSOR: HomeKitCarbonDioxideSensor,
ServicesTypes.BATTERY_SERVICE: HomeKitBatterySensor,
}
@ -230,11 +231,11 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
conn = hass.data[KNOWN_DEVICES][hkid]
@callback
def async_add_service(aid, service):
entity_class = ENTITY_TYPES.get(service["stype"])
def async_add_service(service):
entity_class = ENTITY_TYPES.get(service.short_type)
if not entity_class:
return False
info = {"aid": aid, "iid": service["iid"]}
info = {"aid": service.accessory.aid, "iid": service.iid}
async_add_entities([entity_class(conn, info)], True)
return True

View file

@ -4,6 +4,7 @@ from aiohomekit.model.characteristics import (
InUseValues,
IsConfiguredValues,
)
from aiohomekit.model.services import ServicesTypes
from homeassistant.components.switch import SwitchEntity
from homeassistant.core import callback
@ -96,9 +97,9 @@ class HomeKitValve(HomeKitEntity, SwitchEntity):
ENTITY_TYPES = {
"switch": HomeKitSwitch,
"outlet": HomeKitSwitch,
"valve": HomeKitValve,
ServicesTypes.SWITCH: HomeKitSwitch,
ServicesTypes.OUTLET: HomeKitSwitch,
ServicesTypes.VALVE: HomeKitValve,
}
@ -108,11 +109,11 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
conn = hass.data[KNOWN_DEVICES][hkid]
@callback
def async_add_service(aid, service):
entity_class = ENTITY_TYPES.get(service["stype"])
def async_add_service(service):
entity_class = ENTITY_TYPES.get(service.short_type)
if not entity_class:
return False
info = {"aid": aid, "iid": service["iid"]}
info = {"aid": service.accessory.aid, "iid": service.iid}
async_add_entities([entity_class(conn, info)], True)
return True