Use ZeroconfServiceInfo in homekit_controller (#59979)

Co-authored-by: epenet <epenet@users.noreply.github.com>
This commit is contained in:
epenet 2021-11-19 15:13:56 +01:00 committed by GitHub
parent d6c5aaa0cb
commit 982f2065c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 31 deletions

View File

@ -9,6 +9,7 @@ import voluptuous as vol
from homeassistant import config_entries
from homeassistant.components import zeroconf
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers.device_registry import (
CONNECTION_NETWORK_MAC,
async_get_registry as async_get_device_registry,
@ -157,13 +158,13 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
continue
record = device.info
return await self.async_step_zeroconf(
{
"host": record["address"],
"port": record["port"],
"hostname": record["name"],
"type": "_hap._tcp.local.",
"name": record["name"],
"properties": {
zeroconf.ZeroconfServiceInfo(
host=record["address"],
port=record["port"],
hostname=record["name"],
type="_hap._tcp.local.",
name=record["name"],
properties={
"md": record["md"],
"pv": record["pv"],
"id": unique_id,
@ -174,7 +175,7 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"sf": record["sf"],
"sh": "",
},
}
)
)
return self.async_abort(reason="no_devices")
@ -196,7 +197,9 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
return False
async def async_step_zeroconf(self, discovery_info):
async def async_step_zeroconf(
self, discovery_info: zeroconf.ZeroconfServiceInfo
) -> FlowResult:
"""Handle a discovered HomeKit accessory.
This flow is triggered by the discovery component.
@ -205,7 +208,8 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
# homekit_python has code to do this, but not in a form we can
# easily use, so do the bare minimum ourselves here instead.
properties = {
key.lower(): value for (key, value) in discovery_info["properties"].items()
key.lower(): value
for (key, value) in discovery_info[zeroconf.ATTR_PROPERTIES].items()
}
if "id" not in properties:
@ -221,7 +225,7 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
# It changes if a device is factory reset.
hkid = properties["id"]
model = properties["md"]
name = discovery_info["name"].replace("._hap._tcp.local.", "")
name = discovery_info[zeroconf.ATTR_NAME].replace("._hap._tcp.local.", "")
status_flags = int(properties["sf"])
paired = not status_flags & 0x01
@ -239,8 +243,8 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
# Set unique-id and error out if it's already configured
existing_entry = await self.async_set_unique_id(normalize_hkid(hkid))
updated_ip_port = {
"AccessoryIP": discovery_info["host"],
"AccessoryPort": discovery_info["port"],
"AccessoryIP": discovery_info[zeroconf.ATTR_HOST],
"AccessoryPort": discovery_info[zeroconf.ATTR_PORT],
}
# If the device is already paired and known to us we should monitor c#

View File

@ -11,6 +11,7 @@ from aiohomekit.model.services import ServicesTypes
import pytest
from homeassistant import config_entries
from homeassistant.components import zeroconf
from homeassistant.components.homekit_controller import config_flow
from homeassistant.components.homekit_controller.const import KNOWN_DEVICES
from homeassistant.helpers import device_registry
@ -133,16 +134,18 @@ def get_flow_context(hass, result):
return flow["context"]
def get_device_discovery_info(device, upper_case_props=False, missing_csharp=False):
def get_device_discovery_info(
device, upper_case_props=False, missing_csharp=False
) -> zeroconf.ZeroconfServiceInfo:
"""Turn a aiohomekit format zeroconf entry into a homeassistant one."""
record = device.info
result = {
"host": record["address"],
"port": record["port"],
"hostname": record["name"],
"type": "_hap._tcp.local.",
"name": record["name"],
"properties": {
result = zeroconf.ZeroconfServiceInfo(
host=record["address"],
port=record["port"],
hostname=record["name"],
type="_hap._tcp.local.",
name=record["name"],
properties={
"md": record["md"],
"pv": record["pv"],
"id": device.device_id,
@ -153,7 +156,7 @@ def get_device_discovery_info(device, upper_case_props=False, missing_csharp=Fal
"sf": 0x01, # record["sf"],
"sh": "",
},
}
)
if missing_csharp:
del result["properties"]["c#"]
@ -286,8 +289,8 @@ async def test_discovery_ignored_model(hass, controller):
"""Already paired."""
device = setup_mock_accessory(controller)
discovery_info = get_device_discovery_info(device)
discovery_info["properties"]["id"] = "AA:BB:CC:DD:EE:FF"
discovery_info["properties"]["md"] = "HHKBridge1,1"
discovery_info[zeroconf.ATTR_PROPERTIES]["id"] = "AA:BB:CC:DD:EE:FF"
discovery_info[zeroconf.ATTR_PROPERTIES]["md"] = "HHKBridge1,1"
# Device is discovered
result = await hass.config_entries.flow.async_init(
@ -314,7 +317,7 @@ async def test_discovery_ignored_hk_bridge(hass, controller):
connections={(device_registry.CONNECTION_NETWORK_MAC, formatted_mac)},
)
discovery_info["properties"]["id"] = "AA:BB:CC:DD:EE:FF"
discovery_info[zeroconf.ATTR_PROPERTIES]["id"] = "AA:BB:CC:DD:EE:FF"
# Device is discovered
result = await hass.config_entries.flow.async_init(
@ -341,7 +344,7 @@ async def test_discovery_does_not_ignore_non_homekit(hass, controller):
connections={(device_registry.CONNECTION_NETWORK_MAC, formatted_mac)},
)
discovery_info["properties"]["id"] = "AA:BB:CC:DD:EE:FF"
discovery_info[zeroconf.ATTR_PROPERTIES]["id"] = "AA:BB:CC:DD:EE:FF"
# Device is discovered
result = await hass.config_entries.flow.async_init(
@ -373,7 +376,7 @@ async def test_discovery_broken_pairing_flag(hass, controller):
discovery_info = get_device_discovery_info(device)
# Make sure that we are pairable
assert discovery_info["properties"]["sf"] != 0x0
assert discovery_info[zeroconf.ATTR_PROPERTIES]["sf"] != 0x0
# Device is discovered
result = await hass.config_entries.flow.async_init(
@ -445,7 +448,7 @@ async def test_discovery_already_configured(hass, controller):
discovery_info = get_device_discovery_info(device)
# Set device as already paired
discovery_info["properties"]["sf"] = 0x00
discovery_info[zeroconf.ATTR_PROPERTIES]["sf"] = 0x00
# Device is discovered
result = await hass.config_entries.flow.async_init(
@ -481,9 +484,9 @@ async def test_discovery_already_configured_update_csharp(hass, controller):
discovery_info = get_device_discovery_info(device)
# Set device as already paired
discovery_info["properties"]["sf"] = 0x00
discovery_info["properties"]["c#"] = 99999
discovery_info["properties"]["id"] = "AA:BB:CC:DD:EE:FF"
discovery_info[zeroconf.ATTR_PROPERTIES]["sf"] = 0x00
discovery_info[zeroconf.ATTR_PROPERTIES]["c#"] = 99999
discovery_info[zeroconf.ATTR_PROPERTIES]["id"] = "AA:BB:CC:DD:EE:FF"
# Device is discovered
result = await hass.config_entries.flow.async_init(