-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve service by allowing to reference entity id instead of deconz id #11862
Conversation
cbc4091
to
84d3e57
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear to me why this is necessary to begin with?
yield from deconz.async_put_state(field, data) | ||
entity_id = call.data.get(SERVICE_ENTITY) | ||
data_string = call.data.get(SERVICE_DATA) | ||
data = ast.literal_eval(data_string) # String to dict |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eval is not allowed, too dangerous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have suggestion about how I can get a dictionary here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Issue here is that data is expected to be json compliant, which it unfortunately isn't since it get single quotes, where as json.loads expects double quotes. So there is a translation going on from the service entry in the gui to the service in the backend; {"name": "TRADFRI motion sensor 1"} arrives as {'name': 'TRADFRI motion sensor 1'}
@@ -29,6 +30,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): | |||
if sensor and sensor.type in DECONZ_BINARY_SENSOR: | |||
entities.append(DeconzBinarySensor(sensor)) | |||
async_add_devices(entities, True) | |||
hass.data[DECONZ_ENTITIES] = hass.data[DECONZ_ENTITIES] + entities |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not allowed. Main component should not have access to the entity objects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I could just do a translation dict between entity name and deconz id instead
The real issue is that there is no easy way for the user to know the deconZ_id. I could add it as an attribute to each entity or do you have an alternative to how I can do this? The important thing is to help the user being able to use the service with all devices in deconz. |
@balloob I'd be happy to implement according to your wishes or redesign when your entity registry has been delivered, can we move forward with this? |
facbb09
to
9da45a6
Compare
bcea029
to
9c902b9
Compare
9c902b9
to
f5b54fe
Compare
@@ -37,6 +38,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): | |||
entities.append(DeconzBattery(sensor)) | |||
else: | |||
entities.append(DeconzSensor(sensor)) | |||
#entities.append(DeconzSensor(sensor, entity_registry)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
block comment should start with '# '
@@ -26,6 +26,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): | |||
|
|||
from pydeconz.sensor import DECONZ_SENSOR, SWITCH as DECONZ_REMOTE | |||
sensors = hass.data[DECONZ_DATA].sensors | |||
#entity_registry = hass.data[DECONZ_ENTITIES] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
block comment should start with '# '
groups = list(deconz.groups.values()) | ||
lights = list(deconz.lights.values()) | ||
sensors = list(deconz.sensors.values()) | ||
devices = groups + lights + sensors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what you're looking for is chain
, that way you don't have to create a list but can just iterate over it.
from itertools import chain
for device in chain(deconz.groups.values(), deconz.lights.values(), …):
deconz = hass.data[DOMAIN] | ||
|
||
registry = hass.data.get(DATA_REGISTRY) | ||
if registry.async_is_registered(entity_id): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed here, just get the entry. Do make sure to use guard clause pattern:
entry = registry.async_get_entry(…)
if entry is None:
_LOGGER.error(…)
return
registry = hass.data.get(DATA_REGISTRY) | ||
entity = registry.async_get_entry(entity_id) | ||
for device in chain( | ||
deconz.groups.values(), deconz.lights.values(), deconz.sensors.values()): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
line too long (93 > 79 characters)
…gether with deconz id
Fixed call to protected member
74a1b1d
to
757e1c2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry. I've thought about it more and I think that it's better to keep the Entity Registry private for now. So let have deconz keep track of unique id's.
You could do something like this fairly easy by leveraging the async_added_to_hass
callback:
class DeconzLight(Light):
@asyncio.coroutine
def async_added_to_hass(self):
"""Called when entity added to hass."""
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self.unique_id
(self.hass
and self.entity_id
are guaranteed to exist when async_added_to_hass
is called)
@balloob alright, should I remove the new method for registry? Yes that was the original way I was doing it, just thought the registry would remove the need for a local registry. |
I know. Sorry for not realizing this earlier. Let's remove it. |
No worries, it is not always easy to have a plan ready for new functionality. I will change these things tonight. |
import asyncio | ||
import logging | ||
from itertools import chain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'itertools.chain' imported but unused
import asyncio | ||
import logging | ||
from itertools import chain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'itertools.chain' imported but unused
@balloob better like this? |
async_add_devices(entities, True) | ||
|
||
|
||
class DeconzBinarySensor(BinarySensorDevice): | ||
"""Representation of a binary sensor.""" | ||
|
||
def __init__(self, sensor): | ||
def __init__(self, hass, sensor): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't pass in hass
. It will be set on the entity when the entity has been added to home assistant. This means you can access hass
with self.hass
, after the entity has been added to home assistant.
"""Set up sensor and add update callback to get data from websocket.""" | ||
self.hass = hass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this.
async_add_devices(entities, True) | ||
|
||
|
||
class DeconzLight(Light): | ||
"""Representation of a deCONZ light.""" | ||
|
||
def __init__(self, light): | ||
def __init__(self, hass, light): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't pass in hass
. It will be set on the entity when the entity has been added to home assistant. This means you can access hass
with self.hass
, after the entity has been added to home assistant.
"""Set up light and add update callback to get data from websocket.""" | ||
self.hass = hass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove.
async_add_devices(entities) | ||
|
||
|
||
class DeconzScene(Scene): | ||
"""Representation of a deCONZ scene.""" | ||
|
||
def __init__(self, scene): | ||
def __init__(self, hass, scene): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
"""Set up a scene.""" | ||
self.hass = hass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
async_add_devices(entities, True) | ||
|
||
|
||
class DeconzSensor(Entity): | ||
"""Representation of a sensor.""" | ||
|
||
def __init__(self, sensor): | ||
def __init__(self, hass, sensor): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
"""Set up sensor and add update callback to get data from websocket.""" | ||
self.hass = hass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
@@ -116,8 +119,9 @@ def device_state_attributes(self): | |||
class DeconzBattery(Entity): | |||
"""Battery class for when a device is only represented as an event.""" | |||
|
|||
def __init__(self, device): | |||
def __init__(self, hass, device): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
"""Register dispatcher callback for update of battery state.""" | ||
self.hass = hass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me!
Thanks @MartinHjelmare |
Description:
It is cumbersome to get ahold of the deconz_id, this allows the user to specify the entity_id instead.
Related issue (if applicable): fixes #
Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.io#4494
Checklist:
If user exposed functionality or configuration variables are added/changed: