Migrate homekit to use async_at_started (#113102)
This commit is contained in:
parent
5dc44500c3
commit
6e59d1cb29
4 changed files with 112 additions and 103 deletions
|
@ -45,13 +45,11 @@ from homeassistant.const import (
|
||||||
CONF_IP_ADDRESS,
|
CONF_IP_ADDRESS,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_PORT,
|
CONF_PORT,
|
||||||
EVENT_HOMEASSISTANT_STARTED,
|
|
||||||
EVENT_HOMEASSISTANT_STOP,
|
EVENT_HOMEASSISTANT_STOP,
|
||||||
SERVICE_RELOAD,
|
SERVICE_RELOAD,
|
||||||
)
|
)
|
||||||
from homeassistant.core import (
|
from homeassistant.core import (
|
||||||
CALLBACK_TYPE,
|
CALLBACK_TYPE,
|
||||||
CoreState,
|
|
||||||
HomeAssistant,
|
HomeAssistant,
|
||||||
ServiceCall,
|
ServiceCall,
|
||||||
State,
|
State,
|
||||||
|
@ -75,6 +73,7 @@ from homeassistant.helpers.service import (
|
||||||
async_extract_referenced_entity_ids,
|
async_extract_referenced_entity_ids,
|
||||||
async_register_admin_service,
|
async_register_admin_service,
|
||||||
)
|
)
|
||||||
|
from homeassistant.helpers.start import async_at_started
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.loader import IntegrationNotFound, async_get_integration
|
from homeassistant.loader import IntegrationNotFound, async_get_integration
|
||||||
|
|
||||||
|
@ -358,10 +357,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
)
|
)
|
||||||
hass.data[DOMAIN][entry.entry_id] = entry_data
|
hass.data[DOMAIN][entry.entry_id] = entry_data
|
||||||
|
|
||||||
if hass.state is CoreState.running:
|
async def _async_start_homekit(hass: HomeAssistant) -> None:
|
||||||
await homekit.async_start()
|
await homekit.async_start()
|
||||||
else:
|
|
||||||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, homekit.async_start)
|
entry.async_on_unload(async_at_started(hass, _async_start_homekit))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -553,7 +552,6 @@ class HomeKit:
|
||||||
"""Set up bridge and accessory driver."""
|
"""Set up bridge and accessory driver."""
|
||||||
assert self.iid_storage is not None
|
assert self.iid_storage is not None
|
||||||
persist_file = get_persist_fullpath_for_entry_id(self.hass, self._entry_id)
|
persist_file = get_persist_fullpath_for_entry_id(self.hass, self._entry_id)
|
||||||
|
|
||||||
self.driver = HomeDriver(
|
self.driver = HomeDriver(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._entry_id,
|
self._entry_id,
|
||||||
|
@ -569,7 +567,6 @@ class HomeKit:
|
||||||
loader=get_loader(),
|
loader=get_loader(),
|
||||||
iid_storage=self.iid_storage,
|
iid_storage=self.iid_storage,
|
||||||
)
|
)
|
||||||
|
|
||||||
# If we do not load the mac address will be wrong
|
# If we do not load the mac address will be wrong
|
||||||
# as pyhap uses a random one until state is restored
|
# as pyhap uses a random one until state is restored
|
||||||
if os.path.exists(persist_file):
|
if os.path.exists(persist_file):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""Test the HomeKit config flow."""
|
"""Test the HomeKit config flow."""
|
||||||
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import AsyncMock, Mock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
@ -428,62 +428,68 @@ async def test_options_flow_devices(
|
||||||
demo_config_entry = MockConfigEntry(domain="domain")
|
demo_config_entry = MockConfigEntry(domain="domain")
|
||||||
demo_config_entry.add_to_hass(hass)
|
demo_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
assert await async_setup_component(hass, "homeassistant", {})
|
with patch("homeassistant.components.homekit.HomeKit") as mock_homekit:
|
||||||
assert await async_setup_component(hass, "demo", {"demo": {}})
|
mock_homekit.return_value = homekit = Mock()
|
||||||
assert await async_setup_component(hass, "homekit", {"homekit": {}})
|
type(homekit).async_start = AsyncMock()
|
||||||
|
assert await async_setup_component(hass, "homekit", {"homekit": {}})
|
||||||
|
assert await async_setup_component(hass, "homeassistant", {})
|
||||||
|
assert await async_setup_component(hass, "demo", {"demo": {}})
|
||||||
|
assert await async_setup_component(hass, "homekit", {"homekit": {}})
|
||||||
|
|
||||||
hass.states.async_set("climate.old", "off")
|
hass.states.async_set("climate.old", "off")
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
result = await hass.config_entries.options.async_init(
|
result = await hass.config_entries.options.async_init(
|
||||||
config_entry.entry_id, context={"show_advanced_options": True}
|
config_entry.entry_id, context={"show_advanced_options": True}
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
|
||||||
assert result["step_id"] == "init"
|
|
||||||
|
|
||||||
result = await hass.config_entries.options.async_configure(
|
|
||||||
result["flow_id"],
|
|
||||||
user_input={
|
|
||||||
"domains": ["fan", "vacuum", "climate"],
|
|
||||||
"include_exclude_mode": "exclude",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
|
||||||
assert result["step_id"] == "exclude"
|
|
||||||
|
|
||||||
entry = entity_registry.async_get("light.ceiling_lights")
|
|
||||||
assert entry is not None
|
|
||||||
device_id = entry.device_id
|
|
||||||
|
|
||||||
result2 = await hass.config_entries.options.async_configure(
|
|
||||||
result["flow_id"],
|
|
||||||
user_input={
|
|
||||||
"entities": ["climate.old"],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
with patch("homeassistant.components.homekit.async_setup_entry", return_value=True):
|
|
||||||
result3 = await hass.config_entries.options.async_configure(
|
|
||||||
result2["flow_id"],
|
|
||||||
user_input={"devices": [device_id]},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result3["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||||
assert config_entry.options == {
|
assert result["step_id"] == "init"
|
||||||
"devices": [device_id],
|
|
||||||
"mode": "bridge",
|
|
||||||
"filter": {
|
|
||||||
"exclude_domains": [],
|
|
||||||
"exclude_entities": ["climate.old"],
|
|
||||||
"include_domains": ["fan", "vacuum", "climate"],
|
|
||||||
"include_entities": [],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
result = await hass.config_entries.options.async_configure(
|
||||||
await hass.config_entries.async_unload(config_entry.entry_id)
|
result["flow_id"],
|
||||||
|
user_input={
|
||||||
|
"domains": ["fan", "vacuum", "climate"],
|
||||||
|
"include_exclude_mode": "exclude",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||||
|
assert result["step_id"] == "exclude"
|
||||||
|
|
||||||
|
entry = entity_registry.async_get("light.ceiling_lights")
|
||||||
|
assert entry is not None
|
||||||
|
device_id = entry.device_id
|
||||||
|
|
||||||
|
result2 = await hass.config_entries.options.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={
|
||||||
|
"entities": ["climate.old"],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.homekit.async_setup_entry", return_value=True
|
||||||
|
):
|
||||||
|
result3 = await hass.config_entries.options.async_configure(
|
||||||
|
result2["flow_id"],
|
||||||
|
user_input={"devices": [device_id]},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result3["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
||||||
|
assert config_entry.options == {
|
||||||
|
"devices": [device_id],
|
||||||
|
"mode": "bridge",
|
||||||
|
"filter": {
|
||||||
|
"exclude_domains": [],
|
||||||
|
"exclude_entities": ["climate.old"],
|
||||||
|
"include_domains": ["fan", "vacuum", "climate"],
|
||||||
|
"include_entities": [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
await hass.config_entries.async_unload(config_entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
@patch(f"{PATH_HOMEKIT}.async_port_is_available", return_value=True)
|
@patch(f"{PATH_HOMEKIT}.async_port_is_available", return_value=True)
|
||||||
|
@ -514,49 +520,53 @@ async def test_options_flow_devices_preserved_when_advanced_off(
|
||||||
demo_config_entry = MockConfigEntry(domain="domain")
|
demo_config_entry = MockConfigEntry(domain="domain")
|
||||||
demo_config_entry.add_to_hass(hass)
|
demo_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
assert await async_setup_component(hass, "homekit", {"homekit": {}})
|
with patch("homeassistant.components.homekit.HomeKit") as mock_homekit:
|
||||||
|
mock_homekit.return_value = homekit = Mock()
|
||||||
|
type(homekit).async_start = AsyncMock()
|
||||||
|
assert await async_setup_component(hass, "homekit", {"homekit": {}})
|
||||||
|
|
||||||
hass.states.async_set("climate.old", "off")
|
hass.states.async_set("climate.old", "off")
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
result = await hass.config_entries.options.async_init(
|
result = await hass.config_entries.options.async_init(
|
||||||
config_entry.entry_id, context={"show_advanced_options": False}
|
config_entry.entry_id, context={"show_advanced_options": False}
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||||
assert result["step_id"] == "init"
|
assert result["step_id"] == "init"
|
||||||
|
|
||||||
result = await hass.config_entries.options.async_configure(
|
result = await hass.config_entries.options.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
user_input={
|
user_input={
|
||||||
"domains": ["fan", "vacuum", "climate"],
|
"domains": ["fan", "vacuum", "climate"],
|
||||||
"include_exclude_mode": "exclude",
|
"include_exclude_mode": "exclude",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||||
assert result["step_id"] == "exclude"
|
assert result["step_id"] == "exclude"
|
||||||
|
|
||||||
result2 = await hass.config_entries.options.async_configure(
|
result2 = await hass.config_entries.options.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
user_input={
|
user_input={
|
||||||
"entities": ["climate.old"],
|
"entities": ["climate.old"],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result2["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
assert result2["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
||||||
assert config_entry.options == {
|
assert config_entry.options == {
|
||||||
"devices": ["1fabcabcabcabcabcabcabcabcabc"],
|
"devices": ["1fabcabcabcabcabcabcabcabcabc"],
|
||||||
"mode": "bridge",
|
"mode": "bridge",
|
||||||
"filter": {
|
"filter": {
|
||||||
"exclude_domains": [],
|
"exclude_domains": [],
|
||||||
"exclude_entities": ["climate.old"],
|
"exclude_entities": ["climate.old"],
|
||||||
"include_domains": ["fan", "vacuum", "climate"],
|
"include_domains": ["fan", "vacuum", "climate"],
|
||||||
"include_entities": [],
|
"include_entities": [],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
await hass.config_entries.async_unload(config_entry.entry_id)
|
await hass.config_entries.async_unload(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
||||||
async def test_options_flow_include_mode_with_non_existant_entity(
|
async def test_options_flow_include_mode_with_non_existant_entity(
|
||||||
|
|
|
@ -347,7 +347,7 @@ async def test_homekit_with_single_advertise_ips(
|
||||||
)
|
)
|
||||||
entry.add_to_hass(hass)
|
entry.add_to_hass(hass)
|
||||||
with patch(f"{PATH_HOMEKIT}.HomeDriver", return_value=hk_driver) as mock_driver:
|
with patch(f"{PATH_HOMEKIT}.HomeDriver", return_value=hk_driver) as mock_driver:
|
||||||
mock_driver.async_start = AsyncMock()
|
hk_driver.async_start = AsyncMock()
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -386,7 +386,7 @@ async def test_homekit_with_many_advertise_ips(
|
||||||
)
|
)
|
||||||
entry.add_to_hass(hass)
|
entry.add_to_hass(hass)
|
||||||
with patch(f"{PATH_HOMEKIT}.HomeDriver", return_value=hk_driver) as mock_driver:
|
with patch(f"{PATH_HOMEKIT}.HomeDriver", return_value=hk_driver) as mock_driver:
|
||||||
mock_driver.async_start = AsyncMock()
|
hk_driver.async_start = AsyncMock()
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -2043,6 +2043,7 @@ async def test_reload(hass: HomeAssistant, mock_async_zeroconf: None) -> None:
|
||||||
"homeassistant.components.network.async_get_source_ip", return_value="1.2.3.4"
|
"homeassistant.components.network.async_get_source_ip", return_value="1.2.3.4"
|
||||||
):
|
):
|
||||||
mock_homekit.return_value = homekit = Mock()
|
mock_homekit.return_value = homekit = Mock()
|
||||||
|
type(homekit).async_start = AsyncMock()
|
||||||
assert await async_setup_component(
|
assert await async_setup_component(
|
||||||
hass, "homekit", {"homekit": {CONF_NAME: "reloadable", CONF_PORT: 12345}}
|
hass, "homekit", {"homekit": {CONF_NAME: "reloadable", CONF_PORT: 12345}}
|
||||||
)
|
)
|
||||||
|
@ -2065,16 +2066,15 @@ async def test_reload(hass: HomeAssistant, mock_async_zeroconf: None) -> None:
|
||||||
yaml_path = get_fixture_path("configuration.yaml", "homekit")
|
yaml_path = get_fixture_path("configuration.yaml", "homekit")
|
||||||
with patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path), patch(
|
with patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path), patch(
|
||||||
f"{PATH_HOMEKIT}.HomeKit"
|
f"{PATH_HOMEKIT}.HomeKit"
|
||||||
) as mock_homekit2, patch.object(homekit.bridge, "add_accessory"), patch(
|
) as mock_homekit2, patch(f"{PATH_HOMEKIT}.async_show_setup_message"), patch(
|
||||||
f"{PATH_HOMEKIT}.async_show_setup_message"
|
|
||||||
), patch(
|
|
||||||
f"{PATH_HOMEKIT}.get_accessory",
|
f"{PATH_HOMEKIT}.get_accessory",
|
||||||
), patch(
|
), patch(f"{PATH_HOMEKIT}.async_port_is_available", return_value=True), patch(
|
||||||
"pyhap.accessory_driver.AccessoryDriver.async_start",
|
"pyhap.accessory_driver.AccessoryDriver.async_start",
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.network.async_get_source_ip", return_value="1.2.3.4"
|
"homeassistant.components.network.async_get_source_ip", return_value="1.2.3.4"
|
||||||
):
|
):
|
||||||
mock_homekit2.return_value = homekit = Mock()
|
mock_homekit2.return_value = homekit = Mock()
|
||||||
|
type(homekit).async_start = AsyncMock()
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
"homekit",
|
"homekit",
|
||||||
SERVICE_RELOAD,
|
SERVICE_RELOAD,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""Test HomeKit initialization."""
|
"""Test HomeKit initialization."""
|
||||||
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import AsyncMock, Mock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
@ -31,7 +31,9 @@ async def test_humanify_homekit_changed_event(
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test humanifying HomeKit changed event."""
|
"""Test humanifying HomeKit changed event."""
|
||||||
hass.config.components.add("recorder")
|
hass.config.components.add("recorder")
|
||||||
with patch("homeassistant.components.homekit.HomeKit"):
|
with patch("homeassistant.components.homekit.HomeKit") as mock_homekit:
|
||||||
|
mock_homekit.return_value = homekit = Mock()
|
||||||
|
type(homekit).async_start = AsyncMock()
|
||||||
assert await async_setup_component(hass, "homekit", {"homekit": {}})
|
assert await async_setup_component(hass, "homekit", {"homekit": {}})
|
||||||
assert await async_setup_component(hass, "logbook", {})
|
assert await async_setup_component(hass, "logbook", {})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue