mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
commit
a5ffe0f72b
@ -29,7 +29,7 @@ REQUIREMENTS = ['pysensibo==1.0.2']
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
ALL = 'all'
|
ALL = ['all']
|
||||||
TIMEOUT = 10
|
TIMEOUT = 10
|
||||||
|
|
||||||
SERVICE_ASSUME_STATE = 'sensibo_assume_state'
|
SERVICE_ASSUME_STATE = 'sensibo_assume_state'
|
||||||
|
@ -16,3 +16,9 @@ MESSAGE_EXPIRATION = """
|
|||||||
It looks like your Home Assistant Cloud subscription has expired. Please check
|
It looks like your Home Assistant Cloud subscription has expired. Please check
|
||||||
your [account page](/config/cloud/account) to continue using the service.
|
your [account page](/config/cloud/account) to continue using the service.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
MESSAGE_AUTH_FAIL = """
|
||||||
|
You have been logged out of Home Assistant Cloud because we have been unable
|
||||||
|
to verify your credentials. Please [log in](/config/cloud) again to continue
|
||||||
|
using the service.
|
||||||
|
"""
|
||||||
|
@ -10,7 +10,7 @@ from homeassistant.components.google_assistant import smart_home as ga
|
|||||||
from homeassistant.util.decorator import Registry
|
from homeassistant.util.decorator import Registry
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from . import auth_api
|
from . import auth_api
|
||||||
from .const import MESSAGE_EXPIRATION
|
from .const import MESSAGE_EXPIRATION, MESSAGE_AUTH_FAIL
|
||||||
|
|
||||||
HANDLERS = Registry()
|
HANDLERS = Registry()
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -77,9 +77,9 @@ class CloudIoT:
|
|||||||
self.tries += 1
|
self.tries += 1
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Sleep 0, 5, 10, 15 ... 30 seconds between retries
|
# Sleep 2^tries seconds between retries
|
||||||
self.retry_task = hass.async_add_job(asyncio.sleep(
|
self.retry_task = hass.async_add_job(asyncio.sleep(
|
||||||
min(30, (self.tries - 1) * 5), loop=hass.loop))
|
2**min(9, self.tries), loop=hass.loop))
|
||||||
yield from self.retry_task
|
yield from self.retry_task
|
||||||
self.retry_task = None
|
self.retry_task = None
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
@ -97,13 +97,23 @@ class CloudIoT:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
yield from hass.async_add_job(auth_api.check_token, self.cloud)
|
yield from hass.async_add_job(auth_api.check_token, self.cloud)
|
||||||
|
except auth_api.Unauthenticated as err:
|
||||||
|
_LOGGER.error('Unable to refresh token: %s', err)
|
||||||
|
|
||||||
|
hass.components.persistent_notification.async_create(
|
||||||
|
MESSAGE_AUTH_FAIL, 'Home Assistant Cloud',
|
||||||
|
'cloud_subscription_expired')
|
||||||
|
|
||||||
|
# Don't await it because it will cancel this task
|
||||||
|
hass.async_add_job(self.cloud.logout())
|
||||||
|
return
|
||||||
except auth_api.CloudError as err:
|
except auth_api.CloudError as err:
|
||||||
_LOGGER.warning("Unable to connect: %s", err)
|
_LOGGER.warning("Unable to refresh token: %s", err)
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.cloud.subscription_expired:
|
if self.cloud.subscription_expired:
|
||||||
hass.components.persistent_notification.async_create(
|
hass.components.persistent_notification.async_create(
|
||||||
MESSAGE_EXPIRATION, 'Subscription expired',
|
MESSAGE_EXPIRATION, 'Home Assistant Cloud',
|
||||||
'cloud_subscription_expired')
|
'cloud_subscription_expired')
|
||||||
self.close_requested = True
|
self.close_requested = True
|
||||||
return
|
return
|
||||||
|
@ -192,7 +192,7 @@ class HueBridge(object):
|
|||||||
self.bridge = phue.Bridge(
|
self.bridge = phue.Bridge(
|
||||||
self.host,
|
self.host,
|
||||||
config_file_path=self.hass.config.path(self.filename))
|
config_file_path=self.hass.config.path(self.filename))
|
||||||
except ConnectionRefusedError: # Wrong host was given
|
except (ConnectionRefusedError, OSError): # Wrong host was given
|
||||||
_LOGGER.error("Error connecting to the Hue bridge at %s",
|
_LOGGER.error("Error connecting to the Hue bridge at %s",
|
||||||
self.host)
|
self.host)
|
||||||
return
|
return
|
||||||
@ -201,6 +201,9 @@ class HueBridge(object):
|
|||||||
self.host)
|
self.host)
|
||||||
self.request_configuration()
|
self.request_configuration()
|
||||||
return
|
return
|
||||||
|
except Exception: # pylint: disable=broad-except
|
||||||
|
_LOGGER.exception("Unknown error connecting with Hue bridge at %s",
|
||||||
|
self.host)
|
||||||
|
|
||||||
# If we came here and configuring this host, mark as done
|
# If we came here and configuring this host, mark as done
|
||||||
if self.config_request_id:
|
if self.config_request_id:
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"""Constants used by Home Assistant components."""
|
"""Constants used by Home Assistant components."""
|
||||||
MAJOR_VERSION = 0
|
MAJOR_VERSION = 0
|
||||||
MINOR_VERSION = 64
|
MINOR_VERSION = 64
|
||||||
PATCH_VERSION = '2'
|
PATCH_VERSION = '3'
|
||||||
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
|
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
|
||||||
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
|
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
|
||||||
REQUIRED_PYTHON_VER = (3, 4, 2)
|
REQUIRED_PYTHON_VER = (3, 4, 2)
|
||||||
|
@ -1068,7 +1068,7 @@ class Config(object):
|
|||||||
"""Check if the path is valid for access from outside."""
|
"""Check if the path is valid for access from outside."""
|
||||||
assert path is not None
|
assert path is not None
|
||||||
|
|
||||||
parent = pathlib.Path(path).parent
|
parent = pathlib.Path(path)
|
||||||
try:
|
try:
|
||||||
parent = parent.resolve() # pylint: disable=no-member
|
parent = parent.resolve() # pylint: disable=no-member
|
||||||
except (FileNotFoundError, RuntimeError, PermissionError):
|
except (FileNotFoundError, RuntimeError, PermissionError):
|
||||||
|
@ -6,7 +6,7 @@ from aiohttp import WSMsgType, client_exceptions
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
from homeassistant.components.cloud import iot, auth_api
|
from homeassistant.components.cloud import Cloud, iot, auth_api, MODE_DEV
|
||||||
from tests.components.alexa import test_smart_home as test_alexa
|
from tests.components.alexa import test_smart_home as test_alexa
|
||||||
from tests.common import mock_coro
|
from tests.common import mock_coro
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ def test_cloud_check_token_raising(mock_client, caplog, mock_cloud):
|
|||||||
|
|
||||||
yield from conn.connect()
|
yield from conn.connect()
|
||||||
|
|
||||||
assert 'Unable to connect: BLA' in caplog.text
|
assert 'Unable to refresh token: BLA' in caplog.text
|
||||||
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
@ -348,3 +348,17 @@ def test_handler_google_actions(hass):
|
|||||||
assert device['name']['name'] == 'Config name'
|
assert device['name']['name'] == 'Config name'
|
||||||
assert device['name']['nicknames'] == ['Config alias']
|
assert device['name']['nicknames'] == ['Config alias']
|
||||||
assert device['type'] == 'action.devices.types.LIGHT'
|
assert device['type'] == 'action.devices.types.LIGHT'
|
||||||
|
|
||||||
|
|
||||||
|
async def test_refresh_token_expired(hass):
|
||||||
|
"""Test handling Unauthenticated error raised if refresh token expired."""
|
||||||
|
cloud = Cloud(hass, MODE_DEV, None, None)
|
||||||
|
|
||||||
|
with patch('homeassistant.components.cloud.auth_api.check_token',
|
||||||
|
side_effect=auth_api.Unauthenticated) as mock_check_token, \
|
||||||
|
patch.object(hass.components.persistent_notification,
|
||||||
|
'async_create') as mock_create:
|
||||||
|
await cloud.iot.connect()
|
||||||
|
|
||||||
|
assert len(mock_check_token.mock_calls) == 1
|
||||||
|
assert len(mock_create.mock_calls) == 1
|
||||||
|
@ -809,6 +809,7 @@ class TestConfig(unittest.TestCase):
|
|||||||
|
|
||||||
valid = [
|
valid = [
|
||||||
test_file,
|
test_file,
|
||||||
|
tmp_dir
|
||||||
]
|
]
|
||||||
for path in valid:
|
for path in valid:
|
||||||
assert self.config.is_allowed_path(path)
|
assert self.config.is_allowed_path(path)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user