Fix tellduslive responsiveness (#20603)

* use async_call_later for update

* no need to timeout

* fixes

* move init tasks to hass.loop

* version bump of tellduslive

* fixes for @MartinHjelmare

* fixes task cancel

* don't return from new client
This commit is contained in:
Fredrik Erlandsson 2019-02-06 00:20:23 +01:00 committed by Paulus Schoutsen
parent ca17d4395a
commit c76a61ad16
2 changed files with 36 additions and 31 deletions

View file

@ -5,27 +5,26 @@ For more details about this component, please refer to the documentation at
https://home-assistant.io/components/tellduslive/
"""
import asyncio
from datetime import timedelta
from functools import partial
import logging
import voluptuous as vol
from homeassistant import config_entries
import homeassistant.helpers.config_validation as cv
from homeassistant.const import CONF_UPDATE_INTERVAL
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.event import async_call_later
from . import config_flow # noqa pylint_disable=unused-import
from .const import (
CONF_HOST, DOMAIN, KEY_HOST, KEY_SCAN_INTERVAL,
KEY_SESSION, MIN_UPDATE_INTERVAL, NOT_SO_PRIVATE_KEY, PUBLIC_KEY,
SCAN_INTERVAL, SIGNAL_UPDATE_ENTITY, TELLDUS_DISCOVERY_NEW)
CONF_HOST, DOMAIN, KEY_HOST, KEY_SCAN_INTERVAL, KEY_SESSION,
MIN_UPDATE_INTERVAL, NOT_SO_PRIVATE_KEY, PUBLIC_KEY, SCAN_INTERVAL,
SIGNAL_UPDATE_ENTITY, TELLDUS_DISCOVERY_NEW)
APPLICATION_NAME = 'Home Assistant'
REQUIREMENTS = ['tellduslive==0.10.8']
REQUIREMENTS = ['tellduslive==0.10.10']
_LOGGER = logging.getLogger(__name__)
@ -45,6 +44,7 @@ CONFIG_SCHEMA = vol.Schema(
DATA_CONFIG_ENTRY_LOCK = 'tellduslive_config_entry_lock'
CONFIG_ENTRY_IS_SETUP = 'telldus_config_entry_is_setup'
NEW_CLIENT_TASK = 'telldus_new_client_task'
INTERVAL_TRACKER = '{}_INTERVAL'.format(DOMAIN)
@ -71,33 +71,30 @@ async def async_setup_entry(hass, entry):
hass.data[DATA_CONFIG_ENTRY_LOCK] = asyncio.Lock()
hass.data[CONFIG_ENTRY_IS_SETUP] = set()
client = TelldusLiveClient(hass, entry, session)
hass.data[DOMAIN] = client
await async_add_hubs(hass, client, entry.entry_id)
hass.async_create_task(client.update())
interval = timedelta(seconds=entry.data[KEY_SCAN_INTERVAL])
_LOGGER.debug('Update interval %s', interval)
hass.data[INTERVAL_TRACKER] = async_track_time_interval(
hass, client.update, interval)
hass.data[NEW_CLIENT_TASK] = hass.loop.create_task(
async_new_client(hass, session, entry))
return True
async def async_add_hubs(hass, client, entry_id):
async def async_new_client(hass, session, entry):
"""Add the hubs associated with the current client to device_registry."""
interval = entry.data[KEY_SCAN_INTERVAL]
_LOGGER.debug('Update interval %s seconds.', interval)
client = TelldusLiveClient(hass, entry, session, interval)
hass.data[DOMAIN] = client
dev_reg = await hass.helpers.device_registry.async_get_registry()
for hub in await client.async_get_hubs():
_LOGGER.debug("Connected hub %s", hub['name'])
dev_reg.async_get_or_create(
config_entry_id=entry_id,
config_entry_id=entry.entry_id,
identifiers={(DOMAIN, hub['id'])},
manufacturer='Telldus',
name=hub['name'],
model=hub['type'],
sw_version=hub['version'],
)
await client.update()
async def async_setup(hass, config):
@ -118,6 +115,8 @@ async def async_setup(hass, config):
async def async_unload_entry(hass, config_entry):
"""Unload a config entry."""
if not hass.data[NEW_CLIENT_TASK].done():
hass.data[NEW_CLIENT_TASK].cancel()
interval_tracker = hass.data.pop(INTERVAL_TRACKER)
interval_tracker()
await asyncio.wait([
@ -132,7 +131,7 @@ async def async_unload_entry(hass, config_entry):
class TelldusLiveClient:
"""Get the latest data and update the states."""
def __init__(self, hass, config_entry, session):
def __init__(self, hass, config_entry, session, interval):
"""Initialize the Tellus data object."""
self._known_devices = set()
self._device_infos = {}
@ -140,6 +139,7 @@ class TelldusLiveClient:
self._hass = hass
self._config_entry = config_entry
self._client = session
self._interval = interval
async def async_get_hubs(self):
"""Return hubs registered for the user."""
@ -195,16 +195,21 @@ class TelldusLiveClient:
async def update(self, *args):
"""Periodically poll the servers for current state."""
if not await self._hass.async_add_executor_job(self._client.update):
_LOGGER.warning('Failed request')
dev_ids = {dev.device_id for dev in self._client.devices}
new_devices = dev_ids - self._known_devices
# just await each discover as `gather` use up all HTTPAdapter pools
for d_id in new_devices:
await self._discover(d_id)
self._known_devices |= new_devices
async_dispatcher_send(self._hass, SIGNAL_UPDATE_ENTITY)
try:
if not await self._hass.async_add_executor_job(
self._client.update):
_LOGGER.warning('Failed request')
return
dev_ids = {dev.device_id for dev in self._client.devices}
new_devices = dev_ids - self._known_devices
# just await each discover as `gather` use up all HTTPAdapter pools
for d_id in new_devices:
await self._discover(d_id)
self._known_devices |= new_devices
async_dispatcher_send(self._hass, SIGNAL_UPDATE_ENTITY)
finally:
self._hass.data[INTERVAL_TRACKER] = async_call_later(
self._hass, self._interval, self.update)
def device(self, device_id):
"""Return device representation."""

View file

@ -1628,7 +1628,7 @@ tellcore-net==0.4
tellcore-py==1.1.2
# homeassistant.components.tellduslive
tellduslive==0.10.8
tellduslive==0.10.10
# homeassistant.components.media_player.lg_soundbar
temescal==0.1