From cd5b69d02ee4a5fad5e2aa64e9708c89765591c7 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 16 Feb 2022 07:54:59 -0800 Subject: [PATCH] Add Google local indicator (#66610) --- homeassistant/components/cloud/http_api.py | 1 + .../components/google_assistant/helpers.py | 13 +++++++++++++ .../components/google_assistant/smart_home.py | 2 +- tests/components/cloud/test_http_api.py | 1 + tests/components/google_assistant/test_helpers.py | 10 ++++++++++ 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/cloud/http_api.py b/homeassistant/components/cloud/http_api.py index 517d6b2bb9b..f51266e45dc 100644 --- a/homeassistant/components/cloud/http_api.py +++ b/homeassistant/components/cloud/http_api.py @@ -441,6 +441,7 @@ async def _account_data(hass: HomeAssistant, cloud: Cloud): "email": claims["email"], "google_entities": client.google_user_config["filter"].config, "google_registered": google_config.has_registered_user_agent, + "google_local_connected": google_config.is_local_connected, "logged_in": True, "prefs": client.prefs.as_dict(), "remote_certificate": certificate, diff --git a/homeassistant/components/google_assistant/helpers.py b/homeassistant/components/google_assistant/helpers.py index b2201196917..a348299e282 100644 --- a/homeassistant/components/google_assistant/helpers.py +++ b/homeassistant/components/google_assistant/helpers.py @@ -4,6 +4,7 @@ from __future__ import annotations from abc import ABC, abstractmethod from asyncio import gather from collections.abc import Mapping +from datetime import datetime, timedelta from http import HTTPStatus import logging import pprint @@ -26,6 +27,7 @@ from homeassistant.helpers.entity_registry import RegistryEntry from homeassistant.helpers.event import async_call_later from homeassistant.helpers.network import get_url from homeassistant.helpers.storage import Store +from homeassistant.util.dt import utcnow from . import trait from .const import ( @@ -104,6 +106,7 @@ class AbstractConfig(ABC): self._store = None self._google_sync_unsub = {} self._local_sdk_active = False + self._local_last_active: datetime | None = None async def async_initialize(self): """Perform async initialization of config.""" @@ -149,6 +152,15 @@ class AbstractConfig(ABC): """Return if states should be proactively reported.""" return False + @property + def is_local_connected(self) -> bool: + """Return if local is connected.""" + return ( + self._local_last_active is not None + # We get a reachable devices intent every minute. + and self._local_last_active > utcnow() - timedelta(seconds=70) + ) + def get_local_agent_user_id(self, webhook_id): """Return the user ID to be used for actions received via the local SDK. @@ -336,6 +348,7 @@ class AbstractConfig(ABC): # pylint: disable=import-outside-toplevel from . import smart_home + self._local_last_active = utcnow() payload = await request.json() if _LOGGER.isEnabledFor(logging.DEBUG): diff --git a/homeassistant/components/google_assistant/smart_home.py b/homeassistant/components/google_assistant/smart_home.py index 31fd02544ff..80bc61cc61d 100644 --- a/homeassistant/components/google_assistant/smart_home.py +++ b/homeassistant/components/google_assistant/smart_home.py @@ -281,7 +281,7 @@ async def async_devices_identify(hass, data: RequestData, payload): async def async_devices_reachable(hass, data: RequestData, payload): """Handle action.devices.REACHABLE_DEVICES request. - https://developers.google.com/actions/smarthome/create#actiondevicesdisconnect + https://developers.google.com/assistant/smarthome/develop/local#implement_the_reachable_devices_handler_hub_integrations_only """ google_ids = {dev["id"] for dev in (data.devices or [])} diff --git a/tests/components/cloud/test_http_api.py b/tests/components/cloud/test_http_api.py index 07b87632f19..e06344827a7 100644 --- a/tests/components/cloud/test_http_api.py +++ b/tests/components/cloud/test_http_api.py @@ -424,6 +424,7 @@ async def test_websocket_status( "exclude_entities": [], }, "google_registered": False, + "google_local_connected": False, "remote_domain": None, "remote_connected": False, "remote_certificate": None, diff --git a/tests/components/google_assistant/test_helpers.py b/tests/components/google_assistant/test_helpers.py index ff441e44f25..dc29e5df4ab 100644 --- a/tests/components/google_assistant/test_helpers.py +++ b/tests/components/google_assistant/test_helpers.py @@ -94,7 +94,9 @@ async def test_config_local_sdk(hass, hass_client): client = await hass_client() + assert config.is_local_connected is False config.async_enable_local_sdk() + assert config.is_local_connected is False resp = await client.post( "/api/webhook/mock-webhook-id", @@ -122,6 +124,14 @@ async def test_config_local_sdk(hass, hass_client): "requestId": "mock-req-id", }, ) + + assert config.is_local_connected is True + with patch( + "homeassistant.components.google_assistant.helpers.utcnow", + return_value=dt.utcnow() + timedelta(seconds=90), + ): + assert config.is_local_connected is False + assert resp.status == HTTPStatus.OK result = await resp.json() assert result["requestId"] == "mock-req-id"