Merge pull request #796 from home-assistant/dev

Release 139
This commit is contained in:
Pascal Vizeli 2018-11-05 16:19:17 +01:00 committed by GitHub
commit 6e7cf5e4c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 44 additions and 25 deletions

2
API.md
View File

@ -415,7 +415,7 @@ Proxy to real websocket instance.
### RESTful for API addons
If a add-on will call itself, you can use `/addons/self/...`.
If an add-on will call itself, you can use `/addons/self/...`.
- GET `/addons`

View File

@ -674,7 +674,8 @@ class Addon(CoreSysAttributes):
"""Install an add-on."""
if not self.available:
_LOGGER.error(
"Add-on %s not supported on %s", self._id, self.sys_arch)
"Add-on %s not supported on %s with %s architecture",
self._id, self.sys_machine, self.sys_arch)
return False
if self.is_installed:

View File

@ -2,12 +2,13 @@
import logging
from aiohttp import BasicAuth
from aiohttp.hdrs import CONTENT_TYPE, AUTHORIZATION
from aiohttp.web_exceptions import HTTPUnauthorized
from aiohttp.hdrs import CONTENT_TYPE, AUTHORIZATION, WWW_AUTHENTICATE
from .utils import api_process
from ..const import REQUEST_FROM, CONTENT_TYPE_JSON, CONTENT_TYPE_URL
from ..coresys import CoreSysAttributes
from ..exceptions import APIError, APIForbidden
from ..exceptions import APIForbidden
_LOGGER = logging.getLogger(__name__)
@ -55,4 +56,6 @@ class APIAuth(CoreSysAttributes):
data = await request.post()
return await self._process_dict(request, addon, data)
raise APIError("Auth method not detected!")
raise HTTPUnauthorized(headers={
WWW_AUTHENTICATE: "Basic realm=\"Hass.io Authentication\""
})

View File

@ -153,7 +153,7 @@ class APIProxy(CoreSysAttributes):
except (RuntimeError, ValueError, ClientConnectorError) as err:
_LOGGER.error("Client error on WebSocket API %s.", err)
except HomeAssistantAuthError as err:
except HomeAssistantAuthError:
_LOGGER.error("Failed authentication to Home Assistant WebSocket")
raise APIError()

View File

@ -2,7 +2,7 @@
from pathlib import Path
from ipaddress import ip_network
HASSIO_VERSION = '138'
HASSIO_VERSION = '139'
URL_HASSIO_ADDONS = "https://github.com/home-assistant/hassio-addons"
URL_HASSIO_VERSION = \
@ -259,3 +259,6 @@ ROLE_HOMEASSISTANT = 'homeassistant'
ROLE_BACKUP = 'backup'
ROLE_MANAGER = 'manager'
ROLE_ADMIN = 'admin'
CHAN_ID = 'chan_id'
CHAN_TYPE = 'chan_type'

View File

@ -36,6 +36,7 @@ class Discovery(CoreSysAttributes, JsonConfig):
discovery = Message(**message)
messages[discovery.uuid] = discovery
_LOGGER.info("Load %d messages", len(messages))
self.message_obj = messages
def save(self):
@ -60,7 +61,7 @@ class Discovery(CoreSysAttributes, JsonConfig):
def send(self, addon, service, config):
"""Send a discovery message to Home Assistant."""
try:
DISCOVERY_SERVICES[service](config)
config = DISCOVERY_SERVICES[service](config)
except vol.Invalid as err:
_LOGGER.error(
"Invalid discovery %s config", humanize_error(config, err))
@ -115,7 +116,7 @@ class Discovery(CoreSysAttributes, JsonConfig):
@attr.s
class Message:
"""Represent a single Discovery message."""
uuid = attr.ib(factory=lambda: uuid4().hex, cmp=False, init=False)
addon = attr.ib()
service = attr.ib()
config = attr.ib(cmp=False)
uuid = attr.ib(factory=lambda: uuid4().hex, cmp=False)

View File

@ -66,7 +66,7 @@ class HassOS(CoreSysAttributes):
return self._board
def _check_host(self):
"""Check if HassOS is availabe."""
"""Check if HassOS is available."""
if not self.available:
_LOGGER.error("No HassOS available")
raise HassOSNotSupportedError()

View File

@ -191,7 +191,7 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
@property
def hassio_token(self):
"""Return a access token for the Hass.io API."""
"""Return an access token for the Hass.io API."""
return self._data.get(ATTR_ACCESS_TOKEN)
@property
@ -260,7 +260,7 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
_LOGGER.warning("Version %s is already installed", version)
return HomeAssistantUpdateError()
# process a update
# process an update
async def _update(to_version):
"""Run Home Assistant update."""
try:

View File

