diff --git a/API.md b/API.md index 9b78563d9..9e14112d4 100644 --- a/API.md +++ b/API.md @@ -226,14 +226,15 @@ return: ```json { - "type": "", - "version": "", - "last_version": "", - "features": ["shutdown", "reboot", "update", "hostname", "network_info", "network_control"], - "hostname": "", - "operating_system": "", - "kernel": "", - "chassis": "" + "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", } ``` @@ -302,6 +303,7 @@ Optional: { "version": "INSTALL_VERSION", "last_version": "LAST_VERSION", + "machine": "Image machine type", "image": "str", "custom": "bool -> if custom image", "boot": "bool", diff --git a/hassio/api/homeassistant.py b/hassio/api/homeassistant.py index 8e9c07359..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 @@ -45,6 +46,7 @@ class APIHomeAssistant(CoreSysAttributes): return { 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, diff --git a/hassio/api/host.py b/hassio/api/host.py index 8e1676ef1..fdf8e2d45 100644 --- a/hassio/api/host.py +++ b/hassio/api/host.py @@ -1,13 +1,12 @@ """Init file for HassIO host rest api.""" -import asyncio import logging import voluptuous as vol from .utils import api_process, api_validate from ..const import ( - ATTR_VERSION, ATTR_LAST_VERSION, ATTR_TYPE, ATTR_HOSTNAME, ATTR_FEATURES, - ATTR_OPERATING_SYSTEM, ATTR_KERNEL, ATTR_CHASSIS) + 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__) @@ -28,14 +27,15 @@ class APIHost(CoreSysAttributes): async def info(self, request): """Return host information.""" return { - ATTR_TYPE: None, - ATTR_CHASSIS: self.sys_host.local.chassis, + 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.local.hostname, - ATTR_OPERATING_SYSTEM: self.sys_host.local.operating_system, - ATTR_KERNEL: self.sys_host.local.kernel, + 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 @@ -45,31 +45,26 @@ class APIHost(CoreSysAttributes): # hostname if ATTR_HOSTNAME in body: - await self.sys_host.local.set_hostname(body[ATTR_HOSTNAME]) + await self.sys_host.control.set_hostname(body[ATTR_HOSTNAME]) @api_process def reboot(self, request): """Reboot host.""" - return self.sys_host.power.reboot() + return self.sys_host.control.reboot() @api_process def shutdown(self, request): """Poweroff host.""" - return self.sys_host.power.shutdown() + return self.sys_host.control.shutdown() @api_process def reload(self, request): """Reload host data.""" - return self._host_control.load() + return self.sys_host.reload() @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)) + pass + # body = await api_validate(SCHEMA_VERSION, request) + # version = body.get(ATTR_VERSION, self.sys_host.last_version) diff --git a/hassio/const.py b/hassio/const.py index ad5b26cb4..af6668023 100644 --- a/hassio/const.py +++ b/hassio/const.py @@ -52,7 +52,9 @@ ENV_TIME = 'TZ' REQUEST_FROM = 'HASSIO_FROM' +ATTR_MACHINE = 'machine' ATTR_WAIT_BOOT = 'wait_boot' +ATTR_DEPLOYMENT = 'deployment' ATTR_WATCHDOG = 'watchdog' ATTR_CHANGELOG = 'changelog' ATTR_DATE = 'date' diff --git a/hassio/dbus/utils.py b/hassio/dbus/utils.py index b8656a235..94da81d9a 100644 --- a/hassio/dbus/utils.py +++ b/hassio/dbus/utils.py @@ -8,7 +8,7 @@ def dbus_connected(method): def wrap_dbus(api, *args, **kwargs): """Check if dbus is connected before call a method.""" if api.dbus is None: - raise DBusNotConnectedError(f"{api!s} not connected to dbus!") + raise DBusNotConnectedError() return method(api, *args, **kwargs) return wrap_dbus diff --git a/hassio/exceptions.py b/hassio/exceptions.py index 4c4f66a36..09e06bf00 100644 --- a/hassio/exceptions.py +++ b/hassio/exceptions.py @@ -35,7 +35,7 @@ class DBusError(HassioError): pass -class DBusNotConnectedError(HassioNotSupportedError): +class DBusNotConnectedError(HostNotSupportedError): """DBus is not connected and call a method.""" diff --git a/hassio/host/__init__.py b/hassio/host/__init__.py index 659b4cdf5..af72f448d 100644 --- a/hassio/host/__init__.py +++ b/hassio/host/__init__.py @@ -1,8 +1,8 @@ """Host function like audio/dbus/systemd.""" from .alsa import AlsaAudio -from .power import PowerControl -from .local import LocalCenter +from .control import SystemControl +from .info import InfoCenter from ..const import FEATURES_REBOOT, FEATURES_SHUTDOWN, FEATURES_HOSTNAME from ..coresys import CoreSysAttributes @@ -14,8 +14,8 @@ class HostManager(CoreSysAttributes): """Initialize Host manager.""" self.coresys = coresys self._alsa = AlsaAudio(coresys) - self._power = PowerControl(coresys) - self._local = LocalCenter(coresys) + self._control = SystemControl(coresys) + self._info = InfoCenter(coresys) @property def alsa(self): @@ -23,14 +23,14 @@ class HostManager(CoreSysAttributes): return self._alsa @property - def power(self): - """Return host power handler.""" - return self._power + def control(self): + """Return host control handler.""" + return self._control @property - def local(self): - """Return host local handler.""" - return self._local + def info(self): + """Return host info handler.""" + return self._info @property def supperted_features(self): @@ -51,7 +51,7 @@ class HostManager(CoreSysAttributes): async def load(self): """Load host functions.""" if self.sys_dbus.hostname.is_connected: - await self.local.update() + await self.info.update() def reload(self): """Reload host information.""" diff --git a/hassio/host/power.py b/hassio/host/control.py similarity index 66% rename from hassio/host/power.py rename to hassio/host/control.py index f620e15b2..77559bc4d 100644 --- a/hassio/host/power.py +++ b/hassio/host/control.py @@ -7,14 +7,14 @@ from ..exceptions import HostNotSupportedError _LOGGER = logging.getLogger(__name__) -class PowerControl(CoreSysAttributes): +class SystemControl(CoreSysAttributes): """Handle host power controls.""" def __init__(self, coresys): """Initialize host power handling.""" self.coresys = coresys - def _check_dbus(self): + def _check_systemd(self): """Check if systemd is connect or raise error.""" if not self.sys_dbus.systemd.is_connected: _LOGGER.error("No systemd dbus connection available") @@ -22,7 +22,7 @@ class PowerControl(CoreSysAttributes): async def reboot(self): """Reboot host system.""" - self._check_dbus() + self._check_systemd() _LOGGER.info("Initialize host reboot over systemd") try: @@ -32,10 +32,20 @@ class PowerControl(CoreSysAttributes): async def shutdown(self): """Shutdown host system.""" - self._check_dbus() + self._check_systemd() _LOGGER.info("Initialize host power off over systemd") try: await self.sys_core.shutdown() finally: await self.sys_dbus.systemd.power_off() + + async def set_hostname(self, hostname): + """Set local a new Hostname.""" + if not self.sys_dbus.systemd.is_connected: + _LOGGER.error("No hostname dbus connection available") + raise HostNotSupportedError() + + _LOGGER.info("Set Hostname %s", hostname) + await self.sys_dbus.hostname.set_hostname(hostname) + await self.sys_host.info.update() diff --git a/hassio/host/local.py b/hassio/host/info.py similarity index 60% rename from hassio/host/local.py rename to hassio/host/info.py index ab41be753..af282c4c7 100644 --- a/hassio/host/local.py +++ b/hassio/host/info.py @@ -6,10 +6,8 @@ from ..exceptions import HassioError, HostNotSupportedError _LOGGER = logging.getLogger(__name__) -UNKNOWN = 'Unknown' - -class LocalCenter(CoreSysAttributes): +class InfoCenter(CoreSysAttributes): """Handle local system information controls.""" def __init__(self, coresys): @@ -20,48 +18,41 @@ class LocalCenter(CoreSysAttributes): @property def hostname(self): """Return local hostname.""" - return self._data.get('Hostname', UNKNOWN) + return self._data.get('Hostname') or None @property def chassis(self): """Return local chassis type.""" - return self._data.get('Chassis', UNKNOWN) + return self._data.get('Chassis') or None + + @property + def deployment(self): + """Return local deployment type.""" + return self._data.get('Deployment') or None @property def kernel(self): """Return local kernel version.""" - return self._data.get('KernelRelease', UNKNOWN) + return self._data.get('KernelRelease') or None @property def operating_system(self): """Return local operating system.""" - return self._data.get('OperatingSystemPrettyName', UNKNOWN) + return self._data.get('OperatingSystemPrettyName') or None @property def cpe(self): """Return local CPE.""" - return self._data.get('OperatingSystemCPEName', UNKNOWN) - - def _check_dbus(self): - """Check if systemd is connect or raise error.""" - if not self.sys_dbus.hostname.is_connected: - _LOGGER.error("No hostname dbus connection available") - raise HostNotSupportedError() + return self._data.get('OperatingSystemCPEName') or None async def update(self): """Update properties over dbus.""" - self._check_dbus() + if not self.sys_dbus.systemd.is_connected: + _LOGGER.error("No hostname dbus connection available") + raise HostNotSupportedError() _LOGGER.info("Update local host information") try: self._data = await self.sys_dbus.hostname.get_properties() except HassioError: _LOGGER.warning("Can't update host system information!") - - async def set_hostname(self, hostname): - """Set local a new Hostname.""" - self._check_dbus() - - _LOGGER.info("Set Hostname %s", hostname) - await self.sys_dbus.hostname.set_hostname(hostname) - await self.update()