mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 13:47:35 +00:00
deCONZ - reflect hub status on entities (#18106)
* Support for controlling entity available attribute based on gateways availability * Fix string not being in imperative mood
This commit is contained in:
parent
3d4ff74761
commit
dcdae325ea
@ -6,8 +6,8 @@ https://home-assistant.io/components/binary_sensor.deconz/
|
||||
"""
|
||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||
from homeassistant.components.deconz.const import (
|
||||
ATTR_DARK, ATTR_ON, CONF_ALLOW_CLIP_SENSOR, DOMAIN as DATA_DECONZ,
|
||||
DECONZ_DOMAIN)
|
||||
ATTR_DARK, ATTR_ON, CONF_ALLOW_CLIP_SENSOR, DECONZ_REACHABLE,
|
||||
DOMAIN as DECONZ_DOMAIN)
|
||||
from homeassistant.const import ATTR_BATTERY_LEVEL
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.device_registry import CONNECTION_ZIGBEE
|
||||
@ -24,6 +24,8 @@ async def async_setup_platform(hass, config, async_add_entities,
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up the deCONZ binary sensor."""
|
||||
gateway = hass.data[DECONZ_DOMAIN]
|
||||
|
||||
@callback
|
||||
def async_add_sensor(sensors):
|
||||
"""Add binary sensor from deCONZ."""
|
||||
@ -33,30 +35,35 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
for sensor in sensors:
|
||||
if sensor.type in DECONZ_BINARY_SENSOR and \
|
||||
not (not allow_clip_sensor and sensor.type.startswith('CLIP')):
|
||||
entities.append(DeconzBinarySensor(sensor))
|
||||
entities.append(DeconzBinarySensor(sensor, gateway))
|
||||
async_add_entities(entities, True)
|
||||
|
||||
hass.data[DATA_DECONZ].listeners.append(
|
||||
gateway.listeners.append(
|
||||
async_dispatcher_connect(hass, 'deconz_new_sensor', async_add_sensor))
|
||||
|
||||
async_add_sensor(hass.data[DATA_DECONZ].api.sensors.values())
|
||||
async_add_sensor(gateway.api.sensors.values())
|
||||
|
||||
|
||||
class DeconzBinarySensor(BinarySensorDevice):
|
||||
"""Representation of a binary sensor."""
|
||||
|
||||
def __init__(self, sensor):
|
||||
def __init__(self, sensor, gateway):
|
||||
"""Set up sensor and add update callback to get data from websocket."""
|
||||
self._sensor = sensor
|
||||
self.gateway = gateway
|
||||
self.unsub_dispatcher = None
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Subscribe sensors events."""
|
||||
self._sensor.register_async_callback(self.async_update_callback)
|
||||
self.hass.data[DATA_DECONZ].deconz_ids[self.entity_id] = \
|
||||
self._sensor.deconz_id
|
||||
self.gateway.deconz_ids[self.entity_id] = self._sensor.deconz_id
|
||||
self.unsub_dispatcher = async_dispatcher_connect(
|
||||
self.hass, DECONZ_REACHABLE, self.async_update_callback)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect sensor object when removed."""
|
||||
if self.unsub_dispatcher is not None:
|
||||
self.unsub_dispatcher()
|
||||
self._sensor.remove_callback(self.async_update_callback)
|
||||
self._sensor = None
|
||||
|
||||
@ -101,7 +108,7 @@ class DeconzBinarySensor(BinarySensorDevice):
|
||||
@property
|
||||
def available(self):
|
||||
"""Return True if sensor is available."""
|
||||
return self._sensor.reachable
|
||||
return self.gateway.available and self._sensor.reachable
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
@ -128,7 +135,7 @@ class DeconzBinarySensor(BinarySensorDevice):
|
||||
self._sensor.uniqueid.count(':') != 7):
|
||||
return None
|
||||
serial = self._sensor.uniqueid.split('-', 1)[0]
|
||||
bridgeid = self.hass.data[DATA_DECONZ].api.config.bridgeid
|
||||
bridgeid = self.gateway.api.config.bridgeid
|
||||
return {
|
||||
'connections': {(CONNECTION_ZIGBEE, serial)},
|
||||
'identifiers': {(DECONZ_DOMAIN, serial)},
|
||||
|
@ -5,7 +5,8 @@ For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/cover.deconz/
|
||||
"""
|
||||
from homeassistant.components.deconz.const import (
|
||||
COVER_TYPES, DAMPERS, DOMAIN as DATA_DECONZ, DECONZ_DOMAIN, WINDOW_COVERS)
|
||||
COVER_TYPES, DAMPERS, DECONZ_REACHABLE, DOMAIN as DECONZ_DOMAIN,
|
||||
WINDOW_COVERS)
|
||||
from homeassistant.components.cover import (
|
||||
ATTR_POSITION, CoverDevice, SUPPORT_CLOSE, SUPPORT_OPEN, SUPPORT_STOP,
|
||||
SUPPORT_SET_POSITION)
|
||||
@ -29,6 +30,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
|
||||
Covers are based on same device class as lights in deCONZ.
|
||||
"""
|
||||
gateway = hass.data[DECONZ_DOMAIN]
|
||||
|
||||
@callback
|
||||
def async_add_cover(lights):
|
||||
"""Add cover from deCONZ."""
|
||||
@ -36,23 +39,26 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
for light in lights:
|
||||
if light.type in COVER_TYPES:
|
||||
if light.modelid in ZIGBEE_SPEC:
|
||||
entities.append(DeconzCoverZigbeeSpec(light))
|
||||
entities.append(DeconzCoverZigbeeSpec(light, gateway))
|
||||
else:
|
||||
entities.append(DeconzCover(light))
|
||||
entities.append(DeconzCover(light, gateway))
|
||||
async_add_entities(entities, True)
|
||||
|
||||
hass.data[DATA_DECONZ].listeners.append(
|
||||
gateway.listeners.append(
|
||||
async_dispatcher_connect(hass, 'deconz_new_light', async_add_cover))
|
||||
|
||||
async_add_cover(hass.data[DATA_DECONZ].api.lights.values())
|
||||
async_add_cover(gateway.api.lights.values())
|
||||
|
||||
|
||||
class DeconzCover(CoverDevice):
|
||||
"""Representation of a deCONZ cover."""
|
||||
|
||||
def __init__(self, cover):
|
||||
def __init__(self, cover, gateway):
|
||||
"""Set up cover and add update callback to get data from websocket."""
|
||||
self._cover = cover
|
||||
self.gateway = gateway
|
||||
self.unsub_dispatcher = None
|
||||
|
||||
self._features = SUPPORT_OPEN
|
||||
self._features |= SUPPORT_CLOSE
|
||||
self._features |= SUPPORT_STOP
|
||||
@ -61,11 +67,14 @@ class DeconzCover(CoverDevice):
|
||||
async def async_added_to_hass(self):
|
||||
"""Subscribe to covers events."""
|
||||
self._cover.register_async_callback(self.async_update_callback)
|
||||
self.hass.data[DATA_DECONZ].deconz_ids[self.entity_id] = \
|
||||
self._cover.deconz_id
|
||||
self.gateway.deconz_ids[self.entity_id] = self._cover.deconz_id
|
||||
self.unsub_dispatcher = async_dispatcher_connect(
|
||||
self.hass, DECONZ_REACHABLE, self.async_update_callback)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect cover object when removed."""
|
||||
if self.unsub_dispatcher is not None:
|
||||
self.unsub_dispatcher()
|
||||
self._cover.remove_callback(self.async_update_callback)
|
||||
self._cover = None
|
||||
|
||||
@ -112,7 +121,7 @@ class DeconzCover(CoverDevice):
|
||||
@property
|
||||
def available(self):
|
||||
"""Return True if light is available."""
|
||||
return self._cover.reachable
|
||||
return self.gateway.available and self._cover.reachable
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
@ -150,7 +159,7 @@ class DeconzCover(CoverDevice):
|
||||
self._cover.uniqueid.count(':') != 7):
|
||||
return None
|
||||
serial = self._cover.uniqueid.split('-', 1)[0]
|
||||
bridgeid = self.hass.data[DATA_DECONZ].api.config.bridgeid
|
||||
bridgeid = self.gateway.api.config.bridgeid
|
||||
return {
|
||||
'connections': {(CONNECTION_ZIGBEE, serial)},
|
||||
'identifiers': {(DECONZ_DOMAIN, serial)},
|
||||
|
@ -5,9 +5,6 @@ _LOGGER = logging.getLogger('homeassistant.components.deconz')
|
||||
|
||||
DOMAIN = 'deconz'
|
||||
CONFIG_FILE = 'deconz.conf'
|
||||
DATA_DECONZ_EVENT = 'deconz_events'
|
||||
DATA_DECONZ_ID = 'deconz_entities'
|
||||
DATA_DECONZ_UNSUB = 'deconz_dispatchers'
|
||||
DECONZ_DOMAIN = 'deconz'
|
||||
|
||||
CONF_ALLOW_CLIP_SENSOR = 'allow_clip_sensor'
|
||||
@ -16,6 +13,8 @@ CONF_ALLOW_DECONZ_GROUPS = 'allow_deconz_groups'
|
||||
SUPPORTED_PLATFORMS = ['binary_sensor', 'cover',
|
||||
'light', 'scene', 'sensor', 'switch']
|
||||
|
||||
DECONZ_REACHABLE = 'deconz_reachable'
|
||||
|
||||
ATTR_DARK = 'dark'
|
||||
ATTR_ON = 'on'
|
||||
|
||||
|
@ -8,7 +8,7 @@ from homeassistant.helpers.dispatcher import (
|
||||
from homeassistant.util import slugify
|
||||
|
||||
from .const import (
|
||||
_LOGGER, CONF_ALLOW_CLIP_SENSOR, SUPPORTED_PLATFORMS)
|
||||
_LOGGER, DECONZ_REACHABLE, CONF_ALLOW_CLIP_SENSOR, SUPPORTED_PLATFORMS)
|
||||
|
||||
|
||||
class DeconzGateway:
|
||||
@ -18,6 +18,7 @@ class DeconzGateway:
|
||||
"""Initialize the system."""
|
||||
self.hass = hass
|
||||
self.config_entry = config_entry
|
||||
self.available = True
|
||||
self.api = None
|
||||
self._cancel_retry_setup = None
|
||||
|
||||
@ -30,7 +31,8 @@ class DeconzGateway:
|
||||
hass = self.hass
|
||||
|
||||
self.api = await get_gateway(
|
||||
hass, self.config_entry.data, self.async_add_device_callback
|
||||
hass, self.config_entry.data, self.async_add_device_callback,
|
||||
self.async_connection_status_callback
|
||||
)
|
||||
|
||||
if self.api is False:
|
||||
@ -65,6 +67,13 @@ class DeconzGateway:
|
||||
|
||||
return True
|
||||
|
||||
@callback
|
||||
def async_connection_status_callback(self, available):
|
||||
"""Handle signals of gateway connection status."""
|
||||
self.available = available
|
||||
async_dispatcher_send(
|
||||
self.hass, DECONZ_REACHABLE, {'state': True, 'attr': 'reachable'})
|
||||
|
||||
@callback
|
||||
def async_add_device_callback(self, device_type, device):
|
||||
"""Handle event of new device creation in deCONZ."""
|
||||
@ -122,13 +131,15 @@ class DeconzGateway:
|
||||
return True
|
||||
|
||||
|
||||
async def get_gateway(hass, config, async_add_device_callback):
|
||||
async def get_gateway(hass, config, async_add_device_callback,
|
||||
async_connection_status_callback):
|
||||
"""Create a gateway object and verify configuration."""
|
||||
from pydeconz import DeconzSession
|
||||
|
||||
session = aiohttp_client.async_get_clientsession(hass)
|
||||
deconz = DeconzSession(hass.loop, session, **config,
|
||||
async_add_device=async_add_device_callback)
|
||||
async_add_device=async_add_device_callback,
|
||||
connection_status=async_connection_status_callback)
|
||||
result = await deconz.async_load_parameters()
|
||||
|
||||
if result:
|
||||
|
@ -5,7 +5,7 @@ For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/light.deconz/
|
||||
"""
|
||||
from homeassistant.components.deconz.const import (
|
||||
CONF_ALLOW_DECONZ_GROUPS, DOMAIN as DATA_DECONZ, DECONZ_DOMAIN,
|
||||
CONF_ALLOW_DECONZ_GROUPS, DECONZ_REACHABLE, DOMAIN as DECONZ_DOMAIN,
|
||||
COVER_TYPES, SWITCH_TYPES)
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_EFFECT, ATTR_FLASH, ATTR_HS_COLOR,
|
||||
@ -28,16 +28,18 @@ async def async_setup_platform(hass, config, async_add_entities,
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up the deCONZ lights and groups from a config entry."""
|
||||
gateway = hass.data[DECONZ_DOMAIN]
|
||||
|
||||
@callback
|
||||
def async_add_light(lights):
|
||||
"""Add light from deCONZ."""
|
||||
entities = []
|
||||
for light in lights:
|
||||
if light.type not in COVER_TYPES + SWITCH_TYPES:
|
||||
entities.append(DeconzLight(light))
|
||||
entities.append(DeconzLight(light, gateway))
|
||||
async_add_entities(entities, True)
|
||||
|
||||
hass.data[DATA_DECONZ].listeners.append(
|
||||
gateway.listeners.append(
|
||||
async_dispatcher_connect(hass, 'deconz_new_light', async_add_light))
|
||||
|
||||
@callback
|
||||
@ -47,22 +49,24 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
allow_group = config_entry.data.get(CONF_ALLOW_DECONZ_GROUPS, True)
|
||||
for group in groups:
|
||||
if group.lights and allow_group:
|
||||
entities.append(DeconzLight(group))
|
||||
entities.append(DeconzLight(group, gateway))
|
||||
async_add_entities(entities, True)
|
||||
|
||||
hass.data[DATA_DECONZ].listeners.append(
|
||||
gateway.listeners.append(
|
||||
async_dispatcher_connect(hass, 'deconz_new_group', async_add_group))
|
||||
|
||||
async_add_light(hass.data[DATA_DECONZ].api.lights.values())
|
||||
async_add_group(hass.data[DATA_DECONZ].api.groups.values())
|
||||
async_add_light(gateway.api.lights.values())
|
||||
async_add_group(gateway.api.groups.values())
|
||||
|
||||
|
||||
class DeconzLight(Light):
|
||||
"""Representation of a deCONZ light."""
|
||||
|
||||
def __init__(self, light):
|
||||
def __init__(self, light, gateway):
|
||||
"""Set up light and add update callback to get data from websocket."""
|
||||
self._light = light
|
||||
self.gateway = gateway
|
||||
self.unsub_dispatcher = None
|
||||
|
||||
self._features = SUPPORT_BRIGHTNESS
|
||||
self._features |= SUPPORT_FLASH
|
||||
@ -80,11 +84,14 @@ class DeconzLight(Light):
|
||||
async def async_added_to_hass(self):
|
||||
"""Subscribe to lights events."""
|
||||
self._light.register_async_callback(self.async_update_callback)
|
||||
self.hass.data[DATA_DECONZ].deconz_ids[self.entity_id] = \
|
||||
self._light.deconz_id
|
||||
self.gateway.deconz_ids[self.entity_id] = self._light.deconz_id
|
||||
self.unsub_dispatcher = async_dispatcher_connect(
|
||||
self.hass, DECONZ_REACHABLE, self.async_update_callback)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect light object when removed."""
|
||||
if self.unsub_dispatcher is not None:
|
||||
self.unsub_dispatcher()
|
||||
self._light.remove_callback(self.async_update_callback)
|
||||
self._light = None
|
||||
|
||||
@ -141,7 +148,7 @@ class DeconzLight(Light):
|
||||
@property
|
||||
def available(self):
|
||||
"""Return True if light is available."""
|
||||
return self._light.reachable
|
||||
return self.gateway.available and self._light.reachable
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
@ -214,7 +221,7 @@ class DeconzLight(Light):
|
||||
self._light.uniqueid.count(':') != 7):
|
||||
return None
|
||||
serial = self._light.uniqueid.split('-', 1)[0]
|
||||
bridgeid = self.hass.data[DATA_DECONZ].api.config.bridgeid
|
||||
bridgeid = self.gateway.api.config.bridgeid
|
||||
return {
|
||||
'connections': {(CONNECTION_ZIGBEE, serial)},
|
||||
'identifiers': {(DECONZ_DOMAIN, serial)},
|
||||
|
@ -4,7 +4,7 @@ Support for deCONZ scenes.
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/scene.deconz/
|
||||
"""
|
||||
from homeassistant.components.deconz import DOMAIN as DATA_DECONZ
|
||||
from homeassistant.components.deconz import DOMAIN as DECONZ_DOMAIN
|
||||
from homeassistant.components.scene import Scene
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
@ -20,30 +20,32 @@ async def async_setup_platform(hass, config, async_add_entities,
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up scenes for deCONZ component."""
|
||||
gateway = hass.data[DECONZ_DOMAIN]
|
||||
|
||||
@callback
|
||||
def async_add_scene(scenes):
|
||||
"""Add scene from deCONZ."""
|
||||
entities = []
|
||||
for scene in scenes:
|
||||
entities.append(DeconzScene(scene))
|
||||
entities.append(DeconzScene(scene, gateway))
|
||||
async_add_entities(entities)
|
||||
hass.data[DATA_DECONZ].listeners.append(
|
||||
gateway.listeners.append(
|
||||
async_dispatcher_connect(hass, 'deconz_new_scene', async_add_scene))
|
||||
|
||||
async_add_scene(hass.data[DATA_DECONZ].api.scenes.values())
|
||||
async_add_scene(gateway.api.scenes.values())
|
||||
|
||||
|
||||
class DeconzScene(Scene):
|
||||
"""Representation of a deCONZ scene."""
|
||||
|
||||
def __init__(self, scene):
|
||||
def __init__(self, scene, gateway):
|
||||
"""Set up a scene."""
|
||||
self._scene = scene
|
||||
self.gateway = gateway
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Subscribe to sensors events."""
|
||||
self.hass.data[DATA_DECONZ].deconz_ids[self.entity_id] = \
|
||||
self._scene.deconz_id
|
||||
self.gateway.deconz_ids[self.entity_id] = self._scene.deconz_id
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect scene object when removed."""
|
||||
|
@ -5,8 +5,8 @@ For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/sensor.deconz/
|
||||
"""
|
||||
from homeassistant.components.deconz.const import (
|
||||
ATTR_DARK, ATTR_ON, CONF_ALLOW_CLIP_SENSOR, DOMAIN as DATA_DECONZ,
|
||||
DECONZ_DOMAIN)
|
||||
ATTR_DARK, ATTR_ON, CONF_ALLOW_CLIP_SENSOR, DECONZ_REACHABLE,
|
||||
DOMAIN as DECONZ_DOMAIN)
|
||||
from homeassistant.const import (
|
||||
ATTR_BATTERY_LEVEL, ATTR_VOLTAGE, DEVICE_CLASS_BATTERY)
|
||||
from homeassistant.core import callback
|
||||
@ -30,6 +30,8 @@ async def async_setup_platform(hass, config, async_add_entities,
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up the deCONZ sensors."""
|
||||
gateway = hass.data[DECONZ_DOMAIN]
|
||||
|
||||
@callback
|
||||
def async_add_sensor(sensors):
|
||||
"""Add sensors from deCONZ."""
|
||||
@ -41,32 +43,37 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
not (not allow_clip_sensor and sensor.type.startswith('CLIP')):
|
||||
if sensor.type in DECONZ_REMOTE:
|
||||
if sensor.battery:
|
||||
entities.append(DeconzBattery(sensor))
|
||||
entities.append(DeconzBattery(sensor, gateway))
|
||||
else:
|
||||
entities.append(DeconzSensor(sensor))
|
||||
entities.append(DeconzSensor(sensor, gateway))
|
||||
async_add_entities(entities, True)
|
||||
|
||||
hass.data[DATA_DECONZ].listeners.append(
|
||||
gateway.listeners.append(
|
||||
async_dispatcher_connect(hass, 'deconz_new_sensor', async_add_sensor))
|
||||
|
||||
async_add_sensor(hass.data[DATA_DECONZ].api.sensors.values())
|
||||
async_add_sensor(gateway.api.sensors.values())
|
||||
|
||||
|
||||
class DeconzSensor(Entity):
|
||||
"""Representation of a sensor."""
|
||||
|
||||
def __init__(self, sensor):
|
||||
def __init__(self, sensor, gateway):
|
||||
"""Set up sensor and add update callback to get data from websocket."""
|
||||
self._sensor = sensor
|
||||
self.gateway = gateway
|
||||
self.unsub_dispatcher = None
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Subscribe to sensors events."""
|
||||
self._sensor.register_async_callback(self.async_update_callback)
|
||||
self.hass.data[DATA_DECONZ].deconz_ids[self.entity_id] = \
|
||||
self._sensor.deconz_id
|
||||
self.gateway.deconz_ids[self.entity_id] = self._sensor.deconz_id
|
||||
self.unsub_dispatcher = async_dispatcher_connect(
|
||||
self.hass, DECONZ_REACHABLE, self.async_update_callback)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect sensor object when removed."""
|
||||
if self.unsub_dispatcher is not None:
|
||||
self.unsub_dispatcher()
|
||||
self._sensor.remove_callback(self.async_update_callback)
|
||||
self._sensor = None
|
||||
|
||||
@ -116,7 +123,7 @@ class DeconzSensor(Entity):
|
||||
@property
|
||||
def available(self):
|
||||
"""Return true if sensor is available."""
|
||||
return self._sensor.reachable
|
||||
return self.gateway.available and self._sensor.reachable
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
@ -148,7 +155,7 @@ class DeconzSensor(Entity):
|
||||
self._sensor.uniqueid.count(':') != 7):
|
||||
return None
|
||||
serial = self._sensor.uniqueid.split('-', 1)[0]
|
||||
bridgeid = self.hass.data[DATA_DECONZ].api.config.bridgeid
|
||||
bridgeid = self.gateway.api.config.bridgeid
|
||||
return {
|
||||
'connections': {(CONNECTION_ZIGBEE, serial)},
|
||||
'identifiers': {(DECONZ_DOMAIN, serial)},
|
||||
@ -163,20 +170,26 @@ class DeconzSensor(Entity):
|
||||
class DeconzBattery(Entity):
|
||||
"""Battery class for when a device is only represented as an event."""
|
||||
|
||||
def __init__(self, sensor):
|
||||
def __init__(self, sensor, gateway):
|
||||
"""Register dispatcher callback for update of battery state."""
|
||||
self._sensor = sensor
|
||||
self.gateway = gateway
|
||||
self.unsub_dispatcher = None
|
||||
|
||||
self._name = '{} {}'.format(self._sensor.name, 'Battery Level')
|
||||
self._unit_of_measurement = "%"
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Subscribe to sensors events."""
|
||||
self._sensor.register_async_callback(self.async_update_callback)
|
||||
self.hass.data[DATA_DECONZ].deconz_ids[self.entity_id] = \
|
||||
self._sensor.deconz_id
|
||||
self.gateway.deconz_ids[self.entity_id] = self._sensor.deconz_id
|
||||
self.unsub_dispatcher = async_dispatcher_connect(
|
||||
self.hass, DECONZ_REACHABLE, self.async_update_callback)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect sensor object when removed."""
|
||||
if self.unsub_dispatcher is not None:
|
||||
self.unsub_dispatcher()
|
||||
self._sensor.remove_callback(self.async_update_callback)
|
||||
self._sensor = None
|
||||
|
||||
@ -211,6 +224,11 @@ class DeconzBattery(Entity):
|
||||
"""Return the unit of measurement of this entity."""
|
||||
return self._unit_of_measurement
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
"""Return true if sensor is available."""
|
||||
return self.gateway.available and self._sensor.reachable
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed."""
|
||||
@ -231,7 +249,7 @@ class DeconzBattery(Entity):
|
||||
self._sensor.uniqueid.count(':') != 7):
|
||||
return None
|
||||
serial = self._sensor.uniqueid.split('-', 1)[0]
|
||||
bridgeid = self.hass.data[DATA_DECONZ].api.config.bridgeid
|
||||
bridgeid = self.gateway.api.config.bridgeid
|
||||
return {
|
||||
'connections': {(CONNECTION_ZIGBEE, serial)},
|
||||
'identifiers': {(DECONZ_DOMAIN, serial)},
|
||||
|
@ -5,7 +5,7 @@ For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/switch.deconz/
|
||||
"""
|
||||
from homeassistant.components.deconz.const import (
|
||||
DOMAIN as DATA_DECONZ, DECONZ_DOMAIN, POWER_PLUGS, SIRENS)
|
||||
DECONZ_REACHABLE, DOMAIN as DECONZ_DOMAIN, POWER_PLUGS, SIRENS)
|
||||
from homeassistant.components.switch import SwitchDevice
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.device_registry import CONNECTION_ZIGBEE
|
||||
@ -25,38 +25,45 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
|
||||
Switches are based same device class as lights in deCONZ.
|
||||
"""
|
||||
gateway = hass.data[DECONZ_DOMAIN]
|
||||
|
||||
@callback
|
||||
def async_add_switch(lights):
|
||||
"""Add switch from deCONZ."""
|
||||
entities = []
|
||||
for light in lights:
|
||||
if light.type in POWER_PLUGS:
|
||||
entities.append(DeconzPowerPlug(light))
|
||||
entities.append(DeconzPowerPlug(light, gateway))
|
||||
elif light.type in SIRENS:
|
||||
entities.append(DeconzSiren(light))
|
||||
entities.append(DeconzSiren(light, gateway))
|
||||
async_add_entities(entities, True)
|
||||
|
||||
hass.data[DATA_DECONZ].listeners.append(
|
||||
gateway.listeners.append(
|
||||
async_dispatcher_connect(hass, 'deconz_new_light', async_add_switch))
|
||||
|
||||
async_add_switch(hass.data[DATA_DECONZ].api.lights.values())
|
||||
async_add_switch(gateway.api.lights.values())
|
||||
|
||||
|
||||
class DeconzSwitch(SwitchDevice):
|
||||
"""Representation of a deCONZ switch."""
|
||||
|
||||
def __init__(self, switch):
|
||||
def __init__(self, switch, gateway):
|
||||
"""Set up switch and add update callback to get data from websocket."""
|
||||
self._switch = switch
|
||||
self.gateway = gateway
|
||||
self.unsub_dispatcher = None
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Subscribe to switches events."""
|
||||
self._switch.register_async_callback(self.async_update_callback)
|
||||
self.hass.data[DATA_DECONZ].deconz_ids[self.entity_id] = \
|
||||
self._switch.deconz_id
|
||||
self.gateway.deconz_ids[self.entity_id] = self._switch.deconz_id
|
||||
self.unsub_dispatcher = async_dispatcher_connect(
|
||||
self.hass, DECONZ_REACHABLE, self.async_update_callback)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect switch object when removed."""
|
||||
if self.unsub_dispatcher is not None:
|
||||
self.unsub_dispatcher()
|
||||
self._switch.remove_callback(self.async_update_callback)
|
||||
self._switch = None
|
||||
|
||||
@ -78,7 +85,7 @@ class DeconzSwitch(SwitchDevice):
|
||||
@property
|
||||
def available(self):
|
||||
"""Return True if light is available."""
|
||||
return self._switch.reachable
|
||||
return self.gateway.available and self._switch.reachable
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
@ -92,7 +99,7 @@ class DeconzSwitch(SwitchDevice):
|
||||
self._switch.uniqueid.count(':') != 7):
|
||||
return None
|
||||
serial = self._switch.uniqueid.split('-', 1)[0]
|
||||
bridgeid = self.hass.data[DATA_DECONZ].api.config.bridgeid
|
||||
bridgeid = self.gateway.api.config.bridgeid
|
||||
return {
|
||||
'connections': {(CONNECTION_ZIGBEE, serial)},
|
||||
'identifiers': {(DECONZ_DOMAIN, serial)},
|
||||
|
Loading…
x
Reference in New Issue
Block a user