mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-28 11:36:32 +00:00
commit
d98b4f039f
79
API.md
79
API.md
@ -1,10 +1,11 @@
|
|||||||
# HassIO Server
|
# Hass.io Server
|
||||||
|
|
||||||
## HassIO REST API
|
## Hass.io RESTful API
|
||||||
|
|
||||||
Interface for Home Assistant to control things from supervisor.
|
Interface for Home Assistant to control things from supervisor.
|
||||||
|
|
||||||
On error:
|
On error:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"result": "error",
|
"result": "error",
|
||||||
@ -12,7 +13,8 @@ On error:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
On success
|
On success:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"result": "ok",
|
"result": "ok",
|
||||||
@ -20,10 +22,9 @@ On success
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### HassIO
|
### Hass.io
|
||||||
|
|
||||||
- GET `/supervisor/ping`
|
- GET `/supervisor/ping`
|
||||||
|
|
||||||
- GET `/supervisor/info`
|
- GET `/supervisor/info`
|
||||||
|
|
||||||
The addons from `addons` are only installed one.
|
The addons from `addons` are only installed one.
|
||||||
@ -54,7 +55,9 @@ The addons from `addons` are only installed one.
|
|||||||
```
|
```
|
||||||
|
|
||||||
- POST `/supervisor/update`
|
- POST `/supervisor/update`
|
||||||
|
|
||||||
Optional:
|
Optional:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"version": "VERSION"
|
"version": "VERSION"
|
||||||
@ -62,6 +65,7 @@ Optional:
|
|||||||
```
|
```
|
||||||
|
|
||||||
- POST `/supervisor/options`
|
- POST `/supervisor/options`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"beta_channel": "true|false",
|
"beta_channel": "true|false",
|
||||||
@ -78,11 +82,12 @@ Reload addons/version.
|
|||||||
|
|
||||||
- GET `/supervisor/logs`
|
- GET `/supervisor/logs`
|
||||||
|
|
||||||
Output the raw docker log
|
Output is the raw docker log.
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
- GET `/security/info`
|
- GET `/security/info`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"initialize": "bool",
|
"initialize": "bool",
|
||||||
@ -91,6 +96,7 @@ Output the raw docker log
|
|||||||
```
|
```
|
||||||
|
|
||||||
- POST `/security/options`
|
- POST `/security/options`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"password": "xy"
|
"password": "xy"
|
||||||
@ -98,6 +104,7 @@ Output the raw docker log
|
|||||||
```
|
```
|
||||||
|
|
||||||
- POST `/security/totp`
|
- POST `/security/totp`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"password": "xy"
|
"password": "xy"
|
||||||
@ -117,6 +124,7 @@ Return QR-Code
|
|||||||
### Backup/Snapshot
|
### Backup/Snapshot
|
||||||
|
|
||||||
- GET `/snapshots`
|
- GET `/snapshots`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"snapshots": [
|
"snapshots": [
|
||||||
@ -132,6 +140,7 @@ Return QR-Code
|
|||||||
- POST `/snapshots/reload`
|
- POST `/snapshots/reload`
|
||||||
|
|
||||||
- POST `/snapshots/new/full`
|
- POST `/snapshots/new/full`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"name": "Optional"
|
"name": "Optional"
|
||||||
@ -139,6 +148,7 @@ Return QR-Code
|
|||||||
```
|
```
|
||||||
|
|
||||||
- POST `/snapshots/new/partial`
|
- POST `/snapshots/new/partial`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"name": "Optional",
|
"name": "Optional",
|
||||||
@ -150,6 +160,7 @@ Return QR-Code
|
|||||||
- POST `/snapshots/reload`
|
- POST `/snapshots/reload`
|
||||||
|
|
||||||
- GET `/snapshots/{slug}/info`
|
- GET `/snapshots/{slug}/info`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"slug": "SNAPSHOT ID",
|
"slug": "SNAPSHOT ID",
|
||||||
@ -174,10 +185,9 @@ Return QR-Code
|
|||||||
```
|
```
|
||||||
|
|
||||||
- POST `/snapshots/{slug}/remove`
|
- POST `/snapshots/{slug}/remove`
|
||||||
|
|
||||||
- POST `/snapshots/{slug}/restore/full`
|
- POST `/snapshots/{slug}/restore/full`
|
||||||
|
|
||||||
- POST `/snapshots/{slug}/restore/partial`
|
- POST `/snapshots/{slug}/restore/partial`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"homeassistant": "bool",
|
"homeassistant": "bool",
|
||||||
@ -187,14 +197,14 @@ Return QR-Code
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Host
|
### Host
|
||||||
|
|
||||||
- POST `/host/reload`
|
- POST `/host/reload`
|
||||||
|
|
||||||
- POST `/host/shutdown`
|
- POST `/host/shutdown`
|
||||||
|
|
||||||
- POST `/host/reboot`
|
- POST `/host/reboot`
|
||||||
|
|
||||||
- GET `/host/info`
|
- GET `/host/info`
|
||||||
|
|
||||||
See HostControl info command.
|
See HostControl info command.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"type": "",
|
"type": "",
|
||||||
@ -207,16 +217,37 @@ See HostControl info command.
|
|||||||
```
|
```
|
||||||
|
|
||||||
- POST `/host/update`
|
- POST `/host/update`
|
||||||
|
|
||||||
Optional:
|
Optional:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"version": "VERSION"
|
"version": "VERSION"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- GET `/host/hardware`
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"serial": ["/dev/xy"],
|
||||||
|
"input": ["Input device name"],
|
||||||
|
"disk": ["/dev/sdax"],
|
||||||
|
"audio": {
|
||||||
|
"CARD_ID": {
|
||||||
|
"name": "xy",
|
||||||
|
"type": "microphone",
|
||||||
|
"devices": {
|
||||||
|
"DEV_ID": "type of device"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Network
|
### Network
|
||||||
|
|
||||||
- GET `/network/info`
|
- GET `/network/info`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"hostname": ""
|
"hostname": ""
|
||||||
@ -224,6 +255,7 @@ Optional:
|
|||||||
```
|
```
|
||||||
|
|
||||||
- POST `/network/options`
|
- POST `/network/options`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"hostname": "",
|
"hostname": "",
|
||||||
@ -250,7 +282,9 @@ Optional:
|
|||||||
```
|
```
|
||||||
|
|
||||||
- POST `/homeassistant/update`
|
- POST `/homeassistant/update`
|
||||||
|
|
||||||
Optional:
|
Optional:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"version": "VERSION"
|
"version": "VERSION"
|
||||||
@ -259,11 +293,11 @@ Optional:
|
|||||||
|
|
||||||
- GET `/homeassistant/logs`
|
- GET `/homeassistant/logs`
|
||||||
|
|
||||||
Output the raw docker log
|
Output is the raw Docker log.
|
||||||
|
|
||||||
- POST `/homeassistant/restart`
|
- POST `/homeassistant/restart`
|
||||||
|
|
||||||
- POST `/homeassistant/options`
|
- POST `/homeassistant/options`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"devices": [],
|
"devices": [],
|
||||||
@ -274,11 +308,11 @@ Output the raw docker log
|
|||||||
|
|
||||||
Image with `null` and last_version with `null` reset this options.
|
Image with `null` and last_version with `null` reset this options.
|
||||||
|
|
||||||
### REST API addons
|
### RESTful for API addons
|
||||||
|
|
||||||
- GET `/addons`
|
- GET `/addons`
|
||||||
|
|
||||||
Get all available addons
|
Get all available addons.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -312,8 +346,8 @@ Get all available addons
|
|||||||
```
|
```
|
||||||
|
|
||||||
- POST `/addons/reload`
|
- POST `/addons/reload`
|
||||||
|
|
||||||
- GET `/addons/{addon}/info`
|
- GET `/addons/{addon}/info`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"name": "xy bla",
|
"name": "xy bla",
|
||||||
@ -340,6 +374,7 @@ Get all available addons
|
|||||||
- GET `/addons/{addon}/logo`
|
- GET `/addons/{addon}/logo`
|
||||||
|
|
||||||
- POST `/addons/{addon}/options`
|
- POST `/addons/{addon}/options`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"boot": "auto|manual",
|
"boot": "auto|manual",
|
||||||
@ -358,7 +393,9 @@ For reset custom network settings, set it `null`.
|
|||||||
- POST `/addons/{addon}/stop`
|
- POST `/addons/{addon}/stop`
|
||||||
|
|
||||||
- POST `/addons/{addon}/install`
|
- POST `/addons/{addon}/install`
|
||||||
|
|
||||||
Optional:
|
Optional:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"version": "VERSION"
|
"version": "VERSION"
|
||||||
@ -368,7 +405,9 @@ Optional:
|
|||||||
- POST `/addons/{addon}/uninstall`
|
- POST `/addons/{addon}/uninstall`
|
||||||
|
|
||||||
- POST `/addons/{addon}/update`
|
- POST `/addons/{addon}/update`
|
||||||
|
|
||||||
Optional:
|
Optional:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"version": "VERSION"
|
"version": "VERSION"
|
||||||
@ -377,15 +416,16 @@ Optional:
|
|||||||
|
|
||||||
- GET `/addons/{addon}/logs`
|
- GET `/addons/{addon}/logs`
|
||||||
|
|
||||||
Output the raw docker log
|
Output is the raw Docker log.
|
||||||
|
|
||||||
- POST `/addons/{addon}/restart`
|
- POST `/addons/{addon}/restart`
|
||||||
|
|
||||||
## Host Control
|
## Host Control
|
||||||
|
|
||||||
Communicate over unix socket with a host daemon.
|
Communicate over UNIX socket with a host daemon.
|
||||||
|
|
||||||
- commands
|
- commands
|
||||||
|
|
||||||
```
|
```
|
||||||
# info
|
# info
|
||||||
-> {'type', 'version', 'last_version', 'features', 'hostname'}
|
-> {'type', 'version', 'last_version', 'features', 'hostname'}
|
||||||
@ -404,7 +444,8 @@ Communicate over unix socket with a host daemon.
|
|||||||
# network int route xy
|
# network int route xy
|
||||||
```
|
```
|
||||||
|
|
||||||
features:
|
Features:
|
||||||
|
|
||||||
- shutdown
|
- shutdown
|
||||||
- reboot
|
- reboot
|
||||||
- update
|
- update
|
||||||
|
@ -28,11 +28,12 @@ class RestAPI(object):
|
|||||||
self._handler = None
|
self._handler = None
|
||||||
self.server = None
|
self.server = None
|
||||||
|
|
||||||
def register_host(self, host_control):
|
def register_host(self, host_control, hardware):
|
||||||
"""Register hostcontrol function."""
|
"""Register hostcontrol function."""
|
||||||
api_host = APIHost(self.config, self.loop, host_control)
|
api_host = APIHost(self.config, self.loop, host_control, hardware)
|
||||||
|
|
||||||
self.webapp.router.add_get('/host/info', api_host.info)
|
self.webapp.router.add_get('/host/info', api_host.info)
|
||||||
|
self.webapp.router.add_get('/host/hardware', api_host.hardware)
|
||||||
self.webapp.router.add_post('/host/reboot', api_host.reboot)
|
self.webapp.router.add_post('/host/reboot', api_host.reboot)
|
||||||
self.webapp.router.add_post('/host/shutdown', api_host.shutdown)
|
self.webapp.router.add_post('/host/shutdown', api_host.shutdown)
|
||||||
self.webapp.router.add_post('/host/update', api_host.update)
|
self.webapp.router.add_post('/host/update', api_host.update)
|
||||||
|
@ -7,7 +7,7 @@ import voluptuous as vol
|
|||||||
from .util import api_process_hostcontrol, api_process, api_validate
|
from .util import api_process_hostcontrol, api_process, api_validate
|
||||||
from ..const import (
|
from ..const import (
|
||||||
ATTR_VERSION, ATTR_LAST_VERSION, ATTR_TYPE, ATTR_HOSTNAME, ATTR_FEATURES,
|
ATTR_VERSION, ATTR_LAST_VERSION, ATTR_TYPE, ATTR_HOSTNAME, ATTR_FEATURES,
|
||||||
ATTR_OS)
|
ATTR_OS, ATTR_SERIAL, ATTR_INPUT, ATTR_DISK, ATTR_AUDIO)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -19,11 +19,12 @@ SCHEMA_VERSION = vol.Schema({
|
|||||||
class APIHost(object):
|
class APIHost(object):
|
||||||
"""Handle rest api for host functions."""
|
"""Handle rest api for host functions."""
|
||||||
|
|
||||||
def __init__(self, config, loop, host_control):
|
def __init__(self, config, loop, host_control, hardware):
|
||||||
"""Initialize host rest api part."""
|
"""Initialize host rest api part."""
|
||||||
self.config = config
|
self.config = config
|
||||||
self.loop = loop
|
self.loop = loop
|
||||||
self.host_control = host_control
|
self.host_control = host_control
|
||||||
|
self.local_hw = hardware
|
||||||
|
|
||||||
@api_process
|
@api_process
|
||||||
async def info(self, request):
|
async def info(self, request):
|
||||||
@ -58,3 +59,13 @@ class APIHost(object):
|
|||||||
|
|
||||||
return await asyncio.shield(
|
return await asyncio.shield(
|
||||||
self.host_control.update(version=version), loop=self.loop)
|
self.host_control.update(version=version), loop=self.loop)
|
||||||
|
|
||||||
|
@api_process
|
||||||
|
async def hardware(self, request):
|
||||||
|
"""Return local hardware infos."""
|
||||||
|
return {
|
||||||
|
ATTR_SERIAL: self.local_hw.serial_devices,
|
||||||
|
ATTR_INPUT: self.local_hw.input_devices,
|
||||||
|
ATTR_DISK: self.local_hw.disk_devices,
|
||||||
|
ATTR_AUDIO: self.local_hw.audio_devices,
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Const file for HassIO."""
|
"""Const file for HassIO."""
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
HASSIO_VERSION = '0.48'
|
HASSIO_VERSION = '0.49'
|
||||||
|
|
||||||
URL_HASSIO_VERSION = ('https://raw.githubusercontent.com/home-assistant/'
|
URL_HASSIO_VERSION = ('https://raw.githubusercontent.com/home-assistant/'
|
||||||
'hassio/master/version.json')
|
'hassio/master/version.json')
|
||||||
@ -101,6 +101,10 @@ ATTR_TYPE = 'type'
|
|||||||
ATTR_TIMEOUT = 'timeout'
|
ATTR_TIMEOUT = 'timeout'
|
||||||
ATTR_AUTO_UPDATE = 'auto_update'
|
ATTR_AUTO_UPDATE = 'auto_update'
|
||||||
ATTR_CUSTOM = 'custom'
|
ATTR_CUSTOM = 'custom'
|
||||||
|
ATTR_AUDIO = 'audio'
|
||||||
|
ATTR_INPUT = 'input'
|
||||||
|
ATTR_DISK = 'disk'
|
||||||
|
ATTR_SERIAL = 'serial'
|
||||||
|
|
||||||
STARTUP_INITIALIZE = 'initialize'
|
STARTUP_INITIALIZE = 'initialize'
|
||||||
STARTUP_SYSTEM = 'system'
|
STARTUP_SYSTEM = 'system'
|
||||||
|
@ -14,6 +14,7 @@ from .const import (
|
|||||||
RUN_CLEANUP_API_SESSIONS, STARTUP_SYSTEM, STARTUP_SERVICES,
|
RUN_CLEANUP_API_SESSIONS, STARTUP_SYSTEM, STARTUP_SERVICES,
|
||||||
STARTUP_APPLICATION, STARTUP_INITIALIZE, RUN_RELOAD_SNAPSHOTS_TASKS,
|
STARTUP_APPLICATION, STARTUP_INITIALIZE, RUN_RELOAD_SNAPSHOTS_TASKS,
|
||||||
RUN_UPDATE_ADDONS_TASKS)
|
RUN_UPDATE_ADDONS_TASKS)
|
||||||
|
from .hardware import Hardware
|
||||||
from .homeassistant import HomeAssistant
|
from .homeassistant import HomeAssistant
|
||||||
from .scheduler import Scheduler
|
from .scheduler import Scheduler
|
||||||
from .dock.supervisor import DockerSupervisor
|
from .dock.supervisor import DockerSupervisor
|
||||||
@ -36,6 +37,7 @@ class HassIO(object):
|
|||||||
self.websession = aiohttp.ClientSession(loop=loop)
|
self.websession = aiohttp.ClientSession(loop=loop)
|
||||||
self.scheduler = Scheduler(loop)
|
self.scheduler = Scheduler(loop)
|
||||||
self.api = RestAPI(config, loop)
|
self.api = RestAPI(config, loop)
|
||||||
|
self.hardware = Hardware()
|
||||||
self.dock = docker.DockerClient(
|
self.dock = docker.DockerClient(
|
||||||
base_url="unix:/{}".format(str(SOCKET_DOCKER)), version='auto')
|
base_url="unix:/{}".format(str(SOCKET_DOCKER)), version='auto')
|
||||||
|
|
||||||
@ -81,7 +83,7 @@ class HassIO(object):
|
|||||||
self.host_control.load, RUN_UPDATE_INFO_TASKS)
|
self.host_control.load, RUN_UPDATE_INFO_TASKS)
|
||||||
|
|
||||||
# rest api views
|
# rest api views
|
||||||
self.api.register_host(self.host_control)
|
self.api.register_host(self.host_control, self.hardware)
|
||||||
self.api.register_network(self.host_control)
|
self.api.register_network(self.host_control)
|
||||||
self.api.register_supervisor(
|
self.api.register_supervisor(
|
||||||
self.supervisor, self.snapshots, self.addons, self.host_control,
|
self.supervisor, self.snapshots, self.addons, self.host_control,
|
||||||
|
@ -107,6 +107,7 @@ class DockerAddon(DockerBase):
|
|||||||
self.dock.containers.run(
|
self.dock.containers.run(
|
||||||
self.image,
|
self.image,
|
||||||
name=self.name,
|
name=self.name,
|
||||||
|
hostname=self.name,
|
||||||
detach=True,
|
detach=True,
|
||||||
network_mode=self.addon.network_mode,
|
network_mode=self.addon.network_mode,
|
||||||
ports=self.addon.ports,
|
ports=self.addon.ports,
|
||||||
|
@ -50,6 +50,7 @@ class DockerHomeAssistant(DockerBase):
|
|||||||
self.dock.containers.run(
|
self.dock.containers.run(
|
||||||
self.image,
|
self.image,
|
||||||
name=self.name,
|
name=self.name,
|
||||||
|
hostname=self.name,
|
||||||
detach=True,
|
detach=True,
|
||||||
privileged=True,
|
privileged=True,
|
||||||
devices=self.devices,
|
devices=self.devices,
|
||||||
|
87
hassio/hardware.py
Normal file
87
hassio/hardware.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
"""Read hardware info from system."""
|
||||||
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
import pyudev
|
||||||
|
|
||||||
|
from .const import ATTR_NAME, ATTR_TYPE, ATTR_DEVICES
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
ASOUND_CARDS = Path("/proc/asound/cards")
|
||||||
|
RE_CARDS = re.compile(r"(\d+) \[(\w*) *\]: (.*\w)")
|
||||||
|
|
||||||
|
ASOUND_DEVICES = Path("/proc/asound/devices")
|
||||||
|
RE_DEVICES = re.compile(r"\[.*(\d+)- (\d+).*\]: ([\w ]*)")
|
||||||
|
|
||||||
|
|
||||||
|
class Hardware(object):
|
||||||
|
"""Represent a interface to procfs, sysfs and udev."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""Init hardware object."""
|
||||||
|
self.context = pyudev.Context()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def serial_devices(self):
|
||||||
|
"""Return all serial and connected devices."""
|
||||||
|
dev_list = set()
|
||||||
|
for device in self.context.list_devices(subsystem='tty'):
|
||||||
|
if 'ID_VENDOR' in device:
|
||||||
|
dev_list.add(device.device_node)
|
||||||
|
|
||||||
|
return list(dev_list)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def input_devices(self):
|
||||||
|
"""Return all input devices."""
|
||||||
|
dev_list = set()
|
||||||
|
for device in self.context.list_devices(subsystem='input'):
|
||||||
|
if 'NAME' in device:
|
||||||
|
dev_list.add(device['NAME'].replace('"', ''))
|
||||||
|
|
||||||
|
return list(dev_list)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def disk_devices(self):
|
||||||
|
"""Return all disk devices."""
|
||||||
|
dev_list = set()
|
||||||
|
for device in self.context.list_devices(subsystem='block'):
|
||||||
|
if 'ID_VENDOR' in device:
|
||||||
|
dev_list.add(device.device_node)
|
||||||
|
|
||||||
|
return list(dev_list)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def audio_devices(self):
|
||||||
|
"""Return all available audio interfaces."""
|
||||||
|
try:
|
||||||
|
with ASOUND_CARDS.open('r') as cards_file:
|
||||||
|
cards = cards_file.read()
|
||||||
|
with ASOUND_DEVICES.open('r') as devices_file:
|
||||||
|
devices = devices_file.read()
|
||||||
|
except OSError as err:
|
||||||
|
_LOGGER.error("Can't read asound data -> %s", err)
|
||||||
|
return
|
||||||
|
|
||||||
|
audio_list = {}
|
||||||
|
|
||||||
|
# parse cards
|
||||||
|
for match in RE_CARDS.finditer(cards):
|
||||||
|
audio_list[match.group(1)] = {
|
||||||
|
ATTR_NAME: match.group(3),
|
||||||
|
ATTR_TYPE: match.group(2),
|
||||||
|
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)
|
||||||
|
except KeyError:
|
||||||
|
_LOGGER.warning("Wrong audio device found %s", match.group(0))
|
||||||
|
continue
|
||||||
|
|
||||||
|
return audio_list
|
File diff suppressed because one or more lines are too long
Binary file not shown.
3
setup.py
3
setup.py
@ -46,6 +46,7 @@ setup(
|
|||||||
'gitpython',
|
'gitpython',
|
||||||
'pyotp',
|
'pyotp',
|
||||||
'pyqrcode',
|
'pyqrcode',
|
||||||
'pytz'
|
'pytz',
|
||||||
|
'pyudev'
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"hassio": "0.48",
|
"hassio": "0.49",
|
||||||
"homeassistant": "0.49.1",
|
"homeassistant": "0.49.1",
|
||||||
"resinos": "1.0",
|
"resinos": "1.0",
|
||||||
"resinhup": "0.3",
|
"resinhup": "0.3",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user