Reload nest integration when new devices are added (#62976)

This commit is contained in:
Allen Porter 2021-12-29 03:20:55 -08:00 committed by GitHub
parent d62f9a19ae
commit 2df0adfbc7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 2 deletions

View File

@ -1,6 +1,7 @@
"""Support for Nest devices."""
from __future__ import annotations
from collections.abc import Awaitable, Callable
from http import HTTPStatus
import logging
@ -178,12 +179,21 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
class SignalUpdateCallback:
"""An EventCallback invoked when new events arrive from subscriber."""
def __init__(self, hass: HomeAssistant) -> None:
def __init__(
self, hass: HomeAssistant, config_reload_cb: Callable[[], Awaitable[None]]
) -> None:
"""Initialize EventCallback."""
self._hass = hass
self._config_reload_cb = config_reload_cb
async def async_handle_event(self, event_message: EventMessage) -> None:
"""Process an incoming EventMessage."""
if event_message.relation_update:
# A device was added/removed or a home was added/removed. Reload the integration
# in order to detect any changes.
_LOGGER.info("Devices or homes have changed; Reloading")
self._hass.async_create_task(self._config_reload_cb())
return
if not event_message.resource_update_name:
return
device_id = event_message.resource_update_name
@ -221,7 +231,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
# Use disk backed event media store
subscriber.cache_policy.store = await async_get_media_event_store(hass, subscriber)
callback = SignalUpdateCallback(hass)
async def async_config_reload() -> None:
await hass.config_entries.async_reload(entry.entry_id)
callback = SignalUpdateCallback(hass, async_config_reload)
subscriber.set_update_callback(callback.async_handle_event)
try:
await subscriber.start_async()

View File

@ -5,6 +5,7 @@ pubsub subscriber.
"""
import datetime
from unittest.mock import patch
from google_nest_sdm.device import Device
from google_nest_sdm.event import EventMessage
@ -446,3 +447,65 @@ async def test_doorbell_event_session_update(hass):
"timestamp": timestamp2.replace(microsecond=0),
"nest_event_id": EVENT_SESSION_ID,
}
async def test_structure_update_event(hass):
"""Test a pubsub message for a new device being added."""
events = async_capture_events(hass, NEST_EVENT)
subscriber = await async_setup_devices(
hass,
"sdm.devices.types.DOORBELL",
create_device_traits(["sdm.devices.traits.DoorbellChime"]),
)
# Entity for first device is registered
registry = er.async_get(hass)
assert registry.async_get("camera.front")
new_device = Device.MakeDevice(
{
"name": "device-id-2",
"type": "sdm.devices.types.CAMERA",
"traits": {
"sdm.devices.traits.Info": {
"customName": "Back",
},
"sdm.devices.traits.CameraLiveStream": {},
},
},
auth=None,
)
device_manager = await subscriber.async_get_device_manager()
device_manager.add_device(new_device)
# Entity for new devie has not yet been loaded
assert not registry.async_get("camera.back")
# Send a message that triggers the device to be loaded
message = EventMessage(
{
"eventId": "some-event-id",
"timestamp": utcnow().isoformat(timespec="seconds"),
"relationUpdate": {
"type": "CREATED",
"subject": "enterprise/example/foo",
"object": "enterprise/example/devices/some-device-id2",
},
},
auth=None,
)
with patch(
"homeassistant.helpers.config_entry_oauth2_flow.async_get_config_entry_implementation"
), patch("homeassistant.components.nest.PLATFORMS", [PLATFORM]), patch(
"homeassistant.components.nest.api.GoogleNestSubscriber",
return_value=subscriber,
):
await subscriber.async_receive_event(message)
await hass.async_block_till_done()
# No home assistant events published
assert not events
# Both enties now exist
assert registry.async_get("camera.front")
assert registry.async_get("camera.back")