mirror of
https://github.com/home-assistant/core.git
synced 2025-12-24 12:59:34 +00:00
Add Google Report State (#27112)
* Add Google Report State * UPDATE codeowners" * Add config option for dev mode * update library * lint * Bug fixes
This commit is contained in:
committed by
Pascal Vizeli
parent
3e99743244
commit
f184bf4d85
@@ -1,6 +1,13 @@
|
||||
"""Google config for Cloud."""
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
import async_timeout
|
||||
from hass_nabucasa.google_report_state import ErrorResponse
|
||||
|
||||
from homeassistant.const import CLOUD_NEVER_EXPOSED_ENTITIES
|
||||
from homeassistant.components.google_assistant.helpers import AbstractConfig
|
||||
from homeassistant.helpers import entity_registry
|
||||
|
||||
from .const import (
|
||||
PREF_SHOULD_EXPOSE,
|
||||
@@ -10,15 +17,31 @@ from .const import (
|
||||
DEFAULT_DISABLE_2FA,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CloudGoogleConfig(AbstractConfig):
|
||||
"""HA Cloud Configuration for Google Assistant."""
|
||||
|
||||
def __init__(self, config, prefs, cloud):
|
||||
"""Initialize the Alexa config."""
|
||||
def __init__(self, hass, config, prefs, cloud):
|
||||
"""Initialize the Google config."""
|
||||
super().__init__(hass)
|
||||
self._config = config
|
||||
self._prefs = prefs
|
||||
self._cloud = cloud
|
||||
self._cur_entity_prefs = self._prefs.google_entity_configs
|
||||
self._sync_entities_lock = asyncio.Lock()
|
||||
|
||||
prefs.async_listen_updates(self._async_prefs_updated)
|
||||
hass.bus.async_listen(
|
||||
entity_registry.EVENT_ENTITY_REGISTRY_UPDATED,
|
||||
self._handle_entity_registry_updated,
|
||||
)
|
||||
|
||||
@property
|
||||
def enabled(self):
|
||||
"""Return if Google is enabled."""
|
||||
return self._prefs.google_enabled
|
||||
|
||||
@property
|
||||
def agent_user_id(self):
|
||||
@@ -35,16 +58,25 @@ class CloudGoogleConfig(AbstractConfig):
|
||||
"""Return entity config."""
|
||||
return self._prefs.google_secure_devices_pin
|
||||
|
||||
@property
|
||||
def should_report_state(self):
|
||||
"""Return if states should be proactively reported."""
|
||||
return self._prefs.google_report_state
|
||||
|
||||
def should_expose(self, state):
|
||||
"""If an entity should be exposed."""
|
||||
if state.entity_id in CLOUD_NEVER_EXPOSED_ENTITIES:
|
||||
"""If a state object should be exposed."""
|
||||
return self._should_expose_entity_id(state.entity_id)
|
||||
|
||||
def _should_expose_entity_id(self, entity_id):
|
||||
"""If an entity ID should be exposed."""
|
||||
if entity_id in CLOUD_NEVER_EXPOSED_ENTITIES:
|
||||
return False
|
||||
|
||||
if not self._config["filter"].empty_filter:
|
||||
return self._config["filter"](state.entity_id)
|
||||
return self._config["filter"](entity_id)
|
||||
|
||||
entity_configs = self._prefs.google_entity_configs
|
||||
entity_config = entity_configs.get(state.entity_id, {})
|
||||
entity_config = entity_configs.get(entity_id, {})
|
||||
return entity_config.get(PREF_SHOULD_EXPOSE, DEFAULT_SHOULD_EXPOSE)
|
||||
|
||||
def should_2fa(self, state):
|
||||
@@ -52,3 +84,72 @@ class CloudGoogleConfig(AbstractConfig):
|
||||
entity_configs = self._prefs.google_entity_configs
|
||||
entity_config = entity_configs.get(state.entity_id, {})
|
||||
return not entity_config.get(PREF_DISABLE_2FA, DEFAULT_DISABLE_2FA)
|
||||
|
||||
async def async_report_state(self, message):
|
||||
"""Send a state report to Google."""
|
||||
try:
|
||||
await self._cloud.google_report_state.async_send_message(message)
|
||||
except ErrorResponse as err:
|
||||
_LOGGER.warning("Error reporting state - %s: %s", err.code, err.message)
|
||||
|
||||
async def _async_request_sync_devices(self):
|
||||
"""Trigger a sync with Google."""
|
||||
if self._sync_entities_lock.locked():
|
||||
return 200
|
||||
|
||||
websession = self.hass.helpers.aiohttp_client.async_get_clientsession()
|
||||
|
||||
async with self._sync_entities_lock:
|
||||
with async_timeout.timeout(10):
|
||||
await self._cloud.auth.async_check_token()
|
||||
|
||||
_LOGGER.debug("Requesting sync")
|
||||
|
||||
with async_timeout.timeout(30):
|
||||
req = await websession.post(
|
||||
self._cloud.google_actions_sync_url,
|
||||
headers={"authorization": self._cloud.id_token},
|
||||
)
|
||||
_LOGGER.debug("Finished requesting syncing: %s", req.status)
|
||||
return req.status
|
||||
|
||||
async def async_deactivate_report_state(self):
|
||||
"""Turn off report state and disable further state reporting.
|
||||
|
||||
Called when the user disconnects their account from Google.
|
||||
"""
|
||||
await self._prefs.async_update(google_report_state=False)
|
||||
|
||||
async def _async_prefs_updated(self, prefs):
|
||||
"""Handle updated preferences."""
|
||||
if self.should_report_state != self.is_reporting_state:
|
||||
if self.should_report_state:
|
||||
self.async_enable_report_state()
|
||||
else:
|
||||
self.async_disable_report_state()
|
||||
|
||||
# State reporting is reported as a property on entities.
|
||||
# So when we change it, we need to sync all entities.
|
||||
await self.async_sync_entities()
|
||||
return
|
||||
|
||||
# If entity prefs are the same or we have filter in config.yaml,
|
||||
# don't sync.
|
||||
if (
|
||||
self._cur_entity_prefs is prefs.google_entity_configs
|
||||
or not self._config["filter"].empty_filter
|
||||
):
|
||||
return
|
||||
|
||||
self.async_schedule_google_sync()
|
||||
|
||||
async def _handle_entity_registry_updated(self, event):
|
||||
"""Handle when entity registry updated."""
|
||||
if not self.enabled or not self._cloud.is_logged_in:
|
||||
return
|
||||
|
||||
entity_id = event.data["entity_id"]
|
||||
|
||||
# Schedule a sync if a change was made to an entity that Google knows about
|
||||
if self._should_expose_entity_id(entity_id):
|
||||
await self.async_sync_entities()
|
||||
|
||||
Reference in New Issue
Block a user