From 19e6b6183759279490efbed3129dffd447dc4808 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 15 Feb 2023 15:58:46 -0600 Subject: [PATCH] runtime --- homeassistant/generated/zeroconf.py | 295 +++++-------------------- homeassistant/loader.py | 9 +- script/hassfest/zeroconf.py | 7 +- tests/components/zeroconf/test_init.py | 25 +-- 4 files changed, 76 insertions(+), 260 deletions(-) diff --git a/homeassistant/generated/zeroconf.py b/homeassistant/generated/zeroconf.py index 501f9cd1cd6..6032ce4bf7d 100644 --- a/homeassistant/generated/zeroconf.py +++ b/homeassistant/generated/zeroconf.py @@ -4,242 +4,65 @@ To update, run python3 -m script.hassfest """ HOMEKIT = { - "3810X": { - "domain": "roku", - "iot_class": "local_polling", - }, - "3820X": { - "domain": "roku", - "iot_class": "local_polling", - }, - "4660X": { - "domain": "roku", - "iot_class": "local_polling", - }, - "7820X": { - "domain": "roku", - "iot_class": "local_polling", - }, - "819LMB": { - "domain": "myq", - "iot_class": "cloud_polling", - }, - "AC02": { - "domain": "tado", - "iot_class": "cloud_polling", - }, - "Abode": { - "domain": "abode", - "iot_class": "cloud_push", - }, - "BSB002": { - "domain": "hue", - "iot_class": "local_push", - }, - "C105X": { - "domain": "roku", - "iot_class": "local_polling", - }, - "C135X": { - "domain": "roku", - "iot_class": "local_polling", - }, - "EB-*": { - "domain": "ecobee", - "iot_class": "cloud_polling", - }, - "Escea": { - "domain": "escea", - "iot_class": "local_push", - }, - "HHKBridge*": { - "domain": "hive", - "iot_class": "cloud_polling", - }, - "Healty Home Coach": { - "domain": "netatmo", - "iot_class": "cloud_polling", - }, - "Iota": { - "domain": "abode", - "iot_class": "cloud_push", - }, - "LIFX A19": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX BR30": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Beam": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Candle": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Clean": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Color": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX DLCOL": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX DLWW": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Dlight": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Downlight": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Filament": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX GU10": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Lightstrip": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Mini": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Nightvision": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Pls": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Plus": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Tile": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX White": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "LIFX Z": { - "domain": "lifx", - "iot_class": "local_polling", - }, - "MYQ": { - "domain": "myq", - "iot_class": "cloud_polling", - }, - "NL29": { - "domain": "nanoleaf", - "iot_class": "local_push", - }, - "NL42": { - "domain": "nanoleaf", - "iot_class": "local_push", - }, - "NL47": { - "domain": "nanoleaf", - "iot_class": "local_push", - }, - "NL48": { - "domain": "nanoleaf", - "iot_class": "local_push", - }, - "NL52": { - "domain": "nanoleaf", - "iot_class": "local_push", - }, - "NL59": { - "domain": "nanoleaf", - "iot_class": "local_push", - }, - "Netatmo Relay": { - "domain": "netatmo", - "iot_class": "cloud_polling", - }, - "PowerView": { - "domain": "hunterdouglas_powerview", - "iot_class": "local_polling", - }, - "Presence": { - "domain": "netatmo", - "iot_class": "cloud_polling", - }, - "Rachio": { - "domain": "rachio", - "iot_class": "cloud_push", - }, - "SPK5": { - "domain": "rainmachine", - "iot_class": "local_polling", - }, - "Sensibo": { - "domain": "sensibo", - "iot_class": "cloud_polling", - }, - "Smart Bridge": { - "domain": "lutron_caseta", - "iot_class": "local_push", - }, - "Socket": { - "domain": "wemo", - "iot_class": "local_push", - }, - "TRADFRI": { - "domain": "tradfri", - "iot_class": "local_polling", - }, - "Touch HD": { - "domain": "rainmachine", - "iot_class": "local_polling", - }, - "Welcome": { - "domain": "netatmo", - "iot_class": "cloud_polling", - }, - "Wemo": { - "domain": "wemo", - "iot_class": "local_push", - }, - "YL*": { - "domain": "yeelight", - "iot_class": "local_push", - }, - "ecobee*": { - "domain": "ecobee", - "iot_class": "cloud_polling", - }, - "iSmartGate": { - "domain": "gogogate2", - "iot_class": "local_polling", - }, - "iZone": { - "domain": "izone", - "iot_class": "local_polling", - }, - "tado": { - "domain": "tado", - "iot_class": "cloud_polling", - }, + "3810X": "roku", + "3820X": "roku", + "4660X": "roku", + "7820X": "roku", + "819LMB": "myq", + "AC02": "tado", + "Abode": "abode", + "BSB002": "hue", + "C105X": "roku", + "C135X": "roku", + "EB-*": "ecobee", + "Escea": "escea", + "HHKBridge*": "hive", + "Healty Home Coach": "netatmo", + "Iota": "abode", + "LIFX A19": "lifx", + "LIFX BR30": "lifx", + "LIFX Beam": "lifx", + "LIFX Candle": "lifx", + "LIFX Clean": "lifx", + "LIFX Color": "lifx", + "LIFX DLCOL": "lifx", + "LIFX DLWW": "lifx", + "LIFX Dlight": "lifx", + "LIFX Downlight": "lifx", + "LIFX Filament": "lifx", + "LIFX GU10": "lifx", + "LIFX Lightstrip": "lifx", + "LIFX Mini": "lifx", + "LIFX Nightvision": "lifx", + "LIFX Pls": "lifx", + "LIFX Plus": "lifx", + "LIFX Tile": "lifx", + "LIFX White": "lifx", + "LIFX Z": "lifx", + "MYQ": "myq", + "NL29": "nanoleaf", + "NL42": "nanoleaf", + "NL47": "nanoleaf", + "NL48": "nanoleaf", + "NL52": "nanoleaf", + "NL59": "nanoleaf", + "Netatmo Relay": "netatmo", + "PowerView": "hunterdouglas_powerview", + "Presence": "netatmo", + "Rachio": "rachio", + "SPK5": "rainmachine", + "Sensibo": "sensibo", + "Smart Bridge": "lutron_caseta", + "Socket": "wemo", + "TRADFRI": "tradfri", + "Touch HD": "rainmachine", + "Welcome": "netatmo", + "Wemo": "wemo", + "YL*": "yeelight", + "ecobee*": "ecobee", + "iSmartGate": "gogogate2", + "iZone": "izone", + "tado": "tado", } ZEROCONF = { diff --git a/homeassistant/loader.py b/homeassistant/loader.py index f06ae086c76..eba7154e41b 100644 --- a/homeassistant/loader.py +++ b/homeassistant/loader.py @@ -423,11 +423,14 @@ async def async_get_homekit( hass: HomeAssistant, ) -> dict[str, HomeKitDiscoveredIntegration]: """Return cached list of homekit models.""" + all_domains = set(HOMEKIT.values()) + integrations_by_domain = await async_get_integrations(hass, all_domains) homekit: dict[str, HomeKitDiscoveredIntegration] = { - model: HomeKitDiscoveredIntegration(details["domain"], details["iot_class"]) - for model, details in HOMEKIT.items() + model: HomeKitDiscoveredIntegration(domain, integration_or_exception.iot_class) + for model, domain in HOMEKIT.items() + if (integration_or_exception := integrations_by_domain.get(domain)) + and isinstance(integration_or_exception, Integration) } - integrations = await async_get_custom_components(hass) for integration in integrations.values(): if ( diff --git a/script/hassfest/zeroconf.py b/script/hassfest/zeroconf.py index bdd38d41070..76a7be45c34 100644 --- a/script/hassfest/zeroconf.py +++ b/script/hassfest/zeroconf.py @@ -12,7 +12,7 @@ from .serializer import format_python_namespace def generate_and_validate(integrations: dict[str, Integration]) -> str: """Validate and generate zeroconf data.""" service_type_dict = defaultdict(list) - homekit_dict: dict[str, dict[str, str]] = {} + homekit_dict: dict[str, str] = {} for domain in sorted(integrations): integration = integrations[domain] @@ -42,10 +42,7 @@ def generate_and_validate(integrations: dict[str, Integration]) -> str: ) break - homekit_dict[model] = { - "domain": domain, - "iot_class": integration.manifest["iot_class"], - } + homekit_dict[model] = domain # HomeKit models are matched on starting string, make sure none overlap. warned = set() diff --git a/tests/components/zeroconf/test_init.py b/tests/components/zeroconf/test_init.py index af0e6c7f3de..eceb54c52de 100644 --- a/tests/components/zeroconf/test_init.py +++ b/tests/components/zeroconf/test_init.py @@ -542,7 +542,7 @@ async def test_homekit_match_partial_space(hass, mock_async_zeroconf): clear=True, ), patch.dict( zc_gen.HOMEKIT, - {"LIFX": {"domain": "lifx", "iot_class": "local_polling"}}, + {"LIFX": "lifx"}, clear=True, ), patch.object( hass.config_entries.flow, "async_init" @@ -578,7 +578,7 @@ async def test_device_with_invalid_name(hass, mock_async_zeroconf, caplog): clear=True, ), patch.dict( zc_gen.HOMEKIT, - {"LIFX": {"domain": "lifx", "iot_class": "local_polling"}}, + {"LIFX": "lifx"}, clear=True, ), patch.object( hass.config_entries.flow, "async_init" @@ -609,7 +609,7 @@ async def test_homekit_match_partial_dash(hass, mock_async_zeroconf): clear=True, ), patch.dict( zc_gen.HOMEKIT, - {"Smart Bridge": {"domain": "lutron_caseta", "iot_class": "local_push"}}, + {"Smart Bridge": "lutron_caseta"}, clear=True, ), patch.object( hass.config_entries.flow, "async_init" @@ -638,11 +638,7 @@ async def test_homekit_match_partial_fnmatch(hass, mock_async_zeroconf): zc_gen.ZEROCONF, {"_hap._tcp.local.": [{"domain": "homekit_controller"}]}, clear=True, - ), patch.dict( - zc_gen.HOMEKIT, - {"YLDP*": {"domain": "yeelight", "iot_class": "local_push"}}, - clear=True, - ), patch.object( + ), patch.dict(zc_gen.HOMEKIT, {"YLDP*": "yeelight"}, clear=True), patch.object( hass.config_entries.flow, "async_init" ) as mock_config_flow, patch.object( zeroconf, @@ -671,7 +667,7 @@ async def test_homekit_match_full(hass, mock_async_zeroconf): clear=True, ), patch.dict( zc_gen.HOMEKIT, - {"BSB002": {"domain": "hue", "iot_class": "local_push"}}, + {"BSB002": "hue"}, clear=True, ), patch.object( hass.config_entries.flow, "async_init" @@ -702,10 +698,7 @@ async def test_homekit_already_paired(hass, mock_async_zeroconf): clear=True, ), patch.dict( zc_gen.HOMEKIT, - { - "AC02": {"domain": "tado", "iot_class": "cloud_polling"}, - "tado": {"domain": "tado", "iot_class": "cloud_polling"}, - }, + {"AC02": "tado", "tado": "tado"}, clear=True, ), patch.object( hass.config_entries.flow, "async_init" @@ -737,7 +730,7 @@ async def test_homekit_invalid_paring_status(hass, mock_async_zeroconf): clear=True, ), patch.dict( zc_gen.HOMEKIT, - {"Smart Bridge": {"domain": "lutron_caseta", "iot_class": "local_push"}}, + {"Smart Bridge": "lutron_caseta"}, clear=True, ), patch.object( hass.config_entries.flow, "async_init" @@ -801,7 +794,7 @@ async def test_homekit_controller_still_discovered_unpaired_for_cloud( clear=True, ), patch.dict( zc_gen.HOMEKIT, - {"Rachio": {"domain": "rachio", "iot_class": "cloud_push"}}, + {"Rachio": "rachio"}, clear=True, ), patch.object( hass.config_entries.flow, "async_init" @@ -841,7 +834,7 @@ async def test_homekit_controller_still_discovered_unpaired_for_polling( clear=True, ), patch.dict( zc_gen.HOMEKIT, - {"iSmartGate": {"domain": "gogogate2", "iot_class": "local_polling"}}, + {"iSmartGate": "gogogate2"}, clear=True, ), patch.object( hass.config_entries.flow, "async_init"