Improve service by allowing to reference entity id instead of deconz id (#11862)

* Improve service by allowing to reference entity id instead of deconz id

* Change from having access to full entities to only store entity id together with deconz id

* Don't use eval, there is a dict type for voluptuous

* Use entity registry instead of keeping a local registry over entity ids

* Removed old code

* Add test for get_entry

* Bump dependency to v28
Fixed call to protected member

* Use chain to iterate over dict values

* Cleanup

* Fix hound comment

* Cleanup

* Follow refactoring of entity

* Revert to using a local registry

* Remove unused import

* self.hass is automatically available when entity is registered in hass
This commit is contained in:
Kane610 2018-02-14 01:23:04 +01:00 committed by Paulus Schoutsen
parent a4944da68f
commit 8bff813014
7 changed files with 46 additions and 17 deletions

View file

@ -7,7 +7,8 @@ https://home-assistant.io/components/binary_sensor.deconz/
import asyncio
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.components.deconz import DOMAIN as DECONZ_DATA
from homeassistant.components.deconz import (
DOMAIN as DATA_DECONZ, DATA_DECONZ_ID)
from homeassistant.const import ATTR_BATTERY_LEVEL
from homeassistant.core import callback
@ -21,7 +22,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
return
from pydeconz.sensor import DECONZ_BINARY_SENSOR
sensors = hass.data[DECONZ_DATA].sensors
sensors = hass.data[DATA_DECONZ].sensors
entities = []
for key in sorted(sensors.keys(), key=int):
@ -42,6 +43,7 @@ class DeconzBinarySensor(BinarySensorDevice):
def async_added_to_hass(self):
"""Subscribe sensors events."""
self._sensor.register_async_callback(self.async_update_callback)
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self._sensor.deconz_id
@callback
def async_update_callback(self, reason):

View file

@ -4,6 +4,7 @@ Support for deCONZ devices.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/deconz/
"""
import asyncio
import logging
@ -17,11 +18,12 @@ from homeassistant.helpers import discovery
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.util.json import load_json, save_json
REQUIREMENTS = ['pydeconz==27']
REQUIREMENTS = ['pydeconz==28']
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'deconz'
DATA_DECONZ_ID = 'deconz_entities'
CONFIG_FILE = 'deconz.conf'
@ -34,13 +36,16 @@ CONFIG_SCHEMA = vol.Schema({
}, extra=vol.ALLOW_EXTRA)
SERVICE_FIELD = 'field'
SERVICE_ENTITY = 'entity'
SERVICE_DATA = 'data'
SERVICE_SCHEMA = vol.Schema({
vol.Required(SERVICE_FIELD): cv.string,
vol.Exclusive(SERVICE_FIELD, 'deconz_id'): cv.string,
vol.Exclusive(SERVICE_ENTITY, 'deconz_id'): cv.entity_id,
vol.Required(SERVICE_DATA): dict,
})
CONFIG_INSTRUCTIONS = """
Unlock your deCONZ gateway to register with Home Assistant.
@ -100,6 +105,7 @@ def async_setup_deconz(hass, config, deconz_config):
return False
hass.data[DOMAIN] = deconz
hass.data[DATA_DECONZ_ID] = {}
for component in ['binary_sensor', 'light', 'scene', 'sensor']:
hass.async_add_job(discovery.async_load_platform(
@ -112,6 +118,7 @@ def async_setup_deconz(hass, config, deconz_config):
Field is a string representing a specific device in deCONZ
e.g. field='/lights/1/state'.
Entity_id can be used to retrieve the proper field.
Data is a json object with what data you want to alter
e.g. data={'on': true}.
{
@ -121,9 +128,17 @@ def async_setup_deconz(hass, config, deconz_config):
See Dresden Elektroniks REST API documentation for details:
http://dresden-elektronik.github.io/deconz-rest-doc/rest/
"""
deconz = hass.data[DOMAIN]
field = call.data.get(SERVICE_FIELD)
entity_id = call.data.get(SERVICE_ENTITY)
data = call.data.get(SERVICE_DATA)
deconz = hass.data[DOMAIN]
if entity_id:
entities = hass.data.get(DATA_DECONZ_ID)
if entities:
field = entities.get(entity_id)
if field is None:
_LOGGER.error('Could not find the entity %s', entity_id)
return
yield from deconz.async_put_state(field, data)
hass.services.async_register(
DOMAIN, 'configure', async_configure, schema=SERVICE_SCHEMA)

View file

@ -1,10 +1,13 @@
configure:
description: Set attribute of device in Deconz. See Dresden Elektroniks REST API documentation for details http://dresden-elektronik.github.io/deconz-rest-doc/rest/
description: Set attribute of device in deCONZ. See https://home-assistant.io/components/deconz/#device-services for details.
fields:
field:
description: Field is a string representing a specific device in Deconz.
description: Field is a string representing a specific device in deCONZ.
example: '/lights/1/state'
entity:
description: Entity id representing a specific device in deCONZ.
example: 'light.rgb_light'
data:
description: Data is a json object with what data you want to alter.
example: '{"on": true}'

View file

@ -6,7 +6,8 @@ https://home-assistant.io/components/light.deconz/
"""
import asyncio
from homeassistant.components.deconz import DOMAIN as DECONZ_DATA
from homeassistant.components.deconz import (
DOMAIN as DATA_DECONZ, DATA_DECONZ_ID)
from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_EFFECT, ATTR_FLASH, ATTR_RGB_COLOR,
ATTR_TRANSITION, ATTR_XY_COLOR, EFFECT_COLORLOOP, FLASH_LONG, FLASH_SHORT,
@ -17,8 +18,6 @@ from homeassistant.util.color import color_RGB_to_xy
DEPENDENCIES = ['deconz']
ATTR_LIGHT_GROUP = 'LightGroup'
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
@ -26,8 +25,8 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
if discovery_info is None:
return
lights = hass.data[DECONZ_DATA].lights
groups = hass.data[DECONZ_DATA].groups
lights = hass.data[DATA_DECONZ].lights
groups = hass.data[DATA_DECONZ].groups
entities = []
for light in lights.values():
@ -64,6 +63,7 @@ class DeconzLight(Light):
def async_added_to_hass(self):
"""Subscribe to lights events."""
self._light.register_async_callback(self.async_update_callback)
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self._light.deconz_id
@callback
def async_update_callback(self, reason):

View file

@ -6,7 +6,8 @@ https://home-assistant.io/components/scene.deconz/
"""
import asyncio
from homeassistant.components.deconz import DOMAIN as DECONZ_DATA
from homeassistant.components.deconz import (
DOMAIN as DATA_DECONZ, DATA_DECONZ_ID)
from homeassistant.components.scene import Scene
DEPENDENCIES = ['deconz']
@ -18,7 +19,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
if discovery_info is None:
return
scenes = hass.data[DECONZ_DATA].scenes
scenes = hass.data[DATA_DECONZ].scenes
entities = []
for scene in scenes.values():
@ -33,6 +34,11 @@ class DeconzScene(Scene):
"""Set up a scene."""
self._scene = scene
@asyncio.coroutine
def async_added_to_hass(self):
"""Subscribe to sensors events."""
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self._scene.deconz_id
@asyncio.coroutine
def async_activate(self):
"""Activate the scene."""

View file

@ -6,7 +6,8 @@ https://home-assistant.io/components/sensor.deconz/
"""
import asyncio
from homeassistant.components.deconz import DOMAIN as DECONZ_DATA
from homeassistant.components.deconz import (
DOMAIN as DATA_DECONZ, DATA_DECONZ_ID)
from homeassistant.const import ATTR_BATTERY_LEVEL, CONF_EVENT, CONF_ID
from homeassistant.core import EventOrigin, callback
from homeassistant.helpers.entity import Entity
@ -25,7 +26,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
return
from pydeconz.sensor import DECONZ_SENSOR, SWITCH as DECONZ_REMOTE
sensors = hass.data[DECONZ_DATA].sensors
sensors = hass.data[DATA_DECONZ].sensors
entities = []
for key in sorted(sensors.keys(), key=int):
@ -51,6 +52,7 @@ class DeconzSensor(Entity):
def async_added_to_hass(self):
"""Subscribe to sensors events."""
self._sensor.register_async_callback(self.async_update_callback)
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self._sensor.deconz_id
@callback
def async_update_callback(self, reason):
@ -127,6 +129,7 @@ class DeconzBattery(Entity):
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
@callback
def async_update_callback(self, reason):

View file

@ -688,7 +688,7 @@ pycsspeechtts==1.0.2
pydaikin==0.4
# homeassistant.components.deconz
pydeconz==27
pydeconz==28
# homeassistant.components.zwave
pydispatcher==2.0.5