Skip to content
Permalink
Browse files

Homekit should skip devices that are missing in device registry (#35857)

* Homekit should skip devices that are missing in device registry

* Add test for this failure state
  • Loading branch information
bdraco authored and pvizeli committed May 21, 2020
1 parent 813203a commit 1c38bcaeb52d4ad4c7847ea58abb29a7b14e6dea
Showing with 88 additions and 6 deletions.
  1. +8 −6 homeassistant/components/homekit/__init__.py
  2. +80 −0 tests/components/homekit/test_homekit.py
@@ -627,12 +627,14 @@ async def _async_set_device_info_attributes(self, ent_reg_ent, dev_reg, entity_i
ent_cfg = self._config.setdefault(entity_id, {})
if ent_reg_ent.device_id:
dev_reg_ent = dev_reg.async_get(ent_reg_ent.device_id)
if dev_reg_ent.manufacturer:
ent_cfg[ATTR_MANUFACTURER] = dev_reg_ent.manufacturer
if dev_reg_ent.model:
ent_cfg[ATTR_MODEL] = dev_reg_ent.model
if dev_reg_ent.sw_version:
ent_cfg[ATTR_SOFTWARE_VERSION] = dev_reg_ent.sw_version
if dev_reg_ent is not None:
# Handle missing devices
if dev_reg_ent.manufacturer:
ent_cfg[ATTR_MANUFACTURER] = dev_reg_ent.manufacturer
if dev_reg_ent.model:
ent_cfg[ATTR_MODEL] = dev_reg_ent.model
if dev_reg_ent.sw_version:
ent_cfg[ATTR_SOFTWARE_VERSION] = dev_reg_ent.sw_version
if ATTR_MANUFACTURER not in ent_cfg:
integration = await async_get_integration(self.hass, ent_reg_ent.platform)
ent_cfg[ATTR_INTERGRATION] = integration.name
@@ -913,3 +913,83 @@ def _write_data(path: str, data: Dict) -> None:
if not os.path.isdir(os.path.dirname(path)):
os.makedirs(os.path.dirname(path))
json_util.save_json(path, data)


async def test_homekit_ignored_missing_devices(
hass, hk_driver, debounce_patcher, device_reg, entity_reg
):
"""Test HomeKit handles a device in the entity registry but missing from the device registry."""
entry = await async_init_integration(hass)

homekit = HomeKit(
hass,
None,
None,
None,
{},
{"light.demo": {}},
DEFAULT_SAFE_MODE,
advertise_ip=None,
interface_choice=None,
entry_id=entry.entry_id,
)
homekit.driver = hk_driver
homekit._filter = Mock(return_value=True)
homekit.bridge = HomeBridge(hass, hk_driver, "mock_bridge")

config_entry = MockConfigEntry(domain="test", data={})
config_entry.add_to_hass(hass)
device_entry = device_reg.async_get_or_create(
config_entry_id=config_entry.entry_id,
sw_version="0.16.0",
model="Powerwall 2",
manufacturer="Tesla",
connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
)

entity_reg.async_get_or_create(
"binary_sensor",
"powerwall",
"battery_charging",
device_id=device_entry.id,
device_class=DEVICE_CLASS_BATTERY_CHARGING,
)
entity_reg.async_get_or_create(
"sensor",
"powerwall",
"battery",
device_id=device_entry.id,
device_class=DEVICE_CLASS_BATTERY,
)
light = entity_reg.async_get_or_create(
"light", "powerwall", "demo", device_id=device_entry.id
)

# Delete the device to make sure we fallback
# to using the platform
device_reg.async_remove_device(device_entry.id)

hass.states.async_set(light.entity_id, STATE_ON)

def _mock_get_accessory(*args, **kwargs):
return [None, "acc", None]

with patch.object(homekit.bridge, "add_accessory"), patch(
f"{PATH_HOMEKIT}.show_setup_message"
), patch(f"{PATH_HOMEKIT}.get_accessory") as mock_get_acc, patch(
"pyhap.accessory_driver.AccessoryDriver.start"
):
await homekit.async_start()
await hass.async_block_till_done()

mock_get_acc.assert_called_with(
hass,
hk_driver,
ANY,
ANY,
{
"platform": "Tesla Powerwall",
"linked_battery_charging_sensor": "binary_sensor.powerwall_battery_charging",
"linked_battery_sensor": "sensor.powerwall_battery",
},
)

0 comments on commit 1c38bca

Please sign in to comment.
You can’t perform that action at this time.