Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get status once per device instead of per platform #51

Merged
merged 2 commits into from
Sep 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions custom_components/localtuya/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,17 @@
"""
import asyncio
import logging
from datetime import timedelta, datetime

from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.const import (
CONF_DEVICE_ID,
CONF_PLATFORM,
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 .config_flow import config_schema
Expand All @@ -63,6 +67,9 @@
_LOGGER = logging.getLogger(__name__)

UNSUB_LISTENER = "unsub_listener"
UNSUB_TRACK = "unsub_track"

POLL_INTERVAL = 30

CONFIG_SCHEMA = config_schema()

Expand All @@ -85,17 +92,43 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
"""Set up LocalTuya integration from a config entry."""
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] = {
UNSUB_LISTENER: unsub_listener,
TUYA_DEVICE: TuyaDevice(entry.data),
UNSUB_TRACK: unsub_track,
TUYA_DEVICE: device,
}

for entity in entry.data[CONF_ENTITIES]:
platform = entity[CONF_PLATFORM]
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, platform)
async def setup_entities():
await asyncio.gather(
*[
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


Expand All @@ -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_TRACK]()
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)

Expand Down
2 changes: 1 addition & 1 deletion custom_components/localtuya/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
44 changes: 31 additions & 13 deletions custom_components/localtuya/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from threading import Lock

from homeassistant.helpers.entity import Entity
from homeassistant.helpers.dispatcher import async_dispatcher_connect

from homeassistant.const import (
CONF_DEVICE_ID,
Expand Down Expand Up @@ -132,9 +133,27 @@ def __init__(self, device, config_entry, dps_id, **kwargs):
self._device = device
self._config_entry = config_entry
self._config = get_entity_config(config_entry, dps_id)
self._available = False
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
def device_info(self):
Expand All @@ -155,6 +174,11 @@ def name(self):
"""Get name of Tuya entity."""
return self._config[CONF_FRIENDLY_NAME]

@property
def should_poll(self):
"""Return if platform should poll for updates."""
return False

@property
def unique_id(self):
"""Return unique device identifier."""
Expand All @@ -163,28 +187,22 @@ def unique_id(self):
@property
def available(self):
"""Return if device is available or not."""
return self._available
return bool(self._status)

def dps(self, dps_index):
"""Return cached value for DPS index."""
if "dps" not in self._status:
return None

value = self._status["dps"].get(str(dps_index))
if value is None:
_LOGGER.warning(
"Entity %s is requesting unknown DPS index %s",
self.entity_id,
dps_index,
)
return value

def update(self):
"""Update state of Tuya entity."""
try:
self._status = self._device.status()
self.status_updated()
except Exception:
self._available = False
else:
self._available = True
return value

def status_updated(self):
"""Device status was updated.
Expand Down
7 changes: 1 addition & 6 deletions custom_components/localtuya/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -78,11 +78,6 @@ def __init__(
)
)

@property
def available(self):
"""Return if device is available or not."""
return self._available

@property
def supported_features(self):
"""Flag supported features."""
Expand Down
2 changes: 1 addition & 1 deletion custom_components/localtuya/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion custom_components/localtuya/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion custom_components/localtuya/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion custom_components/localtuya/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down