mirror of https://github.com/home-assistant/core
127 lines
4.0 KiB
Python
127 lines
4.0 KiB
Python
"""Support for controlling Sisyphus Kinetic Art Tables."""
|
|
|
|
import asyncio
|
|
import logging
|
|
|
|
from sisyphus_control import Table
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.const import CONF_HOST, CONF_NAME, EVENT_HOMEASSISTANT_STOP, Platform
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|
import homeassistant.helpers.config_validation as cv
|
|
from homeassistant.helpers.discovery import async_load_platform
|
|
from homeassistant.helpers.typing import ConfigType
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
DATA_SISYPHUS = "sisyphus"
|
|
DOMAIN = "sisyphus"
|
|
|
|
AUTODETECT_SCHEMA = vol.Schema({})
|
|
|
|
TABLE_SCHEMA = vol.Schema(
|
|
{vol.Required(CONF_NAME): cv.string, vol.Required(CONF_HOST): cv.string}
|
|
)
|
|
|
|
TABLES_SCHEMA = vol.Schema([TABLE_SCHEMA])
|
|
|
|
CONFIG_SCHEMA = vol.Schema(
|
|
{DOMAIN: vol.Any(AUTODETECT_SCHEMA, TABLES_SCHEMA)}, extra=vol.ALLOW_EXTRA
|
|
)
|
|
|
|
# Silence these loggers by default. Their INFO level is super chatty and we
|
|
# only need error-level logging from the integration itself by default.
|
|
logging.getLogger("socketio.client").setLevel(logging.CRITICAL + 1)
|
|
logging.getLogger("engineio.client").setLevel(logging.CRITICAL + 1)
|
|
|
|
|
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|
"""Set up the sisyphus component."""
|
|
|
|
tables = hass.data.setdefault(DATA_SISYPHUS, {})
|
|
table_configs = config[DOMAIN]
|
|
session = async_get_clientsession(hass)
|
|
|
|
async def add_table(host, name=None):
|
|
"""Add platforms for a single table with the given hostname."""
|
|
tables[host] = TableHolder(hass, session, host, name)
|
|
|
|
hass.async_create_task(
|
|
async_load_platform(hass, Platform.LIGHT, DOMAIN, {CONF_HOST: host}, config)
|
|
)
|
|
hass.async_create_task(
|
|
async_load_platform(
|
|
hass, Platform.MEDIA_PLAYER, DOMAIN, {CONF_HOST: host}, config
|
|
)
|
|
)
|
|
|
|
if isinstance(table_configs, dict): # AUTODETECT_SCHEMA
|
|
for ip_address in await Table.find_table_ips(session):
|
|
await add_table(ip_address)
|
|
else: # TABLES_SCHEMA
|
|
for conf in table_configs:
|
|
await add_table(conf[CONF_HOST], conf[CONF_NAME])
|
|
|
|
async def close_tables(*args):
|
|
"""Close all table objects."""
|
|
tasks = [table.close() for table in tables.values()]
|
|
if tasks:
|
|
await asyncio.wait(tasks)
|
|
|
|
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, close_tables)
|
|
|
|
return True
|
|
|
|
|
|
class TableHolder:
|
|
"""Holds table objects and makes them available to platforms."""
|
|
|
|
def __init__(self, hass, session, host, name):
|
|
"""Initialize the table holder."""
|
|
self._hass = hass
|
|
self._session = session
|
|
self._host = host
|
|
self._name = name
|
|
self._table = None
|
|
self._table_task = None
|
|
|
|
@property
|
|
def available(self):
|
|
"""Return true if the table is responding to heartbeats."""
|
|
if self._table_task and self._table_task.done():
|
|
return self._table_task.result().is_connected
|
|
return False
|
|
|
|
@property
|
|
def name(self):
|
|
"""Return the name of the table."""
|
|
return self._name
|
|
|
|
async def get_table(self):
|
|
"""Return the Table held by this holder, connecting to it if needed."""
|
|
if self._table:
|
|
return self._table
|
|
|
|
if not self._table_task:
|
|
self._table_task = self._hass.async_create_task(self._connect_table())
|
|
|
|
return await self._table_task
|
|
|
|
async def _connect_table(self):
|
|
try:
|
|
self._table = await Table.connect(self._host, self._session)
|
|
if self._name is None:
|
|
self._name = self._table.name
|
|
_LOGGER.debug("Connected to %s at %s", self._name, self._host)
|
|
return self._table
|
|
finally:
|
|
self._table_task = None
|
|
|
|
async def close(self):
|
|
"""Close the table held by this holder, if any."""
|
|
if self._table:
|
|
await self._table.close()
|
|
self._table = None
|
|
self._table_task = None
|