Get status once per device instead of per platform
This commit is contained in:
committed by
rospogrigio
parent
b7173f3033
commit
caaf884a7a
@@ -48,13 +48,17 @@ localtuya:
|
|||||||
"""
|
"""
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
from datetime import timedelta, datetime
|
||||||
|
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
|
CONF_DEVICE_ID,
|
||||||
CONF_PLATFORM,
|
CONF_PLATFORM,
|
||||||
CONF_ENTITIES,
|
CONF_ENTITIES,
|
||||||
)
|
)
|
||||||
|
from homeassistant.helpers.event import async_track_time_interval
|
||||||
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||||
|
|
||||||
from .const import DOMAIN, TUYA_DEVICE
|
from .const import DOMAIN, TUYA_DEVICE
|
||||||
from .config_flow import config_schema
|
from .config_flow import config_schema
|
||||||
@@ -63,6 +67,9 @@ from .common import TuyaDevice
|
|||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
UNSUB_LISTENER = "unsub_listener"
|
UNSUB_LISTENER = "unsub_listener"
|
||||||
|
UNSUB_TRACK = "unsub_track"
|
||||||
|
|
||||||
|
POLL_INTERVAL = 30
|
||||||
|
|
||||||
CONFIG_SCHEMA = config_schema()
|
CONFIG_SCHEMA = config_schema()
|
||||||
|
|
||||||
@@ -85,17 +92,43 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
"""Set up LocalTuya integration from a config entry."""
|
"""Set up LocalTuya integration from a config entry."""
|
||||||
unsub_listener = entry.add_update_listener(update_listener)
|
unsub_listener = entry.add_update_listener(update_listener)
|
||||||
|
|
||||||
|
device = TuyaDevice(entry.data)
|
||||||
|
|
||||||
|
def update_state(now):
|
||||||
|
"""Read device status and update platforms."""
|
||||||
|
status = None
|
||||||
|
try:
|
||||||
|
status = device.status()
|
||||||
|
except Exception:
|
||||||
|
_LOGGER.exception("update failed")
|
||||||
|
|
||||||
|
signal = f"localtuya_{entry.data[CONF_DEVICE_ID]}"
|
||||||
|
async_dispatcher_send(hass, signal, status)
|
||||||
|
|
||||||
|
unsub_track = async_track_time_interval(
|
||||||
|
hass, update_state, timedelta(seconds=POLL_INTERVAL)
|
||||||
|
)
|
||||||
|
|
||||||
hass.data[DOMAIN][entry.entry_id] = {
|
hass.data[DOMAIN][entry.entry_id] = {
|
||||||
UNSUB_LISTENER: unsub_listener,
|
UNSUB_LISTENER: unsub_listener,
|
||||||
TUYA_DEVICE: TuyaDevice(entry.data),
|
UNSUB_TRACK: unsub_track,
|
||||||
|
TUYA_DEVICE: device,
|
||||||
}
|
}
|
||||||
|
|
||||||
for entity in entry.data[CONF_ENTITIES]:
|
async def setup_entities():
|
||||||
platform = entity[CONF_PLATFORM]
|
await asyncio.gather(
|
||||||
hass.async_create_task(
|
*[
|
||||||
hass.config_entries.async_forward_entry_setup(entry, platform)
|
hass.config_entries.async_forward_entry_setup(
|
||||||
|
entry, entity[CONF_PLATFORM]
|
||||||
|
)
|
||||||
|
for entity in entry.data[CONF_ENTITIES]
|
||||||
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
update_state(datetime.now())
|
||||||
|
|
||||||
|
hass.async_create_task(setup_entities())
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@@ -113,6 +146,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
)
|
)
|
||||||
|
|
||||||
hass.data[DOMAIN][entry.entry_id][UNSUB_LISTENER]()
|
hass.data[DOMAIN][entry.entry_id][UNSUB_LISTENER]()
|
||||||
|
hass.data[DOMAIN][entry.entry_id][UNSUB_TRACK]()
|
||||||
if unload_ok:
|
if unload_ok:
|
||||||
hass.data[DOMAIN].pop(entry.entry_id)
|
hass.data[DOMAIN].pop(entry.entry_id)
|
||||||
|
|
||||||
|
@@ -45,7 +45,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
async_add_entities(sensors, True)
|
async_add_entities(sensors)
|
||||||
|
|
||||||
|
|
||||||
class LocaltuyaBinarySensor(LocalTuyaEntity, BinarySensorEntity):
|
class LocaltuyaBinarySensor(LocalTuyaEntity, BinarySensorEntity):
|
||||||
|
@@ -4,6 +4,7 @@ from time import time, sleep
|
|||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_DEVICE_ID,
|
CONF_DEVICE_ID,
|
||||||
@@ -132,9 +133,27 @@ class LocalTuyaEntity(Entity):
|
|||||||
self._device = device
|
self._device = device
|
||||||
self._config_entry = config_entry
|
self._config_entry = config_entry
|
||||||
self._config = get_entity_config(config_entry, dps_id)
|
self._config = get_entity_config(config_entry, dps_id)
|
||||||
self._available = False
|
|
||||||
self._dps_id = dps_id
|
self._dps_id = dps_id
|
||||||
self._status = None
|
self._status = {}
|
||||||
|
|
||||||
|
async def async_added_to_hass(self):
|
||||||
|
"""Subscribe localtuya events."""
|
||||||
|
await super().async_added_to_hass()
|
||||||
|
|
||||||
|
def _update_handler(status):
|
||||||
|
"""Update entity state when status was updated."""
|
||||||
|
if status is not None:
|
||||||
|
self._status = status
|
||||||
|
self.status_updated()
|
||||||
|
else:
|
||||||
|
self._status = {}
|
||||||
|
|
||||||
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
|
signal = f"localtuya_{self._config_entry.data[CONF_DEVICE_ID]}"
|
||||||
|
self.async_on_remove(
|
||||||
|
async_dispatcher_connect(self.hass, signal, _update_handler)
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self):
|
def device_info(self):
|
||||||
@@ -155,6 +174,11 @@ class LocalTuyaEntity(Entity):
|
|||||||
"""Get name of Tuya entity."""
|
"""Get name of Tuya entity."""
|
||||||
return self._config[CONF_FRIENDLY_NAME]
|
return self._config[CONF_FRIENDLY_NAME]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def should_poll(self):
|
||||||
|
"""Return if platform should poll for updates."""
|
||||||
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self):
|
def unique_id(self):
|
||||||
"""Return unique device identifier."""
|
"""Return unique device identifier."""
|
||||||
@@ -163,10 +187,13 @@ class LocalTuyaEntity(Entity):
|
|||||||
@property
|
@property
|
||||||
def available(self):
|
def available(self):
|
||||||
"""Return if device is available or not."""
|
"""Return if device is available or not."""
|
||||||
return self._available
|
return bool(self._status)
|
||||||
|
|
||||||
def dps(self, dps_index):
|
def dps(self, dps_index):
|
||||||
"""Return cached value for DPS index."""
|
"""Return cached value for DPS index."""
|
||||||
|
if "dps" not in self._status:
|
||||||
|
return None
|
||||||
|
|
||||||
value = self._status["dps"].get(str(dps_index))
|
value = self._status["dps"].get(str(dps_index))
|
||||||
if value is None:
|
if value is None:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
@@ -174,17 +201,8 @@ class LocalTuyaEntity(Entity):
|
|||||||
self.entity_id,
|
self.entity_id,
|
||||||
dps_index,
|
dps_index,
|
||||||
)
|
)
|
||||||
return value
|
|
||||||
|
|
||||||
def update(self):
|
return value
|
||||||
"""Update state of Tuya entity."""
|
|
||||||
try:
|
|
||||||
self._status = self._device.status()
|
|
||||||
self.status_updated()
|
|
||||||
except Exception:
|
|
||||||
self._available = False
|
|
||||||
else:
|
|
||||||
self._available = True
|
|
||||||
|
|
||||||
def status_updated(self):
|
def status_updated(self):
|
||||||
"""Device status was updated.
|
"""Device status was updated.
|
||||||
|
@@ -55,7 +55,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
async_add_entities(covers, True)
|
async_add_entities(covers)
|
||||||
|
|
||||||
|
|
||||||
class LocaltuyaCover(LocalTuyaEntity, CoverEntity):
|
class LocaltuyaCover(LocalTuyaEntity, CoverEntity):
|
||||||
@@ -78,11 +78,6 @@ class LocaltuyaCover(LocalTuyaEntity, CoverEntity):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
def available(self):
|
|
||||||
"""Return if device is available or not."""
|
|
||||||
return self._available
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supported_features(self):
|
def supported_features(self):
|
||||||
"""Flag supported features."""
|
"""Flag supported features."""
|
||||||
|
@@ -42,7 +42,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
async_add_entities(fans, True)
|
async_add_entities(fans)
|
||||||
|
|
||||||
|
|
||||||
class LocaltuyaFan(LocalTuyaEntity, FanEntity):
|
class LocaltuyaFan(LocalTuyaEntity, FanEntity):
|
||||||
|
@@ -50,7 +50,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
async_add_entities(lights, True)
|
async_add_entities(lights)
|
||||||
|
|
||||||
|
|
||||||
class LocaltuyaLight(LocalTuyaEntity, LightEntity):
|
class LocaltuyaLight(LocalTuyaEntity, LightEntity):
|
||||||
|
@@ -49,7 +49,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
async_add_entities(sensors, True)
|
async_add_entities(sensors)
|
||||||
|
|
||||||
|
|
||||||
class LocaltuyaSensor(LocalTuyaEntity):
|
class LocaltuyaSensor(LocalTuyaEntity):
|
||||||
|
@@ -49,7 +49,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
async_add_entities(switches, True)
|
async_add_entities(switches)
|
||||||
|
|
||||||
|
|
||||||
class LocaltuyaSwitch(LocalTuyaEntity, SwitchEntity):
|
class LocaltuyaSwitch(LocalTuyaEntity, SwitchEntity):
|
||||||
|
Reference in New Issue
Block a user