@ -6,7 +6,8 @@ from string import Template
import attr
from ..const import ATTR_INPUT, ATTR_OUTPUT, ATTR_DEVICES, ATTR_NAME
from ..const import (
ATTR_INPUT, ATTR_OUTPUT, ATTR_DEVICES, ATTR_NAME, CHAN_ID, CHAN_TYPE)
from ..coresys import CoreSysAttributes
_LOGGER = logging.getLogger(__name__)
@ -58,7 +59,9 @@ class AlsaAudio(CoreSysAttributes):
# Process devices
for dev_id, dev_data in self.sys_hardware.audio_devices.items():
for chan_id, chan_type in dev_data[ATTR_DEVICES].items():
for chan_info in dev_data[ATTR_DEVICES]:
chan_id = chan_info[CHAN_ID]
chan_type = chan_info[CHAN_TYPE]
alsa_id = f"{dev_id},{chan_id}"
dev_name = dev_data[ATTR_NAME]

View File

@ -6,7 +6,7 @@ import re
import pyudev
from ..const import ATTR_NAME, ATTR_TYPE, ATTR_DEVICES
from ..const import ATTR_NAME, ATTR_TYPE, ATTR_DEVICES, CHAN_ID, CHAN_TYPE
_LOGGER = logging.getLogger(__name__)
@ -87,14 +87,16 @@ class Hardware:
audio_list[match.group(1)] = {
ATTR_NAME: match.group(3),
ATTR_TYPE: match.group(2),
ATTR_DEVICES: {},
ATTR_DEVICES: [],
}
# parse devices
for match in RE_DEVICES.finditer(devices):
try:
audio_list[match.group(1)][ATTR_DEVICES][match.group(2)] = \
match.group(3)
audio_list[match.group(1)][ATTR_DEVICES].append({
CHAN_ID: match.group(2),
CHAN_TYPE: match.group(3)
})
except KeyError:
_LOGGER.warning("Wrong audio device found %s", match.group(0))
continue

View File

@ -118,7 +118,7 @@ class SnapshotManager(CoreSysAttributes):
async def do_snapshot_full(self, name="", password=None):
"""Create a full snapshot."""
if self.lock.locked():
_LOGGER.error("It is already a snapshot/restore process running")
_LOGGER.error("A snapshot/restore process is already running")
return None
snapshot = self._create_snapshot(name, SNAPSHOT_FULL, password)
@ -153,7 +153,7 @@ class SnapshotManager(CoreSysAttributes):
password=None):
"""Create a partial snapshot."""
if self.lock.locked():
_LOGGER.error("It is already a snapshot/restore process running")
_LOGGER.error("A snapshot/restore process is already running")
return None
addons = addons or []
@ -201,7 +201,7 @@ class SnapshotManager(CoreSysAttributes):
async def do_restore_full(self, snapshot, password=None):
"""Restore a snapshot."""
if self.lock.locked():
_LOGGER.error("It is already a snapshot/restore process running")
_LOGGER.error("A snapshot/restore process is already running")
return False
if snapshot.sys_type != SNAPSHOT_FULL:
@ -274,7 +274,7 @@ class SnapshotManager(CoreSysAttributes):
addons=None, folders=None, password=None):
"""Restore a snapshot."""
if self.lock.locked():
_LOGGER.error("It is already a snapshot/restore process running")
_LOGGER.error("A snapshot/restore process is already running")
return False
if snapshot.protected and not snapshot.set_password(password):

View File

@ -3,6 +3,7 @@ import asyncio
import logging
from .coresys import CoreSysAttributes
from .exceptions import HomeAssistantError
_LOGGER = logging.getLogger(__name__)
@ -104,7 +105,10 @@ class Tasks(CoreSysAttributes):
return
_LOGGER.warning("Watchdog found a problem with Home Assistant Docker!")
await self.sys_homeassistant.start()
try:
await self.sys_homeassistant.start()
except HomeAssistantError:
_LOGGER.error("Watchdog Home Assistant reanimation fails!")
async def _watchdog_homeassistant_api(self):
"""Create scheduler task for monitoring running state of API.
@ -136,6 +140,8 @@ class Tasks(CoreSysAttributes):
_LOGGER.error("Watchdog found a problem with Home Assistant API!")
try:
await self.sys_homeassistant.restart()
except HomeAssistantError:
_LOGGER.error("Watchdog Home Assistant reanimation fails!")
finally:
self._cache[HASS_WATCHDOG_API] = 0

View File

@ -1,4 +1,4 @@
attr==0.3.1
attrs==18.2.0
async_timeout==3.0.1
aiohttp==3.4.4
docker==3.5.0

View File

@ -3,7 +3,7 @@ envlist = lint
[testenv]
deps =
flake8==3.5.0
flake8==3.6.0
pylint==2.1.1
-r{toxinidir}/requirements.txt