Bring the Sisyphus integration to silver quality (#22457)

* Bring the Sisyphus integration to silver quality

Checklist:
- [x] (N/A - push integration) Set an appropriate SCAN_INTERVAL (if a polling integration)
- [x] Raise PlatformNotReady if unable to connect during platform setup
- [x] (N/A - no credentials) Handles expiration of auth credentials. Refresh if possible or print correct error and fail setup. If based on a config entry, should trigger a new config entry flow to re-authorize.
- [x] (N/A - local integration) Handles internet unavailable. Log a warning once when unavailable, log once when reconnected.
- [x] Handles device/service unavailable. Log a warning once when unavailable, log once when reconnected.
- [x] Set available property to False if appropriate
- [x] Entities have unique ID (if available)

* Feedback (fix a couple verbose places)

* Use a task instead of a lock

* Initialize field in constructor

* Revert package upgrade.
This commit is contained in:
Jonathan Keljo 2019-06-06 15:16:27 -07:00 committed by Paulus Schoutsen
parent 32844bb318
commit bf7e09ce59
3 changed files with 107 additions and 15 deletions

View File

@ -35,26 +35,31 @@ CONFIG_SCHEMA = vol.Schema({
async def async_setup(hass, config):
"""Set up the sisyphus component."""
from sisyphus_control import Table
class SocketIONoiseFilter(logging.Filter):
"""Filters out excessively verbose logs from SocketIO."""
def filter(self, record):
if record.msg.contains('waiting for connection'):
return False
return True
logging.getLogger('socketIO-client').addFilter(SocketIONoiseFilter())
tables = hass.data.setdefault(DATA_SISYPHUS, {})
table_configs = config.get(DOMAIN)
session = async_get_clientsession(hass)
async def add_table(host, name=None):
"""Add platforms for a single table with the given hostname."""
table = await Table.connect(host, session)
if name is None:
name = table.name
tables[name] = table
_LOGGER.debug("Connected to %s at %s", name, host)
tables[host] = TableHolder(hass, session, host, name)
hass.async_create_task(async_load_platform(
hass, 'light', DOMAIN, {
CONF_NAME: name,
CONF_HOST: host,
}, config
))
hass.async_create_task(async_load_platform(
hass, 'media_player', DOMAIN, {
CONF_NAME: name,
CONF_HOST: host,
}, config
))
@ -75,3 +80,51 @@ async def async_setup(hass, config):
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 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):
from sisyphus_control import Table
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
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

View File

@ -1,8 +1,11 @@
"""Support for the light on the Sisyphus Kinetic Art Table."""
import logging
import aiohttp
from homeassistant.components.light import SUPPORT_BRIGHTNESS, Light
from homeassistant.const import CONF_NAME
from homeassistant.const import CONF_HOST
from homeassistant.exceptions import PlatformNotReady
from . import DATA_SISYPHUS
@ -11,11 +14,18 @@ _LOGGER = logging.getLogger(__name__)
SUPPORTED_FEATURES = SUPPORT_BRIGHTNESS
def setup_platform(hass, config, add_entities, discovery_info=None):
async def async_setup_platform(hass, config, add_entities,
discovery_info=None):
"""Set up a single Sisyphus table."""
name = discovery_info[CONF_NAME]
host = discovery_info[CONF_HOST]
try:
table_holder = hass.data[DATA_SISYPHUS][host]
table = await table_holder.get_table()
except aiohttp.ClientError:
raise PlatformNotReady()
add_entities(
[SisyphusLight(name, hass.data[DATA_SISYPHUS][name])],
[SisyphusLight(table_holder.name, table)],
update_before_add=True)
@ -32,6 +42,16 @@ class SisyphusLight(Light):
self._table.add_listener(
lambda: self.async_schedule_update_ha_state(False))
@property
def available(self):
"""Return true if the table is responding to heartbeats."""
return self._table.is_connected
@property
def unique_id(self):
"""Return the UUID of the table."""
return self._table.id
@property
def name(self):
"""Return the ame of the table."""

View File

@ -1,13 +1,16 @@
"""Support for track controls on the Sisyphus Kinetic Art Table."""
import logging
import aiohttp
from homeassistant.components.media_player import MediaPlayerDevice
from homeassistant.components.media_player.const import (
SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PLAY, SUPPORT_PREVIOUS_TRACK,
SUPPORT_SHUFFLE_SET, SUPPORT_TURN_OFF, SUPPORT_TURN_ON,
SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET)
from homeassistant.const import (
CONF_HOST, CONF_NAME, STATE_IDLE, STATE_OFF, STATE_PAUSED, STATE_PLAYING)
CONF_HOST, STATE_IDLE, STATE_OFF, STATE_PAUSED, STATE_PLAYING)
from homeassistant.exceptions import PlatformNotReady
from . import DATA_SISYPHUS
@ -27,12 +30,18 @@ SUPPORTED_FEATURES = SUPPORT_VOLUME_MUTE \
# pylint: disable=unused-argument
def setup_platform(hass, config, add_entities, discovery_info=None):
async def async_setup_platform(hass, config, add_entities,
discovery_info=None):
"""Set up a media player entity for a Sisyphus table."""
name = discovery_info[CONF_NAME]
host = discovery_info[CONF_HOST]
try:
table_holder = hass.data[DATA_SISYPHUS][host]
table = await table_holder.get_table()
except aiohttp.ClientError:
raise PlatformNotReady()
add_entities(
[SisyphusPlayer(name, host, hass.data[DATA_SISYPHUS][name])], True)
[SisyphusPlayer(table_holder.name, host, table)], True)
class SisyphusPlayer(MediaPlayerDevice):
@ -49,6 +58,16 @@ class SisyphusPlayer(MediaPlayerDevice):
self._table.add_listener(
lambda: self.async_schedule_update_ha_state(False))
@property
def unique_id(self):
"""Return the UUID of the table."""
return self._table.id
@property
def available(self):
"""Return true if the table is responding to heartbeats."""
return self._table.is_connected
@property
def name(self):
"""Return the name of the table."""