zha: Clean up binary_sensor listener registration/state updates (#14197)

- Instead of registering listeners in the entity __init__, do it in
   async_added_to_hass to avoid errors updating an entity which isn't fully
   set up yet
 - Change from schedule_update_ha_state to async_schedule_update_ha_state
This commit is contained in:
Russell Cloran 2018-05-01 05:55:25 -07:00 committed by Paulus Schoutsen
parent a4e0c9c251
commit 9d4d1c8233
3 changed files with 21 additions and 16 deletions

View file

@ -164,7 +164,6 @@ class Switch(zha.Entity, BinarySensorDevice):
"""Handle attribute updates on this cluster."""
if attrid == 0:
self._entity.set_state(value)
self._entity.schedule_update_ha_state()
def zdo_command(self, *args, **kwargs):
"""Handle ZDO commands on this cluster."""
@ -202,6 +201,7 @@ class Switch(zha.Entity, BinarySensorDevice):
def __init__(self, **kwargs):
"""Initialize Switch."""
super().__init__(**kwargs)
self._state = True
self._level = 255
from zigpy.zcl.clusters import general
@ -209,7 +209,6 @@ class Switch(zha.Entity, BinarySensorDevice):
general.OnOff.cluster_id: self.OnOffListener(self),
general.LevelControl.cluster_id: self.LevelListener(self),
}
super().__init__(**kwargs)
@property
def is_on(self) -> bool:
@ -227,20 +226,20 @@ class Switch(zha.Entity, BinarySensorDevice):
self._level = 0
self._level = min(255, max(0, self._level + change))
self._state = bool(self._level)
self.schedule_update_ha_state()
self.async_schedule_update_ha_state()
def set_level(self, level):
"""Set the level, setting state if appropriate."""
self._level = level
self._state = bool(self._level)
self.schedule_update_ha_state()
self.async_schedule_update_ha_state()
def set_state(self, state):
"""Set the state."""
self._state = state
if self._level == 0:
self._level = 255
self.schedule_update_ha_state()
self.async_schedule_update_ha_state()
async def async_update(self):
"""Retrieve latest state."""

View file

@ -71,7 +71,7 @@ class Sensor(zha.Entity):
_LOGGER.debug("Attribute updated: %s %s %s", self, attribute, value)
if attribute == self.value_attribute:
self._state = value
self.schedule_update_ha_state()
self.async_schedule_update_ha_state()
class TemperatureSensor(Sensor):

View file

@ -288,11 +288,6 @@ class Entity(entity.Entity):
"""A base class for ZHA entities."""
_domain = None # Must be overridden by subclasses
# Normally the entity itself is the listener. Base classes may set this to
# a dict of cluster ID -> listener to receive messages for specific
# clusters separately
_in_listeners = {}
_out_listeners = {}
def __init__(self, endpoint, in_clusters, out_clusters, manufacturer,
model, application_listener, unique_id, **kwargs):
@ -321,19 +316,30 @@ class Entity(entity.Entity):
kwargs.get('entity_suffix', ''),
)
for cluster_id, cluster in in_clusters.items():
cluster.add_listener(self._in_listeners.get(cluster_id, self))
for cluster_id, cluster in out_clusters.items():
cluster.add_listener(self._out_listeners.get(cluster_id, self))
self._endpoint = endpoint
self._in_clusters = in_clusters
self._out_clusters = out_clusters
self._state = ha_const.STATE_UNKNOWN
self._unique_id = unique_id
# Normally the entity itself is the listener. Sub-classes may set this
# to a dict of cluster ID -> listener to receive messages for specific
# clusters separately
self._in_listeners = {}
self._out_listeners = {}
application_listener.register_entity(ieee, self)
async def async_added_to_hass(self):
"""Callback once the entity is added to hass.
It is now safe to update the entity state
"""
for cluster_id, cluster in self._in_clusters.items():
cluster.add_listener(self._in_listeners.get(cluster_id, self))
for cluster_id, cluster in self._out_clusters.items():
cluster.add_listener(self._out_listeners.get(cluster_id, self))
@property
def unique_id(self) -> str:
"""Return a unique ID."""