Fix so that entities are properly unloaded with config entry (#16281)
This commit is contained in:
parent
88f72a654a
commit
645c3a67d8
8 changed files with 62 additions and 20 deletions
|
@ -54,6 +54,11 @@ class DeconzBinarySensor(BinarySensorDevice):
|
|||
self._sensor.register_async_callback(self.async_update_callback)
|
||||
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self._sensor.deconz_id
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect sensor object when removed."""
|
||||
self._sensor.remove_callback(self.async_update_callback)
|
||||
self._sensor = None
|
||||
|
||||
@callback
|
||||
def async_update_callback(self, reason):
|
||||
"""Update the sensor's state.
|
||||
|
|
|
@ -24,7 +24,7 @@ from .const import (
|
|||
CONF_ALLOW_CLIP_SENSOR, CONFIG_FILE, DATA_DECONZ_EVENT,
|
||||
DATA_DECONZ_ID, DATA_DECONZ_UNSUB, DOMAIN, _LOGGER)
|
||||
|
||||
REQUIREMENTS = ['pydeconz==44']
|
||||
REQUIREMENTS = ['pydeconz==45']
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: vol.Schema({
|
||||
|
@ -179,15 +179,22 @@ async def async_unload_entry(hass, config_entry):
|
|||
deconz = hass.data.pop(DOMAIN)
|
||||
hass.services.async_remove(DOMAIN, SERVICE_DECONZ)
|
||||
deconz.close()
|
||||
for component in ['binary_sensor', 'light', 'scene', 'sensor']:
|
||||
|
||||
for component in ['binary_sensor', 'light', 'scene', 'sensor', 'switch']:
|
||||
await hass.config_entries.async_forward_entry_unload(
|
||||
config_entry, component)
|
||||
|
||||
dispatchers = hass.data[DATA_DECONZ_UNSUB]
|
||||
for unsub_dispatcher in dispatchers:
|
||||
unsub_dispatcher()
|
||||
hass.data[DATA_DECONZ_UNSUB] = []
|
||||
hass.data[DATA_DECONZ_EVENT] = []
|
||||
|
||||
for event in hass.data[DATA_DECONZ_EVENT]:
|
||||
event.async_will_remove_from_hass()
|
||||
hass.data[DATA_DECONZ_EVENT].remove(event)
|
||||
|
||||
hass.data[DATA_DECONZ_ID] = []
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
@ -206,6 +213,12 @@ class DeconzEvent:
|
|||
self._event = 'deconz_{}'.format(CONF_EVENT)
|
||||
self._id = slugify(self._device.name)
|
||||
|
||||
@callback
|
||||
def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect event object when removed."""
|
||||
self._device.remove_callback(self.async_update_callback)
|
||||
self._device = None
|
||||
|
||||
@callback
|
||||
def async_update_callback(self, reason):
|
||||
"""Fire the event if reason is that state is updated."""
|
||||
|
|
|
@ -82,6 +82,11 @@ class DeconzLight(Light):
|
|||
self._light.register_async_callback(self.async_update_callback)
|
||||
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self._light.deconz_id
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect light object when removed."""
|
||||
self._light.remove_callback(self.async_update_callback)
|
||||
self._light = None
|
||||
|
||||
@callback
|
||||
def async_update_callback(self, reason):
|
||||
"""Update the light's state."""
|
||||
|
|
|
@ -38,6 +38,10 @@ class DeconzScene(Scene):
|
|||
"""Subscribe to sensors events."""
|
||||
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self._scene.deconz_id
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect scene object when removed."""
|
||||
self._scene = None
|
||||
|
||||
async def async_activate(self):
|
||||
"""Activate the scene."""
|
||||
await self._scene.async_set_state({})
|
||||
|
|
|
@ -64,6 +64,11 @@ class DeconzSensor(Entity):
|
|||
self._sensor.register_async_callback(self.async_update_callback)
|
||||
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self._sensor.deconz_id
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect sensor object when removed."""
|
||||
self._sensor.remove_callback(self.async_update_callback)
|
||||
self._sensor = None
|
||||
|
||||
@callback
|
||||
def async_update_callback(self, reason):
|
||||
"""Update the sensor's state.
|
||||
|
@ -155,16 +160,21 @@ class DeconzSensor(Entity):
|
|||
class DeconzBattery(Entity):
|
||||
"""Battery class for when a device is only represented as an event."""
|
||||
|
||||
def __init__(self, device):
|
||||
def __init__(self, sensor):
|
||||
"""Register dispatcher callback for update of battery state."""
|
||||
self._device = device
|
||||
self._name = '{} {}'.format(self._device.name, 'Battery Level')
|
||||
self._sensor = sensor
|
||||
self._name = '{} {}'.format(self._sensor.name, 'Battery Level')
|
||||
self._unit_of_measurement = "%"
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Subscribe to sensors events."""
|
||||
self._device.register_async_callback(self.async_update_callback)
|
||||
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self._device.deconz_id
|
||||
self._sensor.register_async_callback(self.async_update_callback)
|
||||
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self._sensor.deconz_id
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect sensor object when removed."""
|
||||
self._sensor.remove_callback(self.async_update_callback)
|
||||
self._sensor = None
|
||||
|
||||
@callback
|
||||
def async_update_callback(self, reason):
|
||||
|
@ -175,7 +185,7 @@ class DeconzBattery(Entity):
|
|||
@property
|
||||
def state(self):
|
||||
"""Return the state of the battery."""
|
||||
return self._device.battery
|
||||
return self._sensor.battery
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -185,7 +195,7 @@ class DeconzBattery(Entity):
|
|||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique identifier for the device."""
|
||||
return self._device.uniqueid
|
||||
return self._sensor.uniqueid
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
|
@ -206,22 +216,22 @@ class DeconzBattery(Entity):
|
|||
def device_state_attributes(self):
|
||||
"""Return the state attributes of the battery."""
|
||||
attr = {
|
||||
ATTR_EVENT_ID: slugify(self._device.name),
|
||||
ATTR_EVENT_ID: slugify(self._sensor.name),
|
||||
}
|
||||
return attr
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return a device description for device registry."""
|
||||
if (self._device.uniqueid is None or
|
||||
self._device.uniqueid.count(':') != 7):
|
||||
if (self._sensor.uniqueid is None or
|
||||
self._sensor.uniqueid.count(':') != 7):
|
||||
return None
|
||||
serial = self._device.uniqueid.split('-', 1)[0]
|
||||
serial = self._sensor.uniqueid.split('-', 1)[0]
|
||||
return {
|
||||
'connections': {(CONNECTION_ZIGBEE, serial)},
|
||||
'identifiers': {(DECONZ_DOMAIN, serial)},
|
||||
'manufacturer': self._device.manufacturer,
|
||||
'model': self._device.modelid,
|
||||
'name': self._device.name,
|
||||
'sw_version': self._device.swversion,
|
||||
'manufacturer': self._sensor.manufacturer,
|
||||
'model': self._sensor.modelid,
|
||||
'name': self._sensor.name,
|
||||
'sw_version': self._sensor.swversion,
|
||||
}
|
||||
|
|
|
@ -55,6 +55,11 @@ class DeconzSwitch(SwitchDevice):
|
|||
self._switch.register_async_callback(self.async_update_callback)
|
||||
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self._switch.deconz_id
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect switch object when removed."""
|
||||
self._switch.remove_callback(self.async_update_callback)
|
||||
self._switch = None
|
||||
|
||||
@callback
|
||||
def async_update_callback(self, reason):
|
||||
"""Update the switch's state."""
|
||||
|
|
|
@ -820,7 +820,7 @@ pycsspeechtts==1.0.2
|
|||
pydaikin==0.4
|
||||
|
||||
# homeassistant.components.deconz
|
||||
pydeconz==44
|
||||
pydeconz==45
|
||||
|
||||
# homeassistant.components.zwave
|
||||
pydispatcher==2.0.5
|
||||
|
|
|
@ -139,7 +139,7 @@ py-canary==0.5.0
|
|||
pyblackbird==0.5
|
||||
|
||||
# homeassistant.components.deconz
|
||||
pydeconz==44
|
||||
pydeconz==45
|
||||
|
||||
# homeassistant.components.zwave
|
||||
pydispatcher==2.0.5
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue