Cloud: Recover when internet is not available yet (#42877)

This commit is contained in:
Paulus Schoutsen 2020-11-06 12:12:18 +01:00 committed by GitHub
parent fd04b96132
commit 15da7b3ca6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 3 deletions

View File

@ -1,5 +1,6 @@
"""Interface implementation for cloud client."""
import asyncio
import logging
from pathlib import Path
from typing import Any, Dict
@ -14,6 +15,7 @@ from homeassistant.components.google_assistant import const as gc, smart_home as
from homeassistant.const import HTTP_OK
from homeassistant.core import Context, callback
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.event import async_call_later
from homeassistant.helpers.typing import HomeAssistantType
from homeassistant.util.aiohttp import MockRequest
@ -106,13 +108,22 @@ class CloudClient(Interface):
"""When user logs in."""
await self.prefs.async_set_username(self.cloud.username)
if self.alexa_config.enabled and self.alexa_config.should_report_state:
async def enable_alexa(_):
"""Enable Alexa."""
try:
await self.alexa_config.async_enable_proactive_mode()
except aiohttp.ClientError as err: # If no internet available yet
if self._hass.is_running:
logging.getLogger(__package__).warning(
"Unable to activate Alexa Report State: %s. Retrying in 30 seconds",
err,
)
async_call_later(self._hass, 30, enable_alexa)
except alexa_errors.NoTokenAvailable:
pass
if self._prefs.google_enabled:
async def enable_google(_):
"""Enable Google."""
gconf = await self.get_google_config()
gconf.async_enable_local_sdk()
@ -120,6 +131,17 @@ class CloudClient(Interface):
if gconf.should_report_state:
gconf.async_enable_report_state()
tasks = []
if self.alexa_config.enabled and self.alexa_config.should_report_state:
tasks.append(enable_alexa)
if self._prefs.google_enabled:
tasks.append(enable_google)
if tasks:
await asyncio.gather(*[task(None) for task in tasks])
async def cleanups(self) -> None:
"""Cleanup some stuff after logout."""
await self.prefs.async_set_username(None)

View File

@ -1,4 +1,7 @@
"""Test the cloud.iot module."""
from datetime import timedelta
import aiohttp
from aiohttp import web
import pytest
@ -8,10 +11,12 @@ from homeassistant.components.cloud.const import PREF_ENABLE_ALEXA, PREF_ENABLE_
from homeassistant.const import CONTENT_TYPE_JSON
from homeassistant.core import State
from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util
from . import mock_cloud, mock_cloud_prefs
from tests.async_mock import AsyncMock, MagicMock, patch
from tests.async_mock import AsyncMock, MagicMock, Mock, patch
from tests.common import async_fire_time_changed
from tests.components.alexa import test_smart_home as test_alexa
@ -260,3 +265,25 @@ async def test_set_username(hass):
assert len(prefs.async_set_username.mock_calls) == 1
assert prefs.async_set_username.mock_calls[0][1][0] == "mock-username"
async def test_login_recovers_bad_internet(hass, caplog):
"""Test Alexa can recover bad auth."""
prefs = Mock(
alexa_enabled=True,
google_enabled=False,
async_set_username=AsyncMock(return_value=None),
)
client = CloudClient(hass, prefs, None, {}, {})
client.cloud = Mock()
client._alexa_config = Mock(
async_enable_proactive_mode=Mock(side_effect=aiohttp.ClientError)
)
await client.logged_in()
assert len(client._alexa_config.async_enable_proactive_mode.mock_calls) == 1
assert "Unable to activate Alexa Report State" in caplog.text
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=30))
await hass.async_block_till_done()
assert len(client._alexa_config.async_enable_proactive_mode.mock_calls) == 2