Add mysensors state update delay (#18891)
* Add mysensors state update delay * Schedule state update after delay to avoid updating state multiple times during the same short timespan. * Code review
This commit is contained in:
parent
25408bd483
commit
937688f7a6
4 changed files with 34 additions and 8 deletions
|
@ -14,7 +14,7 @@ async def async_setup_scanner(hass, config, async_see, discovery_info=None):
|
||||||
"""Set up the MySensors device scanner."""
|
"""Set up the MySensors device scanner."""
|
||||||
new_devices = mysensors.setup_mysensors_platform(
|
new_devices = mysensors.setup_mysensors_platform(
|
||||||
hass, DOMAIN, discovery_info, MySensorsDeviceScanner,
|
hass, DOMAIN, discovery_info, MySensorsDeviceScanner,
|
||||||
device_args=(async_see, ))
|
device_args=(hass, async_see))
|
||||||
if not new_devices:
|
if not new_devices:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -37,12 +37,13 @@ async def async_setup_scanner(hass, config, async_see, discovery_info=None):
|
||||||
class MySensorsDeviceScanner(mysensors.device.MySensorsDevice):
|
class MySensorsDeviceScanner(mysensors.device.MySensorsDevice):
|
||||||
"""Represent a MySensors scanner."""
|
"""Represent a MySensors scanner."""
|
||||||
|
|
||||||
def __init__(self, async_see, *args):
|
def __init__(self, hass, async_see, *args):
|
||||||
"""Set up instance."""
|
"""Set up instance."""
|
||||||
super().__init__(*args)
|
super().__init__(*args)
|
||||||
self.async_see = async_see
|
self.async_see = async_see
|
||||||
|
self.hass = hass
|
||||||
|
|
||||||
async def async_update_callback(self):
|
async def _async_update_callback(self):
|
||||||
"""Update the device."""
|
"""Update the device."""
|
||||||
await self.async_update()
|
await self.async_update()
|
||||||
node = self.gateway.sensors[self.node_id]
|
node = self.gateway.sensors[self.node_id]
|
||||||
|
|
|
@ -23,6 +23,7 @@ SCHEMA = 'schema'
|
||||||
CHILD_CALLBACK = 'mysensors_child_callback_{}_{}_{}_{}'
|
CHILD_CALLBACK = 'mysensors_child_callback_{}_{}_{}_{}'
|
||||||
NODE_CALLBACK = 'mysensors_node_callback_{}_{}'
|
NODE_CALLBACK = 'mysensors_node_callback_{}_{}'
|
||||||
TYPE = 'type'
|
TYPE = 'type'
|
||||||
|
UPDATE_DELAY = 0.1
|
||||||
|
|
||||||
# MySensors const schemas
|
# MySensors const schemas
|
||||||
BINARY_SENSOR_SCHEMA = {PLATFORM: 'binary_sensor', TYPE: 'V_TRIPPED'}
|
BINARY_SENSOR_SCHEMA = {PLATFORM: 'binary_sensor', TYPE: 'V_TRIPPED'}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
"""Handle MySensors devices."""
|
"""Handle MySensors devices."""
|
||||||
import logging
|
import logging
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_BATTERY_LEVEL, STATE_OFF, STATE_ON)
|
ATTR_BATTERY_LEVEL, STATE_OFF, STATE_ON)
|
||||||
|
@ -7,7 +8,7 @@ from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
|
||||||
from .const import CHILD_CALLBACK, NODE_CALLBACK
|
from .const import CHILD_CALLBACK, NODE_CALLBACK, UPDATE_DELAY
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -39,6 +40,8 @@ class MySensorsDevice:
|
||||||
child = gateway.sensors[node_id].children[child_id]
|
child = gateway.sensors[node_id].children[child_id]
|
||||||
self.child_type = child.type
|
self.child_type = child.type
|
||||||
self._values = {}
|
self._values = {}
|
||||||
|
self._update_scheduled = False
|
||||||
|
self.hass = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
@ -84,6 +87,29 @@ class MySensorsDevice:
|
||||||
else:
|
else:
|
||||||
self._values[value_type] = value
|
self._values[value_type] = value
|
||||||
|
|
||||||
|
async def _async_update_callback(self):
|
||||||
|
"""Update the device."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def async_update_callback(self):
|
||||||
|
"""Update the device after delay."""
|
||||||
|
if self._update_scheduled:
|
||||||
|
return
|
||||||
|
|
||||||
|
async def update():
|
||||||
|
"""Perform update."""
|
||||||
|
try:
|
||||||
|
await self._async_update_callback()
|
||||||
|
except Exception: # pylint: disable=broad-except
|
||||||
|
_LOGGER.exception("Error updating %s", self.name)
|
||||||
|
finally:
|
||||||
|
self._update_scheduled = False
|
||||||
|
|
||||||
|
self._update_scheduled = True
|
||||||
|
delayed_update = partial(self.hass.async_create_task, update())
|
||||||
|
self.hass.loop.call_later(UPDATE_DELAY, delayed_update)
|
||||||
|
|
||||||
|
|
||||||
class MySensorsEntity(MySensorsDevice, Entity):
|
class MySensorsEntity(MySensorsDevice, Entity):
|
||||||
"""Representation of a MySensors entity."""
|
"""Representation of a MySensors entity."""
|
||||||
|
@ -98,10 +124,9 @@ class MySensorsEntity(MySensorsDevice, Entity):
|
||||||
"""Return true if entity is available."""
|
"""Return true if entity is available."""
|
||||||
return self.value_type in self._values
|
return self.value_type in self._values
|
||||||
|
|
||||||
@callback
|
async def _async_update_callback(self):
|
||||||
def async_update_callback(self):
|
|
||||||
"""Update the entity."""
|
"""Update the entity."""
|
||||||
self.async_schedule_update_ha_state(True)
|
await self.async_update_ha_state(True)
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
async def async_added_to_hass(self):
|
||||||
"""Register update callback."""
|
"""Register update callback."""
|
||||||
|
|
|
@ -99,7 +99,6 @@ def _handle_child_update(hass, hass_config, msg):
|
||||||
for signal in set(signals):
|
for signal in set(signals):
|
||||||
# Only one signal per device is needed.
|
# Only one signal per device is needed.
|
||||||
# A device can have multiple platforms, ie multiple schemas.
|
# A device can have multiple platforms, ie multiple schemas.
|
||||||
# FOR LATER: Add timer to not signal if another update comes in.
|
|
||||||
async_dispatcher_send(hass, signal)
|
async_dispatcher_send(hass, signal)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue