diff --git a/API.md b/API.md
index 58e5d136c..9e14112d4 100644
--- a/API.md
+++ b/API.md
@@ -217,25 +217,36 @@ return:
### Host
- POST `/host/reload`
+
- POST `/host/shutdown`
+
- POST `/host/reboot`
+
- GET `/host/info`
```json
{
- "type": "",
- "version": "",
- "last_version": "",
- "features": ["shutdown", "reboot", "update", "hostname", "network_info", "network_control"],
- "hostname": "",
- "os": "",
- "audio": {
- "input": "0,0",
- "output": "0,0"
- }
+ "hostname": "hostname|null",
+ "features": ["shutdown", "reboot", "update", "hostname"],
+ "operating_system": "Hass.io-OS XY|Ubuntu 16.4|null",
+ "kernel": "4.15.7|null",
+ "chassis": "specific|null",
+ "type": "Hass.io-OS Type|null",
+ "deployment": "stable|beta|dev|null",
+ "version": "xy|null",
+ "last_version": "xy|null",
}
```
+- POST `/host/options`
+
+```json
+{
+ "hostname": "",
+}
+```
+
+
- POST `/host/update`
Optional:
@@ -284,24 +295,6 @@ Optional:
}
```
-### Network
-
-- GET `/network/info`
-
-```json
-{
- "hostname": ""
-}
-```
-
-- POST `/network/options`
-
-```json
-{
- "hostname": "",
-}
-```
-
### Home Assistant
- GET `/homeassistant/info`
@@ -310,6 +303,7 @@ Optional:
{
"version": "INSTALL_VERSION",
"last_version": "LAST_VERSION",
+ "machine": "Image machine type",
"image": "str",
"custom": "bool -> if custom image",
"boot": "bool",
@@ -613,46 +607,3 @@ This service perform a auto discovery to Home-Assistant.
```
- DEL `/services/mqtt`
-
-## Host Control
-
-Communicate over UNIX socket with a host daemon.
-
-- commands
-
-```
-# info
--> {'type', 'version', 'last_version', 'features', 'hostname'}
-# reboot
-# shutdown
-# host-update [v]
-
-# hostname xy
-
-# network info
--> {}
-# network wlan ssd xy
-# network wlan password xy
-# network int ip xy
-# network int netmask xy
-# network int route xy
-```
-
-Features:
-
-- shutdown
-- reboot
-- update
-- hostname
-- network_info
-- network_control
-
-Answer:
-```
-{}|OK|ERROR|WRONG
-```
-
-- {}: json
-- OK: call was successfully
-- ERROR: error on call
-- WRONG: not supported
diff --git a/Dockerfile b/Dockerfile
index df893aafb..2ed844f41 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -9,7 +9,9 @@ RUN apk add --no-cache \
python3 \
git \
socat \
+ glib \
libstdc++ \
+ eudev-libs \
&& apk add --no-cache --virtual .build-dependencies \
make \
python3-dev \
diff --git a/hassio/__main__.py b/hassio/__main__.py
index 4d6f0d6b9..b64bad447 100644
--- a/hassio/__main__.py
+++ b/hassio/__main__.py
@@ -5,7 +5,6 @@ import logging
import sys
import hassio.bootstrap as bootstrap
-import hassio.core as core
_LOGGER = logging.getLogger(__name__)
@@ -34,14 +33,13 @@ if __name__ == "__main__":
_LOGGER.info("Initialize Hassio setup")
coresys = bootstrap.initialize_coresys(loop)
- hassio = core.HassIO(coresys)
bootstrap.migrate_system_env(coresys)
_LOGGER.info("Setup HassIO")
- loop.run_until_complete(hassio.setup())
+ loop.run_until_complete(coresys.core.setup())
- loop.call_soon_threadsafe(loop.create_task, hassio.start())
+ loop.call_soon_threadsafe(loop.create_task, coresys.core.start())
loop.call_soon_threadsafe(bootstrap.reg_signal, loop)
try:
@@ -49,7 +47,7 @@ if __name__ == "__main__":
loop.run_forever()
finally:
_LOGGER.info("Stopping HassIO")
- loop.run_until_complete(hassio.stop())
+ loop.run_until_complete(coresys.core.stop())
executor.shutdown(wait=False)
loop.close()
diff --git a/hassio/addons/__init__.py b/hassio/addons/__init__.py
index d75dfab96..58c728af1 100644
--- a/hassio/addons/__init__.py
+++ b/hassio/addons/__init__.py
@@ -5,7 +5,7 @@ import logging
from .addon import Addon
from .repository import Repository
from .data import AddonsData
-from ..const import REPOSITORY_CORE, REPOSITORY_LOCAL, BOOT_AUTO
+from ..const import REPOSITORY_CORE, REPOSITORY_LOCAL, BOOT_AUTO, STATE_STARTED
from ..coresys import CoreSysAttributes
_LOGGER = logging.getLogger(__name__)
@@ -56,7 +56,7 @@ class AddonManager(CoreSysAttributes):
# init hassio built-in repositories
repositories = \
- set(self._config.addons_repositories) | BUILTIN_REPOSITORIES
+ set(self.sys_config.addons_repositories) | BUILTIN_REPOSITORIES
# init custom repositories & load addons
await self.load_repositories(repositories)
@@ -66,7 +66,7 @@ class AddonManager(CoreSysAttributes):
tasks = [repository.update() for repository in
self.repositories_obj.values()]
if tasks:
- await asyncio.wait(tasks, loop=self._loop)
+ await asyncio.wait(tasks)
# read data from repositories
self.data.reload()
@@ -90,16 +90,16 @@ class AddonManager(CoreSysAttributes):
# don't add built-in repository to config
if url not in BUILTIN_REPOSITORIES:
- self._config.add_addon_repository(url)
+ self.sys_config.add_addon_repository(url)
tasks = [_add_repository(url) for url in new_rep - old_rep]
if tasks:
- await asyncio.wait(tasks, loop=self._loop)
+ await asyncio.wait(tasks)
# del new repository
for url in old_rep - new_rep - BUILTIN_REPOSITORIES:
self.repositories_obj.pop(url).remove()
- self._config.drop_addon_repository(url)
+ self.sys_config.drop_addon_repository(url)
# update data
self.data.reload()
@@ -125,13 +125,13 @@ class AddonManager(CoreSysAttributes):
self.addons_obj[addon_slug] = addon
if tasks:
- await asyncio.wait(tasks, loop=self._loop)
+ await asyncio.wait(tasks)
# remove
for addon_slug in del_addons:
self.addons_obj.pop(addon_slug)
- async def auto_boot(self, stage):
+ async def boot(self, stage):
"""Boot addons with mode auto."""
tasks = []
for addon in self.addons_obj.values():
@@ -141,5 +141,18 @@ class AddonManager(CoreSysAttributes):
_LOGGER.info("Startup %s run %d addons", stage, len(tasks))
if tasks:
- await asyncio.wait(tasks, loop=self._loop)
- await asyncio.sleep(self._config.wait_boot, loop=self._loop)
+ await asyncio.wait(tasks)
+ await asyncio.sleep(self.sys_config.wait_boot)
+
+ async def shutdown(self, stage):
+ """Shutdown addons."""
+ tasks = []
+ for addon in self.addons_obj.values():
+ if addon.is_installed and \
+ await addon.state() == STATE_STARTED and \
+ addon.startup == stage:
+ tasks.append(addon.stop())
+
+ _LOGGER.info("Shutdown %s stop %d addons", stage, len(tasks))
+ if tasks:
+ await asyncio.wait(tasks)
diff --git a/hassio/addons/addon.py b/hassio/addons/addon.py
index e17f3f7a5..4bebda235 100644
--- a/hassio/addons/addon.py
+++ b/hassio/addons/addon.py
@@ -66,7 +66,7 @@ class Addon(CoreSysAttributes):
@property
def _data(self):
"""Return addons data storage."""
- return self._addons.data
+ return self.sys_addons.data
@property
def is_installed(self):
@@ -376,7 +376,7 @@ class Addon(CoreSysAttributes):
if self.is_installed and \
ATTR_AUDIO_OUTPUT in self._data.user[self._id]:
return self._data.user[self._id][ATTR_AUDIO_OUTPUT]
- return self._alsa.default.output
+ return self.sys_host.alsa.default.output
@audio_output.setter
def audio_output(self, value):
@@ -394,7 +394,7 @@ class Addon(CoreSysAttributes):
if self.is_installed and ATTR_AUDIO_INPUT in self._data.user[self._id]:
return self._data.user[self._id][ATTR_AUDIO_INPUT]
- return self._alsa.default.input
+ return self.sys_host.alsa.default.input
@audio_input.setter
def audio_input(self, value):
@@ -436,11 +436,11 @@ class Addon(CoreSysAttributes):
# Repository with dockerhub images
if ATTR_IMAGE in addon_data:
- return addon_data[ATTR_IMAGE].format(arch=self._arch)
+ return addon_data[ATTR_IMAGE].format(arch=self.sys_arch)
# local build
return "{}/{}-addon-{}".format(
- addon_data[ATTR_REPOSITORY], self._arch,
+ addon_data[ATTR_REPOSITORY], self.sys_arch,
addon_data[ATTR_SLUG])
@property
@@ -461,12 +461,12 @@ class Addon(CoreSysAttributes):
@property
def path_data(self):
"""Return addon data path inside supervisor."""
- return Path(self._config.path_addons_data, self._id)
+ return Path(self.sys_config.path_addons_data, self._id)
@property
def path_extern_data(self):
"""Return addon data path external for docker."""
- return PurePath(self._config.path_extern_addons_data, self._id)
+ return PurePath(self.sys_config.path_extern_addons_data, self._id)
@property
def path_options(self):
@@ -506,16 +506,16 @@ class Addon(CoreSysAttributes):
@property
def path_asound(self):
"""Return path to asound config."""
- return Path(self._config.path_tmp, f"{self.slug}_asound")
+ return Path(self.sys_config.path_tmp, f"{self.slug}_asound")
@property
def path_extern_asound(self):
"""Return path to asound config for docker."""
- return Path(self._config.path_extern_tmp, f"{self.slug}_asound")
+ return Path(self.sys_config.path_extern_tmp, f"{self.slug}_asound")
def save_data(self):
"""Save data of addon."""
- self._addons.data.save_data()
+ self.sys_addons.data.save_data()
def write_options(self):
"""Return True if addon options is written to data."""
@@ -537,7 +537,7 @@ class Addon(CoreSysAttributes):
def write_asound(self):
"""Write asound config to file and return True on success."""
- asound_config = self._alsa.asound(
+ asound_config = self.sys_host.alsa.asound(
alsa_input=self.audio_input, alsa_output=self.audio_output)
try:
@@ -590,9 +590,9 @@ class Addon(CoreSysAttributes):
async def install(self):
"""Install a addon."""
- if self._arch not in self.supported_arch:
+ if self.sys_arch not in self.supported_arch:
_LOGGER.error(
- "Addon %s not supported on %s", self._id, self._arch)
+ "Addon %s not supported on %s", self._id, self.sys_arch)
return False
if self.is_installed:
@@ -735,7 +735,7 @@ class Addon(CoreSysAttributes):
@check_installed
async def snapshot(self, tar_file):
"""Snapshot a state of a addon."""
- with TemporaryDirectory(dir=str(self._config.path_tmp)) as temp:
+ with TemporaryDirectory(dir=str(self.sys_config.path_tmp)) as temp:
# store local image
if self.need_build and not await \
self.instance.export_image(Path(temp, "image.tar")):
@@ -764,7 +764,7 @@ class Addon(CoreSysAttributes):
try:
_LOGGER.info("Build snapshot for addon %s", self._id)
- await self._loop.run_in_executor(None, _write_tarfile)
+ await self.sys_run_in_executor(_write_tarfile)
except (tarfile.TarError, OSError) as err:
_LOGGER.error("Can't write tarfile %s: %s", tar_file, err)
return False
@@ -774,7 +774,7 @@ class Addon(CoreSysAttributes):
async def restore(self, tar_file):
"""Restore a state of a addon."""
- with TemporaryDirectory(dir=str(self._config.path_tmp)) as temp:
+ with TemporaryDirectory(dir=str(self.sys_config.path_tmp)) as temp:
# extract snapshot
def _extract_tarfile():
"""Extract tar snapshot."""
@@ -782,7 +782,7 @@ class Addon(CoreSysAttributes):
snapshot.extractall(path=Path(temp))
try:
- await self._loop.run_in_executor(None, _extract_tarfile)
+ await self.sys_run_in_executor(_extract_tarfile)
except tarfile.TarError as err:
_LOGGER.error("Can't read tarfile %s: %s", tar_file, err)
return False
@@ -828,7 +828,7 @@ class Addon(CoreSysAttributes):
try:
_LOGGER.info("Restore data for addon %s", self._id)
- await self._loop.run_in_executor(None, _restore_data)
+ await self.sys_run_in_executor(_restore_data)
except shutil.Error as err:
_LOGGER.error("Can't restore origin data: %s", err)
return False
diff --git a/hassio/addons/build.py b/hassio/addons/build.py
index d98c9597a..4d9a37618 100644
--- a/hassio/addons/build.py
+++ b/hassio/addons/build.py
@@ -25,13 +25,13 @@ class AddonBuild(JsonConfig, CoreSysAttributes):
@property
def addon(self):
"""Return addon of build data."""
- return self._addons.get(self._id)
+ return self.sys_addons.get(self._id)
@property
def base_image(self):
"""Base images for this addon."""
return self._data[ATTR_BUILD_FROM].get(
- self._arch, BASE_IMAGE[self._arch])
+ self.sys_arch, BASE_IMAGE[self.sys_arch])
@property
def squash(self):
@@ -53,7 +53,7 @@ class AddonBuild(JsonConfig, CoreSysAttributes):
'squash': self.squash,
'labels': {
'io.hass.version': version,
- 'io.hass.arch': self._arch,
+ 'io.hass.arch': self.sys_arch,
'io.hass.type': META_ADDON,
'io.hass.name': self._fix_label('name'),
'io.hass.description': self._fix_label('description'),
@@ -61,7 +61,7 @@ class AddonBuild(JsonConfig, CoreSysAttributes):
'buildargs': {
'BUILD_FROM': self.base_image,
'BUILD_VERSION': version,
- 'BUILD_ARCH': self._arch,
+ 'BUILD_ARCH': self.sys_arch,
**self.additional_args,
}
}
diff --git a/hassio/addons/data.py b/hassio/addons/data.py
index 777d2b025..ade770c54 100644
--- a/hassio/addons/data.py
+++ b/hassio/addons/data.py
@@ -56,17 +56,17 @@ class AddonsData(JsonConfig, CoreSysAttributes):
# read core repository
self._read_addons_folder(
- self._config.path_addons_core, REPOSITORY_CORE)
+ self.sys_config.path_addons_core, REPOSITORY_CORE)
# read local repository
self._read_addons_folder(
- self._config.path_addons_local, REPOSITORY_LOCAL)
+ self.sys_config.path_addons_local, REPOSITORY_LOCAL)
# add built-in repositories information
self._set_builtin_repositories()
# read custom git repositories
- for repository_element in self._config.path_addons_git.iterdir():
+ for repository_element in self.sys_config.path_addons_git.iterdir():
if repository_element.is_dir():
self._read_git_repository(repository_element)
diff --git a/hassio/addons/git.py b/hassio/addons/git.py
index a00521946..6f487d579 100644
--- a/hassio/addons/git.py
+++ b/hassio/addons/git.py
@@ -45,7 +45,7 @@ class GitRepo(CoreSysAttributes):
async with self.lock:
try:
_LOGGER.info("Load addon %s repository", self.path)
- self.repo = await self._loop.run_in_executor(
+ self.repo = await self.sys_loop.run_in_executor(
None, git.Repo, str(self.path))
except (git.InvalidGitRepositoryError, git.NoSuchPathError,
@@ -68,7 +68,7 @@ class GitRepo(CoreSysAttributes):
try:
_LOGGER.info("Clone addon %s repository", self.url)
- self.repo = await self._loop.run_in_executor(None, ft.partial(
+ self.repo = await self.sys_run_in_executor(ft.partial(
git.Repo.clone_from, self.url, str(self.path),
**git_args
))
@@ -89,7 +89,7 @@ class GitRepo(CoreSysAttributes):
async with self.lock:
try:
_LOGGER.info("Pull addon %s repository", self.url)
- await self._loop.run_in_executor(
+ await self.sys_loop.run_in_executor(
None, self.repo.remotes.origin.pull)
except (git.InvalidGitRepositoryError, git.NoSuchPathError,
diff --git a/hassio/addons/repository.py b/hassio/addons/repository.py
index 851e9e037..37d75ea75 100644
--- a/hassio/addons/repository.py
+++ b/hassio/addons/repository.py
@@ -30,7 +30,7 @@ class Repository(CoreSysAttributes):
@property
def _mesh(self):
"""Return data struct repository."""
- return self._addons.data.repositories.get(self._id, {})
+ return self.sys_addons.data.repositories.get(self._id, {})
@property
def slug(self):
diff --git a/hassio/api/__init__.py b/hassio/api/__init__.py
index b91d79485..20195d21c 100644
--- a/hassio/api/__init__.py
+++ b/hassio/api/__init__.py
@@ -9,7 +9,6 @@ from .discovery import APIDiscovery
from .homeassistant import APIHomeAssistant
from .hardware import APIHardware
from .host import APIHost
-from .network import APINetwork
from .proxy import APIProxy
from .supervisor import APISupervisor
from .snapshots import APISnapshots
@@ -28,7 +27,7 @@ class RestAPI(CoreSysAttributes):
self.coresys = coresys
self.security = SecurityMiddleware(coresys)
self.webapp = web.Application(
- middlewares=[self.security.token_validation], loop=self._loop)
+ middlewares=[self.security.token_validation], loop=coresys.loop)
# service stuff
self._handler = None
@@ -44,7 +43,6 @@ class RestAPI(CoreSysAttributes):
self._register_panel()
self._register_addons()
self._register_snapshots()
- self._register_network()
self._register_discovery()
self._register_services()
@@ -61,16 +59,6 @@ class RestAPI(CoreSysAttributes):
web.post('/host/reload', api_host.reload),
])
- def _register_network(self):
- """Register network function."""
- api_net = APINetwork()
- api_net.coresys = self.coresys
-
- self.webapp.add_routes([
- web.get('/network/info', api_net.info),
- web.post('/network/options', api_net.options),
- ])
-
def _register_hardware(self):
"""Register hardware function."""
api_hardware = APIHardware()
@@ -221,10 +209,10 @@ class RestAPI(CoreSysAttributes):
async def start(self):
"""Run rest api webserver."""
- self._handler = self.webapp.make_handler(loop=self._loop)
+ self._handler = self.webapp.make_handler()
try:
- self.server = await self._loop.create_server(
+ self.server = await self.sys_loop.create_server(
self._handler, "0.0.0.0", "80")
except OSError as err:
_LOGGER.fatal(
diff --git a/hassio/api/addons.py b/hassio/api/addons.py
index a4d5b4593..f382c9116 100644
--- a/hassio/api/addons.py
+++ b/hassio/api/addons.py
@@ -43,7 +43,7 @@ class APIAddons(CoreSysAttributes):
def _extract_addon(self, request, check_installed=True):
"""Return addon and if not exists trow a exception."""
- addon = self._addons.get(request.match_info.get('addon'))
+ addon = self.sys_addons.get(request.match_info.get('addon'))
if not addon:
raise RuntimeError("Addon not exists")
@@ -64,7 +64,7 @@ class APIAddons(CoreSysAttributes):
async def list(self, request):
"""Return all addons / repositories ."""
data_addons = []
- for addon in self._addons.list_addons:
+ for addon in self.sys_addons.list_addons:
data_addons.append({
ATTR_NAME: addon.name,
ATTR_SLUG: addon.slug,
@@ -81,7 +81,7 @@ class APIAddons(CoreSysAttributes):
})
data_repositories = []
- for repository in self._addons.list_repositories:
+ for repository in self.sys_addons.list_repositories:
data_repositories.append({
ATTR_SLUG: repository.slug,
ATTR_NAME: repository.name,
@@ -98,7 +98,7 @@ class APIAddons(CoreSysAttributes):
@api_process
async def reload(self, request):
"""Reload all addons data."""
- await asyncio.shield(self._addons.reload(), loop=self._loop)
+ await asyncio.shield(self.sys_addons.reload())
return True
@api_process
@@ -194,13 +194,13 @@ class APIAddons(CoreSysAttributes):
def install(self, request):
"""Install addon."""
addon = self._extract_addon(request, check_installed=False)
- return asyncio.shield(addon.install(), loop=self._loop)
+ return asyncio.shield(addon.install())
@api_process
def uninstall(self, request):
"""Uninstall addon."""
addon = self._extract_addon(request)
- return asyncio.shield(addon.uninstall(), loop=self._loop)
+ return asyncio.shield(addon.uninstall())
@api_process
def start(self, request):
@@ -214,13 +214,13 @@ class APIAddons(CoreSysAttributes):
except vol.Invalid as ex:
raise RuntimeError(humanize_error(options, ex)) from None
- return asyncio.shield(addon.start(), loop=self._loop)
+ return asyncio.shield(addon.start())
@api_process
def stop(self, request):
"""Stop addon."""
addon = self._extract_addon(request)
- return asyncio.shield(addon.stop(), loop=self._loop)
+ return asyncio.shield(addon.stop())
@api_process
def update(self, request):
@@ -230,13 +230,13 @@ class APIAddons(CoreSysAttributes):
if addon.last_version == addon.version_installed:
raise RuntimeError("No update available!")
- return asyncio.shield(addon.update(), loop=self._loop)
+ return asyncio.shield(addon.update())
@api_process
def restart(self, request):
"""Restart addon."""
addon = self._extract_addon(request)
- return asyncio.shield(addon.restart(), loop=self._loop)
+ return asyncio.shield(addon.restart())
@api_process
def rebuild(self, request):
@@ -245,7 +245,7 @@ class APIAddons(CoreSysAttributes):
if not addon.need_build:
raise RuntimeError("Only local build addons are supported")
- return asyncio.shield(addon.rebuild(), loop=self._loop)
+ return asyncio.shield(addon.rebuild())
@api_process_raw(CONTENT_TYPE_BINARY)
def logs(self, request):
@@ -291,4 +291,4 @@ class APIAddons(CoreSysAttributes):
raise RuntimeError("STDIN not supported by addon")
data = await request.read()
- return await asyncio.shield(addon.write_stdin(data), loop=self._loop)
+ return await asyncio.shield(addon.write_stdin(data))
diff --git a/hassio/api/discovery.py b/hassio/api/discovery.py
index fb028fcd9..7ab5f8d2a 100644
--- a/hassio/api/discovery.py
+++ b/hassio/api/discovery.py
@@ -21,7 +21,7 @@ class APIDiscovery(CoreSysAttributes):
def _extract_message(self, request):
"""Extract discovery message from URL."""
- message = self._services.discovery.get(request.match_info.get('uuid'))
+ message = self.sys_discovery.get(request.match_info.get('uuid'))
if not message:
raise RuntimeError("Discovery message not found")
return message
@@ -30,7 +30,7 @@ class APIDiscovery(CoreSysAttributes):
async def list(self, request):
"""Show register services."""
discovery = []
- for message in self._services.discovery.list_messages:
+ for message in self.sys_discovery.list_messages:
discovery.append({
ATTR_PROVIDER: message.provider,
ATTR_UUID: message.uuid,
@@ -45,7 +45,7 @@ class APIDiscovery(CoreSysAttributes):
async def set_discovery(self, request):
"""Write data into a discovery pipeline."""
body = await api_validate(SCHEMA_DISCOVERY, request)
- message = self._services.discovery.send(
+ message = self.sys_discovery.send(
provider=request[REQUEST_FROM], **body)
return {ATTR_UUID: message.uuid}
@@ -68,5 +68,5 @@ class APIDiscovery(CoreSysAttributes):
"""Delete data into a discovery message."""
message = self._extract_message(request)
- self._services.discovery.remove(message)
+ self.sys_discovery.remove(message)
return True
diff --git a/hassio/api/hardware.py b/hassio/api/hardware.py
index e5e22a35f..7830b9675 100644
--- a/hassio/api/hardware.py
+++ b/hassio/api/hardware.py
@@ -16,11 +16,11 @@ class APIHardware(CoreSysAttributes):
async def info(self, request):
"""Show hardware info."""
return {
- ATTR_SERIAL: list(self._hardware.serial_devices),
- ATTR_INPUT: list(self._hardware.input_devices),
- ATTR_DISK: list(self._hardware.disk_devices),
- ATTR_GPIO: list(self._hardware.gpio_devices),
- ATTR_AUDIO: self._hardware.audio_devices,
+ ATTR_SERIAL: list(self.sys_hardware.serial_devices),
+ ATTR_INPUT: list(self.sys_hardware.input_devices),
+ ATTR_DISK: list(self.sys_hardware.disk_devices),
+ ATTR_GPIO: list(self.sys_hardware.gpio_devices),
+ ATTR_AUDIO: self.sys_hardware.audio_devices,
}
@api_process
@@ -28,7 +28,7 @@ class APIHardware(CoreSysAttributes):
"""Show ALSA audio devices."""
return {
ATTR_AUDIO: {
- ATTR_INPUT: self._alsa.input_devices,
- ATTR_OUTPUT: self._alsa.output_devices,
+ ATTR_INPUT: self.sys_host.alsa.input_devices,
+ ATTR_OUTPUT: self.sys_host.alsa.output_devices,
}
}
diff --git a/hassio/api/homeassistant.py b/hassio/api/homeassistant.py
index 86bfaf296..dd5e9698b 100644
--- a/hassio/api/homeassistant.py
+++ b/hassio/api/homeassistant.py
@@ -9,7 +9,8 @@ from ..const import (
ATTR_VERSION, ATTR_LAST_VERSION, ATTR_IMAGE, ATTR_CUSTOM, ATTR_BOOT,
ATTR_PORT, ATTR_PASSWORD, ATTR_SSL, ATTR_WATCHDOG, ATTR_CPU_PERCENT,
ATTR_MEMORY_USAGE, ATTR_MEMORY_LIMIT, ATTR_NETWORK_RX, ATTR_NETWORK_TX,
- ATTR_BLK_READ, ATTR_BLK_WRITE, ATTR_WAIT_BOOT, CONTENT_TYPE_BINARY)
+ ATTR_BLK_READ, ATTR_BLK_WRITE, ATTR_WAIT_BOOT, ATTR_MACHINE,
+ CONTENT_TYPE_BINARY)
from ..coresys import CoreSysAttributes
from ..validate import NETWORK_PORT, DOCKER_IMAGE
@@ -43,15 +44,16 @@ class APIHomeAssistant(CoreSysAttributes):
async def info(self, request):
"""Return host information."""
return {
- ATTR_VERSION: self._homeassistant.version,
- ATTR_LAST_VERSION: self._homeassistant.last_version,
- ATTR_IMAGE: self._homeassistant.image,
- ATTR_CUSTOM: self._homeassistant.is_custom_image,
- ATTR_BOOT: self._homeassistant.boot,
- ATTR_PORT: self._homeassistant.api_port,
- ATTR_SSL: self._homeassistant.api_ssl,
- ATTR_WATCHDOG: self._homeassistant.watchdog,
- ATTR_WAIT_BOOT: self._homeassistant.wait_boot,
+ ATTR_VERSION: self.sys_homeassistant.version,
+ ATTR_LAST_VERSION: self.sys_homeassistant.last_version,
+ ATTR_MACHINE: self.sys_homeassistant.machine,
+ ATTR_IMAGE: self.sys_homeassistant.image,
+ ATTR_CUSTOM: self.sys_homeassistant.is_custom_image,
+ ATTR_BOOT: self.sys_homeassistant.boot,
+ ATTR_PORT: self.sys_homeassistant.api_port,
+ ATTR_SSL: self.sys_homeassistant.api_ssl,
+ ATTR_WATCHDOG: self.sys_homeassistant.watchdog,
+ ATTR_WAIT_BOOT: self.sys_homeassistant.wait_boot,
}
@api_process
@@ -60,34 +62,34 @@ class APIHomeAssistant(CoreSysAttributes):
body = await api_validate(SCHEMA_OPTIONS, request)
if ATTR_IMAGE in body and ATTR_LAST_VERSION in body:
- self._homeassistant.image = body[ATTR_IMAGE]
- self._homeassistant.last_version = body[ATTR_LAST_VERSION]
+ self.sys_homeassistant.image = body[ATTR_IMAGE]
+ self.sys_homeassistant.last_version = body[ATTR_LAST_VERSION]
if ATTR_BOOT in body:
- self._homeassistant.boot = body[ATTR_BOOT]
+ self.sys_homeassistant.boot = body[ATTR_BOOT]
if ATTR_PORT in body:
- self._homeassistant.api_port = body[ATTR_PORT]
+ self.sys_homeassistant.api_port = body[ATTR_PORT]
if ATTR_PASSWORD in body:
- self._homeassistant.api_password = body[ATTR_PASSWORD]
+ self.sys_homeassistant.api_password = body[ATTR_PASSWORD]
if ATTR_SSL in body:
- self._homeassistant.api_ssl = body[ATTR_SSL]
+ self.sys_homeassistant.api_ssl = body[ATTR_SSL]
if ATTR_WATCHDOG in body:
- self._homeassistant.watchdog = body[ATTR_WATCHDOG]
+ self.sys_homeassistant.watchdog = body[ATTR_WATCHDOG]
if ATTR_WAIT_BOOT in body:
- self._homeassistant.wait_boot = body[ATTR_WAIT_BOOT]
+ self.sys_homeassistant.wait_boot = body[ATTR_WAIT_BOOT]
- self._homeassistant.save_data()
+ self.sys_homeassistant.save_data()
return True
@api_process
async def stats(self, request):
"""Return resource information."""
- stats = await self._homeassistant.stats()
+ stats = await self.sys_homeassistant.stats()
if not stats:
raise RuntimeError("No stats available")
@@ -105,38 +107,38 @@ class APIHomeAssistant(CoreSysAttributes):
async def update(self, request):
"""Update homeassistant."""
body = await api_validate(SCHEMA_VERSION, request)
- version = body.get(ATTR_VERSION, self._homeassistant.last_version)
+ version = body.get(ATTR_VERSION, self.sys_homeassistant.last_version)
- if version == self._homeassistant.version:
+ if version == self.sys_homeassistant.version:
raise RuntimeError("Version {} is already in use".format(version))
return await asyncio.shield(
- self._homeassistant.update(version), loop=self._loop)
+ self.sys_homeassistant.update(version))
@api_process
def stop(self, request):
"""Stop homeassistant."""
- return asyncio.shield(self._homeassistant.stop(), loop=self._loop)
+ return asyncio.shield(self.sys_homeassistant.stop())
@api_process
def start(self, request):
"""Start homeassistant."""
- return asyncio.shield(self._homeassistant.start(), loop=self._loop)
+ return asyncio.shield(self.sys_homeassistant.start())
@api_process
def restart(self, request):
"""Restart homeassistant."""
- return asyncio.shield(self._homeassistant.restart(), loop=self._loop)
+ return asyncio.shield(self.sys_homeassistant.restart())
@api_process_raw(CONTENT_TYPE_BINARY)
def logs(self, request):
"""Return homeassistant docker logs."""
- return self._homeassistant.logs()
+ return self.sys_homeassistant.logs()
@api_process
async def check(self, request):
"""Check config of homeassistant."""
- result = await self._homeassistant.check_config()
+ result = await self.sys_homeassistant.check_config()
if not result.valid:
raise RuntimeError(result.log)
diff --git a/hassio/api/host.py b/hassio/api/host.py
index a0b63f2c9..94991a46b 100644
--- a/hassio/api/host.py
+++ b/hassio/api/host.py
@@ -4,10 +4,10 @@ import logging
import voluptuous as vol
-from .utils import api_process_hostcontrol, api_process, api_validate
+from .utils import api_process, api_validate
from ..const import (
- ATTR_VERSION, ATTR_LAST_VERSION, ATTR_TYPE, ATTR_HOSTNAME, ATTR_FEATURES,
- ATTR_OS)
+ ATTR_VERSION, ATTR_LAST_VERSION, ATTR_HOSTNAME, ATTR_FEATURES, ATTR_KERNEL,
+ ATTR_TYPE, ATTR_OPERATING_SYSTEM, ATTR_CHASSIS, ATTR_DEPLOYMENT)
from ..coresys import CoreSysAttributes
_LOGGER = logging.getLogger(__name__)
@@ -16,6 +16,10 @@ SCHEMA_VERSION = vol.Schema({
vol.Optional(ATTR_VERSION): vol.Coerce(str),
})
+SCHEMA_OPTIONS = vol.Schema({
+ vol.Optional(ATTR_HOSTNAME): vol.Coerce(str),
+})
+
class APIHost(CoreSysAttributes):
"""Handle rest api for host functions."""
@@ -24,38 +28,45 @@ class APIHost(CoreSysAttributes):
async def info(self, request):
"""Return host information."""
return {
- ATTR_TYPE: self._host_control.type,
- ATTR_VERSION: self._host_control.version,
- ATTR_LAST_VERSION: self._host_control.last_version,
- ATTR_FEATURES: self._host_control.features,
- ATTR_HOSTNAME: self._host_control.hostname,
- ATTR_OS: self._host_control.os_info,
+ ATTR_CHASSIS: self.sys_host.info.chassis,
+ ATTR_VERSION: None,
+ ATTR_LAST_VERSION: None,
+ ATTR_TYPE: None,
+ ATTR_FEATURES: self.sys_host.supperted_features,
+ ATTR_HOSTNAME: self.sys_host.info.hostname,
+ ATTR_OPERATING_SYSTEM: self.sys_host.info.operating_system,
+ ATTR_DEPLOYMENT: self.sys_host.info.deployment,
+ ATTR_KERNEL: self.sys_host.info.kernel,
}
- @api_process_hostcontrol
+ @api_process
+ async def options(self, request):
+ """Edit host settings."""
+ body = await api_validate(SCHEMA_OPTIONS, request)
+
+ # hostname
+ if ATTR_HOSTNAME in body:
+ await asyncio.shield(
+ self.sys_host.control.set_hostname(body[ATTR_HOSTNAME]))
+
+ @api_process
def reboot(self, request):
"""Reboot host."""
- return self._host_control.reboot()
+ return asyncio.shield(self.sys_host.control.reboot())
- @api_process_hostcontrol
+ @api_process
def shutdown(self, request):
"""Poweroff host."""
- return self._host_control.shutdown()
+ return asyncio.shield(self.sys_host.control.shutdown())
- @api_process_hostcontrol
- async def reload(self, request):
+ @api_process
+ def reload(self, request):
"""Reload host data."""
- await self._host_control.load()
- return True
+ return asyncio.shield(self.sys_host.reload())
- @api_process_hostcontrol
+ @api_process
async def update(self, request):
"""Update host OS."""
- body = await api_validate(SCHEMA_VERSION, request)
- version = body.get(ATTR_VERSION, self._host_control.last_version)
-
- if version == self._host_control.version:
- raise RuntimeError(f"Version {version} is already in use")
-
- return await asyncio.shield(
- self._host_control.update(version=version), loop=self._loop)
+ pass
+ # body = await api_validate(SCHEMA_VERSION, request)
+ # version = body.get(ATTR_VERSION, self.sys_host.last_version)
diff --git a/hassio/api/network.py b/hassio/api/network.py
deleted file mode 100644
index c5c647066..000000000
--- a/hassio/api/network.py
+++ /dev/null
@@ -1,38 +0,0 @@
-"""Init file for HassIO network rest api."""
-import logging
-
-import voluptuous as vol
-
-from .utils import api_process, api_process_hostcontrol, api_validate
-from ..const import ATTR_HOSTNAME
-from ..coresys import CoreSysAttributes
-
-_LOGGER = logging.getLogger(__name__)
-
-
-SCHEMA_OPTIONS = vol.Schema({
- vol.Optional(ATTR_HOSTNAME): vol.Coerce(str),
-})
-
-
-class APINetwork(CoreSysAttributes):
- """Handle rest api for network functions."""
-
- @api_process
- async def info(self, request):
- """Show network settings."""
- return {
- ATTR_HOSTNAME: self._host_control.hostname,
- }
-
- @api_process_hostcontrol
- async def options(self, request):
- """Edit network settings."""
- body = await api_validate(SCHEMA_OPTIONS, request)
-
- # hostname
- if ATTR_HOSTNAME in body:
- if self._host_control.hostname != body[ATTR_HOSTNAME]:
- await self._host_control.set_hostname(body[ATTR_HOSTNAME])
-
- return True
diff --git a/hassio/api/panel/hassio-app.html b/hassio/api/panel/hassio-app.html
index f1d3192ae..09f945df5 100644
--- a/hassio/api/panel/hassio-app.html
+++ b/hassio/api/panel/hassio-app.html
@@ -18,8 +18,8 @@
.wave{opacity:0;}#waves,
.wave{overflow:hidden;}.wave-container,
.wave{border-radius:50%;}:host(.circle) #background,
- :host(.circle) #waves{border-radius:50%;}:host(.circle) .wave-container{overflow:hidden;}