From e234fc6e7e33f356e209307ae83e351244502d04 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 14 Apr 2021 21:47:15 -1000 Subject: [PATCH] Disconnect homekit_controller devices on the stop event (#49244) --- .../components/homekit_controller/__init__.py | 12 ++++++++ .../homekit_controller/test_init.py | 29 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 tests/components/homekit_controller/test_init.py diff --git a/homeassistant/components/homekit_controller/__init__.py b/homeassistant/components/homekit_controller/__init__.py index d7b28036426..3db6c1800c9 100644 --- a/homeassistant/components/homekit_controller/__init__.py +++ b/homeassistant/components/homekit_controller/__init__.py @@ -1,6 +1,7 @@ """Support for Homekit device discovery.""" from __future__ import annotations +import asyncio from typing import Any import aiohomekit @@ -13,6 +14,7 @@ from aiohomekit.model.characteristics import ( from aiohomekit.model.services import Service, ServicesTypes from homeassistant.components import zeroconf +from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers.entity import Entity @@ -228,6 +230,16 @@ async def async_setup(hass, config): hass.data[KNOWN_DEVICES] = {} hass.data[TRIGGERS] = {} + async def _async_stop_homekit_controller(event): + await asyncio.gather( + *[ + connection.async_unload() + for connection in hass.data[KNOWN_DEVICES].values() + ] + ) + + hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _async_stop_homekit_controller) + return True diff --git a/tests/components/homekit_controller/test_init.py b/tests/components/homekit_controller/test_init.py new file mode 100644 index 00000000000..cd5662d73c9 --- /dev/null +++ b/tests/components/homekit_controller/test_init.py @@ -0,0 +1,29 @@ +"""Tests for homekit_controller init.""" + +from unittest.mock import patch + +from aiohomekit.model.characteristics import CharacteristicsTypes +from aiohomekit.model.services import ServicesTypes + +from homeassistant.const import EVENT_HOMEASSISTANT_STOP + +from tests.components.homekit_controller.common import setup_test_component + + +def create_motion_sensor_service(accessory): + """Define motion characteristics as per page 225 of HAP spec.""" + service = accessory.add_service(ServicesTypes.MOTION_SENSOR) + cur_state = service.add_char(CharacteristicsTypes.MOTION_DETECTED) + cur_state.value = 0 + + +async def test_unload_on_stop(hass, utcnow): + """Test async_unload is called on stop.""" + await setup_test_component(hass, create_motion_sensor_service) + with patch( + "homeassistant.components.homekit_controller.HKDevice.async_unload" + ) as async_unlock_mock: + hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP) + await hass.async_block_till_done() + + assert async_unlock_mock.called