Z-Wave prevent I/O event loop (#6369)

* Prevent Z-Wave I/O in event loop

* Move value_handler to util class.

* Add docstring
This commit is contained in:
Paulus Schoutsen 2017-03-03 04:47:59 -08:00 committed by Andrey
parent ed9e93c29f
commit edf130b341
2 changed files with 63 additions and 63 deletions

View File

@ -26,6 +26,7 @@ import homeassistant.helpers.config_validation as cv
from . import const
from . import workaround
from .util import value_handler
REQUIREMENTS = ['pydispatcher==2.0.5']
@ -729,8 +730,11 @@ class ZWaveDeviceEntity(Entity):
from pydispatch import dispatcher
self._value = value
self._value.set_change_verified(False)
self.entity_id = "{}.{}".format(domain, self._object_id())
self.entity_id = "{}.{}".format(domain, object_id(value))
self._name = _value_name(self._value)
self._unique_id = "ZWAVE-{}-{}".format(self._value.node.node_id,
self._value.object_id)
self._wakeup_value_id = None
self._battery_value_id = None
self._power_value_id = None
@ -816,62 +820,13 @@ class ZWaveDeviceEntity(Entity):
self.power_consumption = round(
power_value.data, power_value.precision) if power_value else None
def _value_handler(self, method=None, class_id=None, index=None,
label=None, data=None, member=None, instance=None,
**kwargs):
"""Get the values for a given command_class with arguments.
May only be used inside callback.
"""
values = []
if class_id is None:
values.extend(self._value.node.get_values(**kwargs).values())
else:
if not isinstance(class_id, list):
class_id = [class_id]
for cid in class_id:
values.extend(self._value.node.get_values(
class_id=cid, **kwargs).values())
_LOGGER.debug('method=%s, class_id=%s, index=%s, label=%s, data=%s,'
' member=%s, instance=%d, kwargs=%s',
method, class_id, index, label, data, member, instance,
kwargs)
_LOGGER.debug('values=%s', values)
results = None
for value in values:
if index is not None and value.index != index:
continue
if label is not None:
label_found = False
for entry in label:
if value.label == entry:
label_found = True
break
if not label_found:
continue
if method == 'set':
value.data = data
return
if data is not None and value.data != data:
continue
if instance is not None and value.instance != instance:
continue
if member is not None:
results = getattr(value, member)
else:
results = value
break
_LOGGER.debug('final result=%s', results)
return results
def get_value(self, **kwargs):
"""Simplifyer to get values. May only be used inside callback."""
return self._value_handler(method='get', **kwargs)
return value_handler(self._value, method='get', **kwargs)
def set_value(self, **kwargs):
"""Simplifyer to set a value."""
return self._value_handler(method='set', **kwargs)
return value_handler(self._value, method='set', **kwargs)
def update_properties(self):
"""Callback on data changes for node values."""
@ -885,21 +840,12 @@ class ZWaveDeviceEntity(Entity):
@property
def unique_id(self):
"""Return an unique ID."""
return "ZWAVE-{}-{}".format(self._value.node.node_id,
self._value.object_id)
return self._unique_id
@property
def name(self):
"""Return the name of the device."""
return _value_name(self._value)
def _object_id(self):
"""Return the object_id of the device value.
The object_id contains node_id and value instance id to not collide
with other entity_ids.
"""
return object_id(self._value)
return self._name
@property
def device_state_attributes(self):

View File

@ -0,0 +1,54 @@
"""Zwave util methods."""
import logging
_LOGGER = logging.getLogger(__name__)
def value_handler(value, method=None, class_id=None, index=None,
label=None, data=None, member=None, instance=None,
**kwargs):
"""Get the values for a given command_class with arguments.
May only be used inside callback.
"""
values = []
if class_id is None:
values.extend(value.node.get_values(**kwargs).values())
else:
if not isinstance(class_id, list):
class_id = [class_id]
for cid in class_id:
values.extend(value.node.get_values(
class_id=cid, **kwargs).values())
_LOGGER.debug('method=%s, class_id=%s, index=%s, label=%s, data=%s,'
' member=%s, instance=%d, kwargs=%s',
method, class_id, index, label, data, member, instance,
kwargs)
_LOGGER.debug('values=%s', values)
results = None
for value in values:
if index is not None and value.index != index:
continue
if label is not None:
label_found = False
for entry in label:
if value.label == entry:
label_found = True
break
if not label_found:
continue
if method == 'set':
value.data = data
return
if data is not None and value.data != data:
continue
if instance is not None and value.instance != instance:
continue
if member is not None:
results = getattr(value, member)
else:
results = value
break
_LOGGER.debug('final result=%s', results)
return results