Compare commits
11 commits
dev
...
hassio-dis
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8a364ab4f9 | ||
![]() |
ec18d14eb6 | ||
![]() |
f05ec652e6 | ||
![]() |
1fa8eef966 | ||
![]() |
c9710ccc3d | ||
![]() |
ac9ebeab9e | ||
![]() |
2fe4c42cc1 | ||
![]() |
ba9c88ddda | ||
![]() |
977f436b39 | ||
![]() |
1f27426c01 | ||
![]() |
3a58aee32b |
3 changed files with 116 additions and 29 deletions
|
@ -20,7 +20,8 @@ import homeassistant.helpers.config_validation as cv
|
|||
from homeassistant.loader import bind_hass
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
from .handler import HassIO
|
||||
from .handler import HassIO, HassioAPIError
|
||||
from .discovery import async_setup_discovery
|
||||
from .http import HassIOView
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -138,10 +139,12 @@ def is_hassio(hass):
|
|||
def async_check_config(hass):
|
||||
"""Check configuration over Hass.io API."""
|
||||
hassio = hass.data[DOMAIN]
|
||||
result = yield from hassio.check_homeassistant_config()
|
||||
|
||||
if not result:
|
||||
return "Hass.io config check API error"
|
||||
try:
|
||||
result = yield from hassio.check_homeassistant_config()
|
||||
except HassioAPIError as err:
|
||||
_LOGGER.error("Error on Hass.io API: %s", err)
|
||||
|
||||
if result['result'] == "error":
|
||||
return result['message']
|
||||
return None
|
||||
|
@ -150,16 +153,11 @@ def async_check_config(hass):
|
|||
@asyncio.coroutine
|
||||
def async_setup(hass, config):
|
||||
"""Set up the Hass.io component."""
|
||||
try:
|
||||
host = os.environ['HASSIO']
|
||||
except KeyError:
|
||||
_LOGGER.error("Missing HASSIO environment variable.")
|
||||
return False
|
||||
|
||||
try:
|
||||
os.environ['HASSIO_TOKEN']
|
||||
except KeyError:
|
||||
_LOGGER.error("Missing HASSIO_TOKEN environment variable.")
|
||||
# Check local setup
|
||||
for env in ('HASSIO', 'HASSIO_TOKEN'):
|
||||
if os.environ.get(env):
|
||||
continue
|
||||
_LOGGER.error("Missing %s environment variable.", env)
|
||||
return False
|
||||
|
||||
websession = hass.helpers.aiohttp_client.async_get_clientsession()
|
||||
|
@ -233,13 +231,13 @@ def async_setup(hass, config):
|
|||
payload = data
|
||||
|
||||
# Call API
|
||||
ret = yield from hassio.send_command(
|
||||
api_command.format(addon=addon, snapshot=snapshot),
|
||||
payload=payload, timeout=MAP_SERVICE_API[service.service][2]
|
||||
)
|
||||
|
||||
if not ret or ret['result'] != "ok":
|
||||
_LOGGER.error("Error on Hass.io API: %s", ret['message'])
|
||||
try:
|
||||
ret = yield from hassio.send_command(
|
||||
api_command.format(addon=addon, snapshot=snapshot),
|
||||
payload=payload, timeout=MAP_SERVICE_API[service.service][2]
|
||||
)
|
||||
except HassioAPIError as err:
|
||||
_LOGGER.error("Error on Hass.io API: %s", err)
|
||||
|
||||
for service, settings in MAP_SERVICE_API.items():
|
||||
hass.services.async_register(
|
||||
|
@ -248,9 +246,11 @@ def async_setup(hass, config):
|
|||
@asyncio.coroutine
|
||||
def update_homeassistant_version(now):
|
||||
"""Update last available Home Assistant version."""
|
||||
data = yield from hassio.get_homeassistant_info()
|
||||
if data:
|
||||
try:
|
||||
data = yield from hassio.get_homeassistant_info()
|
||||
hass.data[DATA_HOMEASSISTANT_VERSION] = data['last_version']
|
||||
except HassioAPIError as err:
|
||||
_LOGGER.warning("Can't read last version: %s", err)
|
||||
|
||||
hass.helpers.event.async_track_point_in_utc_time(
|
||||
update_homeassistant_version, utcnow() + HASSIO_UPDATE_INTERVAL)
|
||||
|
@ -282,4 +282,7 @@ def async_setup(hass, config):
|
|||
hass.services.async_register(
|
||||
HASS_DOMAIN, service, async_handle_core_service)
|
||||
|
||||
# Init discovery Hass.io feature
|
||||
async_setup_discovery(hass, hassio)
|
||||
|
||||
return True
|
||||
|
|
59
homeassistant/components/hassio/discovery.py
Normal file
59
homeassistant/components/hassio/discovery.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
"""Implement the serivces discovery feature from Hass.io for Add-ons."""
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_START
|
||||
|
||||
from .handler import HassioAPIError
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
EVENT_DISCOVERY_ADD = 'hassio_discovery_add'
|
||||
EVENT_DISCOVERY_DEL = 'hassio_discovery_del'
|
||||
|
||||
ATTR_UUID = 'uuid'
|
||||
ATTR_DISCOVERY = 'discovery'
|
||||
|
||||
|
||||
@callback
|
||||
def async_setup_discovery(hass, hassio):
|
||||
"""Discovery setup."""
|
||||
async def async_discovery_event_handler(event):
|
||||
"""Handle events from Hass.io discovery."""
|
||||
uuid = event.data[ATTR_UUID]
|
||||
|
||||
try:
|
||||
data = await hassio.get_services_discovery(uuid)
|
||||
except HassioAPIError as err:
|
||||
_LOGGER.error(
|
||||
"Can't read discover %s info: %s", uuid, err)
|
||||
return
|
||||
|
||||
hass.async_add_job(async_process_discovery, hass, data)
|
||||
|
||||
hass.bus.async_listen(
|
||||
EVENT_DISCOVERY_ADD, async_discovery_event_handler)
|
||||
|
||||
async def async_discovery_start_handler(event):
|
||||
"""Process all exists discovery on startup."""
|
||||
try:
|
||||
data = await hassio.retrieve_services_discovery()
|
||||
except HassioAPIError as err:
|
||||
_LOGGER.error(
|
||||
"Can't read discover %s info: %s", uuid, err)
|
||||
return
|
||||
|
||||
for discovery in data[ATTR_DISCOVERY]:
|
||||
hass.async_add_job(async_process_discovery, hass, discovery)
|
||||
|
||||
hass.bus.async_listen_once(
|
||||
EVENT_HOMEASSISTANT_START, async_discovery_start_handler)
|
||||
|
||||
|
||||
@callback
|
||||
def async_process_discovery(hass, data):
|
||||
"""Process a discovery request."""
|
|
@ -21,12 +21,20 @@ _LOGGER = logging.getLogger(__name__)
|
|||
X_HASSIO = 'X-HASSIO-KEY'
|
||||
|
||||
|
||||
class HassioAPIError(RuntimeError):
|
||||
"""Return if a API trow a error."""
|
||||
pass
|
||||
|
||||
|
||||
def _api_bool(funct):
|
||||
"""Return a boolean."""
|
||||
async def _wrapper(*argv, **kwargs):
|
||||
"""Wrap function."""
|
||||
data = await funct(*argv, **kwargs)
|
||||
return data and data['result'] == "ok"
|
||||
try:
|
||||
data = await funct(*argv, **kwargs)
|
||||
return data['result'] == "ok"
|
||||
except HassioAPIError:
|
||||
return False
|
||||
|
||||
return _wrapper
|
||||
|
||||
|
@ -36,9 +44,9 @@ def _api_data(funct):
|
|||
async def _wrapper(*argv, **kwargs):
|
||||
"""Wrap function."""
|
||||
data = await funct(*argv, **kwargs)
|
||||
if data and data['result'] == "ok":
|
||||
if data['result'] == "ok":
|
||||
return data['data']
|
||||
return None
|
||||
raise HassioAPIError(data['message'])
|
||||
|
||||
return _wrapper
|
||||
|
||||
|
@ -91,6 +99,23 @@ class HassIO:
|
|||
"""
|
||||
return self.send_command("/homeassistant/check", timeout=300)
|
||||
|
||||
@_api_data
|
||||
def retrieve_services_discovery(self):
|
||||
"""Return all discovery data from Hass.io API.
|
||||
|
||||
This method return a coroutine.
|
||||
"""
|
||||
return self.send_command("/services/discovery", method="get")
|
||||
|
||||
@_api_data
|
||||
def get_services_discovery_entry(self, uuid):
|
||||
"""Return a single discovery data entry.
|
||||
|
||||
This method return a coroutine.
|
||||
"""
|
||||
return self.send_command(
|
||||
"/services/discovery/{}".format(uuid), method="get")
|
||||
|
||||
@_api_bool
|
||||
async def update_hass_api(self, http_config, refresh_token):
|
||||
"""Update Home Assistant API data on Hass.io."""
|
||||
|
@ -137,7 +162,7 @@ class HassIO:
|
|||
if request.status not in (200, 400):
|
||||
_LOGGER.error(
|
||||
"%s return code %d.", command, request.status)
|
||||
return None
|
||||
raise HassioAPIError()
|
||||
|
||||
answer = yield from request.json()
|
||||
return answer
|
||||
|
@ -148,4 +173,4 @@ class HassIO:
|
|||
except aiohttp.ClientError as err:
|
||||
_LOGGER.error("Client error on %s request %s", command, err)
|
||||
|
||||
return None
|
||||
raise HassioAPIError()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue