From a51e0d7a5f4e470d3f8e64ff0db1da2d440a5d72 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 8 Oct 2019 09:58:36 -0700 Subject: [PATCH] Google: Report all states on activating report state (#27312) --- .../components/google_assistant/helpers.py | 5 +++ .../google_assistant/report_state.py | 24 +++++++++++++- .../google_assistant/test_report_state.py | 31 ++++++++++++++++--- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/google_assistant/helpers.py b/homeassistant/components/google_assistant/helpers.py index 207194d79ed..933f0c07999 100644 --- a/homeassistant/components/google_assistant/helpers.py +++ b/homeassistant/components/google_assistant/helpers.py @@ -182,6 +182,11 @@ class GoogleEntity: ] return self._traits + @callback + def should_expose(self): + """If entity should be exposed.""" + return self.config.should_expose(self.state) + @callback def is_supported(self) -> bool: """Return if the entity is supported by Google.""" diff --git a/homeassistant/components/google_assistant/report_state.py b/homeassistant/components/google_assistant/report_state.py index 33bb16d7830..869bc61d7a3 100644 --- a/homeassistant/components/google_assistant/report_state.py +++ b/homeassistant/components/google_assistant/report_state.py @@ -1,8 +1,13 @@ """Google Report State implementation.""" from homeassistant.core import HomeAssistant, callback from homeassistant.const import MATCH_ALL +from homeassistant.helpers.event import async_call_later -from .helpers import AbstractConfig, GoogleEntity +from .helpers import AbstractConfig, GoogleEntity, async_get_entities + +# Time to wait until the homegraph updates +# https://github.com/actions-on-google/smart-home-nodejs/issues/196#issuecomment-439156639 +INITIAL_REPORT_DELAY = 60 @callback @@ -34,6 +39,23 @@ def async_enable_report_state(hass: HomeAssistant, google_config: AbstractConfig {"devices": {"states": {changed_entity: entity_data}}} ) + async_call_later( + hass, INITIAL_REPORT_DELAY, _async_report_all_states(hass, google_config) + ) + return hass.helpers.event.async_track_state_change( MATCH_ALL, async_entity_state_listener ) + + +async def _async_report_all_states(hass: HomeAssistant, google_config: AbstractConfig): + """Report all states.""" + entities = {} + + for entity in async_get_entities(hass, google_config): + if not entity.should_expose(): + continue + + entities[entity.entity_id] = entity.query_serialize() + + await google_config.async_report_state({"devices": {"states": entities}}) diff --git a/tests/components/google_assistant/test_report_state.py b/tests/components/google_assistant/test_report_state.py index bd59502a3a1..734d9ec7fc8 100644 --- a/tests/components/google_assistant/test_report_state.py +++ b/tests/components/google_assistant/test_report_state.py @@ -1,17 +1,38 @@ """Test Google report state.""" from unittest.mock import patch -from homeassistant.components.google_assistant.report_state import ( - async_enable_report_state, -) +from homeassistant.components.google_assistant import report_state +from homeassistant.util.dt import utcnow + from . import BASIC_CONFIG -from tests.common import mock_coro + +from tests.common import mock_coro, async_fire_time_changed async def test_report_state(hass): """Test report state works.""" - unsub = async_enable_report_state(hass, BASIC_CONFIG) + hass.states.async_set("light.ceiling", "off") + hass.states.async_set("switch.ac", "on") + + with patch.object( + BASIC_CONFIG, "async_report_state", side_effect=mock_coro + ) as mock_report, patch.object(report_state, "INITIAL_REPORT_DELAY", 0): + unsub = report_state.async_enable_report_state(hass, BASIC_CONFIG) + + async_fire_time_changed(hass, utcnow()) + await hass.async_block_till_done() + + # Test that enabling report state does a report on all entities + assert len(mock_report.mock_calls) == 1 + assert mock_report.mock_calls[0][1][0] == { + "devices": { + "states": { + "light.ceiling": {"on": False, "online": True}, + "switch.ac": {"on": True, "online": True}, + } + } + } with patch.object( BASIC_CONFIG, "async_report_state", side_effect=mock_coro