Ensure homekit setup messages run in event loop (#60226)

This commit is contained in:
J. Nick Koston 2021-11-23 11:40:20 -06:00 committed by GitHub
parent 9f74ad06d6
commit 400aaeaa91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 37 deletions

View File

@ -102,11 +102,11 @@ from .const import (
from .type_triggers import DeviceTriggerAccessory
from .util import (
accessory_friendly_name,
async_dismiss_setup_message,
async_port_is_available,
dismiss_setup_message,
async_show_setup_message,
get_persist_fullpath_for_entry_id,
remove_state_files_for_entry_id,
show_setup_message,
state_needs_accessory_mode,
validate_entity_config,
)
@ -321,7 +321,7 @@ async def _async_update_listener(hass: HomeAssistant, entry: ConfigEntry):
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
dismiss_setup_message(hass, entry.entry_id)
async_dismiss_setup_message(hass, entry.entry_id)
homekit = hass.data[DOMAIN][entry.entry_id][HOMEKIT]
if homekit.status == STATUS_RUNNING:
@ -719,7 +719,7 @@ class HomeKit:
@callback
def _async_show_setup_message(self):
"""Show the pairing setup message."""
show_setup_message(
async_show_setup_message(
self.hass,
self._entry_id,
accessory_friendly_name(self._entry_title, self.driver.accessory),

View File

@ -4,6 +4,7 @@ import logging
from pyhap.accessory import Accessory, Bridge
from pyhap.accessory_driver import AccessoryDriver
from pyhap.const import CATEGORY_OTHER
from pyhap.util import callback as pyhap_callback
from homeassistant.components import cover
from homeassistant.components.cover import (
@ -80,10 +81,10 @@ from .const import (
)
from .util import (
accessory_friendly_name,
async_dismiss_setup_message,
async_show_setup_message,
convert_to_float,
dismiss_setup_message,
format_sw_version,
show_setup_message,
validate_media_player_features,
)
@ -550,13 +551,15 @@ class HomeDriver(AccessoryDriver):
self._bridge_name = bridge_name
self._entry_title = entry_title
@pyhap_callback
def pair(self, client_uuid, client_public, client_permissions):
"""Override super function to dismiss setup message if paired."""
success = super().pair(client_uuid, client_public, client_permissions)
if success:
dismiss_setup_message(self.hass, self._entry_id)
async_dismiss_setup_message(self.hass, self._entry_id)
return success
@pyhap_callback
def unpair(self, client_uuid):
"""Override super function to show setup message if unpaired."""
super().unpair(client_uuid)
@ -564,7 +567,7 @@ class HomeDriver(AccessoryDriver):
if self.state.paired:
return
show_setup_message(
async_show_setup_message(
self.hass,
self._entry_id,
accessory_friendly_name(self._entry_title, self.accessory),

View File

@ -315,7 +315,7 @@ def validate_media_player_features(state, feature_list):
return True
def show_setup_message(hass, entry_id, bridge_name, pincode, uri):
def async_show_setup_message(hass, entry_id, bridge_name, pincode, uri):
"""Display persistent notification with setup information."""
pin = pincode.decode()
_LOGGER.info("Pincode: %s", pin)
@ -334,12 +334,14 @@ def show_setup_message(hass, entry_id, bridge_name, pincode, uri):
f"### {pin}\n"
f"![image](/api/homekit/pairingqr?{entry_id}-{pairing_secret})"
)
hass.components.persistent_notification.create(message, "HomeKit Pairing", entry_id)
hass.components.persistent_notification.async_create(
message, "HomeKit Pairing", entry_id
)
def dismiss_setup_message(hass, entry_id):
def async_dismiss_setup_message(hass, entry_id):
"""Dismiss persistent notification and remove QR code."""
hass.components.persistent_notification.dismiss(entry_id)
hass.components.persistent_notification.async_dismiss(entry_id)
def convert_to_float(state):

View File

@ -694,7 +694,7 @@ def test_home_driver():
# pair
with patch("pyhap.accessory_driver.AccessoryDriver.pair") as mock_pair, patch(
"homeassistant.components.homekit.accessories.dismiss_setup_message"
"homeassistant.components.homekit.accessories.async_dismiss_setup_message"
) as mock_dissmiss_msg:
driver.pair("client_uuid", "client_public", b"1")
@ -703,7 +703,7 @@ def test_home_driver():
# unpair
with patch("pyhap.accessory_driver.AccessoryDriver.unpair") as mock_unpair, patch(
"homeassistant.components.homekit.accessories.show_setup_message"
"homeassistant.components.homekit.accessories.async_show_setup_message"
) as mock_show_msg:
driver.unpair("client_uuid")

View File

@ -459,7 +459,7 @@ async def test_homekit_start(hass, hk_driver, mock_async_zeroconf, device_reg):
state = hass.states.async_all()[0]
with patch(f"{PATH_HOMEKIT}.HomeKit.add_bridge_accessory") as mock_add_acc, patch(
f"{PATH_HOMEKIT}.show_setup_message"
f"{PATH_HOMEKIT}.async_show_setup_message"
) as mock_setup_msg, patch(
"pyhap.accessory_driver.AccessoryDriver.async_start"
) as hk_driver_start:
@ -491,7 +491,7 @@ async def test_homekit_start(hass, hk_driver, mock_async_zeroconf, device_reg):
# Start again to make sure the registry entry is kept
homekit.status = STATUS_READY
with patch(f"{PATH_HOMEKIT}.HomeKit.add_bridge_accessory") as mock_add_acc, patch(
f"{PATH_HOMEKIT}.show_setup_message"
f"{PATH_HOMEKIT}.async_show_setup_message"
) as mock_setup_msg, patch(
"pyhap.accessory_driver.AccessoryDriver.async_start"
) as hk_driver_start:
@ -529,7 +529,7 @@ async def test_homekit_start_with_a_broken_accessory(
hass.states.async_set("light.broken", "on")
with patch(f"{PATH_HOMEKIT}.get_accessory", side_effect=Exception), patch(
f"{PATH_HOMEKIT}.show_setup_message"
f"{PATH_HOMEKIT}.async_show_setup_message"
) as mock_setup_msg, patch(
"pyhap.accessory_driver.AccessoryDriver.async_start"
) as hk_driver_start:
@ -568,7 +568,7 @@ async def test_homekit_start_with_a_device(
homekit.driver = hk_driver
with patch(f"{PATH_HOMEKIT}.get_accessory", side_effect=Exception), patch(
f"{PATH_HOMEKIT}.show_setup_message"
f"{PATH_HOMEKIT}.async_show_setup_message"
) as mock_setup_msg:
await homekit.async_start()
@ -1085,7 +1085,7 @@ async def test_homekit_too_many_accessories(
hass.states.async_set("light.demo3", "on")
with patch("pyhap.accessory_driver.AccessoryDriver.async_start"), patch(
f"{PATH_HOMEKIT}.show_setup_message"
f"{PATH_HOMEKIT}.async_show_setup_message"
), patch(f"{PATH_HOMEKIT}.HomeBridge", _mock_bridge):
await homekit.async_start()
await hass.async_block_till_done()
@ -1141,7 +1141,7 @@ async def test_homekit_finds_linked_batteries(
)
hass.states.async_set(light.entity_id, STATE_ON)
with patch(f"{PATH_HOMEKIT}.show_setup_message"), patch(
with patch(f"{PATH_HOMEKIT}.async_show_setup_message"), patch(
f"{PATH_HOMEKIT}.get_accessory"
) as mock_get_acc, patch("pyhap.accessory_driver.AccessoryDriver.async_start"):
await homekit.async_start()
@ -1211,7 +1211,7 @@ async def test_homekit_async_get_integration_fails(
hass.states.async_set(light.entity_id, STATE_ON)
with patch.object(homekit.bridge, "add_accessory"), patch(
f"{PATH_HOMEKIT}.show_setup_message"
f"{PATH_HOMEKIT}.async_show_setup_message"
), patch(f"{PATH_HOMEKIT}.get_accessory") as mock_get_acc, patch(
"pyhap.accessory_driver.AccessoryDriver.async_start"
):
@ -1418,7 +1418,7 @@ async def test_homekit_finds_linked_motion_sensors(
hass.states.async_set(camera.entity_id, STATE_ON)
with patch.object(homekit.bridge, "add_accessory"), patch(
f"{PATH_HOMEKIT}.show_setup_message"
f"{PATH_HOMEKIT}.async_show_setup_message"
), patch(f"{PATH_HOMEKIT}.get_accessory") as mock_get_acc, patch(
"pyhap.accessory_driver.AccessoryDriver.async_start"
):
@ -1483,7 +1483,7 @@ async def test_homekit_finds_linked_humidity_sensors(
hass.states.async_set(humidifier.entity_id, STATE_ON)
with patch.object(homekit.bridge, "add_accessory"), patch(
f"{PATH_HOMEKIT}.show_setup_message"
f"{PATH_HOMEKIT}.async_show_setup_message"
), patch(f"{PATH_HOMEKIT}.get_accessory") as mock_get_acc, patch(
"pyhap.accessory_driver.AccessoryDriver.async_start"
):
@ -1543,7 +1543,7 @@ async def test_reload(hass, mock_async_zeroconf):
with patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path), patch(
f"{PATH_HOMEKIT}.HomeKit"
) as mock_homekit2, patch.object(homekit.bridge, "add_accessory"), patch(
f"{PATH_HOMEKIT}.show_setup_message"
f"{PATH_HOMEKIT}.async_show_setup_message"
), patch(
f"{PATH_HOMEKIT}.get_accessory"
), patch(
@ -1592,7 +1592,7 @@ async def test_homekit_start_in_accessory_mode(
hass.states.async_set("light.demo", "on")
with patch(f"{PATH_HOMEKIT}.HomeKit.add_bridge_accessory") as mock_add_acc, patch(
f"{PATH_HOMEKIT}.show_setup_message"
f"{PATH_HOMEKIT}.async_show_setup_message"
) as mock_setup_msg, patch(
"pyhap.accessory_driver.AccessoryDriver.async_start"
) as hk_driver_start:
@ -1623,7 +1623,7 @@ async def test_homekit_start_in_accessory_mode_unsupported_entity(
hass.states.async_set("notsupported.demo", "on")
with patch(f"{PATH_HOMEKIT}.HomeKit.add_bridge_accessory") as mock_add_acc, patch(
f"{PATH_HOMEKIT}.show_setup_message"
f"{PATH_HOMEKIT}.async_show_setup_message"
) as mock_setup_msg, patch(
"pyhap.accessory_driver.AccessoryDriver.async_start"
) as hk_driver_start:
@ -1651,7 +1651,7 @@ async def test_homekit_start_in_accessory_mode_missing_entity(
homekit.driver.accessory = Accessory(hk_driver, "any")
with patch(f"{PATH_HOMEKIT}.HomeKit.add_bridge_accessory") as mock_add_acc, patch(
f"{PATH_HOMEKIT}.show_setup_message"
f"{PATH_HOMEKIT}.async_show_setup_message"
), patch("pyhap.accessory_driver.AccessoryDriver.async_start"):
await homekit.async_start()

View File

@ -25,21 +25,21 @@ from homeassistant.components.homekit.const import (
)
from homeassistant.components.homekit.util import (
accessory_friendly_name,
async_dismiss_setup_message,
async_find_next_available_port,
async_port_is_available,
async_show_setup_message,
cleanup_name_for_homekit,
convert_to_float,
density_to_air_quality,
dismiss_setup_message,
format_sw_version,
show_setup_message,
state_needs_accessory_mode,
temperature_to_homekit,
temperature_to_states,
validate_entity_config as vec,
validate_media_player_features,
)
from homeassistant.components.persistent_notification import create, dismiss
from homeassistant.components.persistent_notification import async_create, async_dismiss
from homeassistant.const import (
ATTR_CODE,
ATTR_SUPPORTED_FEATURES,
@ -231,7 +231,7 @@ def test_density_to_air_quality():
assert density_to_air_quality(300) == 5
async def test_show_setup_msg(hass, hk_driver, mock_get_source_ip):
async def test_async_show_setup_msg(hass, hk_driver, mock_get_source_ip):
"""Test show setup message as persistence notification."""
pincode = b"123-45-678"
@ -239,10 +239,11 @@ async def test_show_setup_msg(hass, hk_driver, mock_get_source_ip):
assert entry
with patch(
"homeassistant.components.persistent_notification.create", side_effect=create
"homeassistant.components.persistent_notification.async_create",
side_effect=async_create,
) as mock_create:
await hass.async_add_executor_job(
show_setup_message, hass, entry.entry_id, "bridge_name", pincode, "X-HM://0"
async_show_setup_message(
hass, entry.entry_id, "bridge_name", pincode, "X-HM://0"
)
await hass.async_block_till_done()
assert hass.data[DOMAIN][entry.entry_id][HOMEKIT_PAIRING_QR_SECRET]
@ -253,12 +254,13 @@ async def test_show_setup_msg(hass, hk_driver, mock_get_source_ip):
assert pincode.decode() in mock_create.mock_calls[0][1][1]
async def test_dismiss_setup_msg(hass):
async def test_async_dismiss_setup_msg(hass):
"""Test dismiss setup message."""
with patch(
"homeassistant.components.persistent_notification.dismiss", side_effect=dismiss
"homeassistant.components.persistent_notification.async_dismiss",
side_effect=async_dismiss,
) as mock_dismiss:
await hass.async_add_executor_job(dismiss_setup_message, hass, "entry_id")
async_dismiss_setup_message(hass, "entry_id")
await hass.async_block_till_done()
assert len(mock_dismiss.mock_calls) == 1