Use standard entity_ids for zwave entities (#7786)
* Use standard entity_ids for zwave entities * Include temporary opt-in for new entity ids * Update link to blog post * Update tests * Add old entity_id as state attribute * Expose ZWave value details * Update tests * Also show new_entity_id * Just can't win with this onepull/8068/head
parent
1c2f4866e2
commit
afb9cba806
|
@ -47,11 +47,11 @@ TEMP_COLD_HASS = (TEMP_COLOR_MAX - TEMP_COLOR_MIN) / 3 + TEMP_COLOR_MIN
|
|||
|
||||
def get_device(node, values, node_config, **kwargs):
|
||||
"""Create Z-Wave entity device."""
|
||||
name = '{}.{}'.format(DOMAIN, zwave.object_id(values.primary))
|
||||
refresh = node_config.get(zwave.CONF_REFRESH_VALUE)
|
||||
delay = node_config.get(zwave.CONF_REFRESH_DELAY)
|
||||
_LOGGER.debug("name=%s node_config=%s CONF_REFRESH_VALUE=%s"
|
||||
" CONF_REFRESH_DELAY=%s", name, node_config, refresh, delay)
|
||||
_LOGGER.debug("node=%d value=%d node_config=%s CONF_REFRESH_VALUE=%s"
|
||||
" CONF_REFRESH_DELAY=%s", node.node_id,
|
||||
values.primary.value_id, node_config, refresh, delay)
|
||||
|
||||
if node.has_command_class(zwave.const.COMMAND_CLASS_SWITCH_COLOR):
|
||||
return ZwaveColorLight(values, refresh, delay)
|
||||
|
|
|
@ -16,6 +16,7 @@ import voluptuous as vol
|
|||
from homeassistant.core import CoreState
|
||||
from homeassistant.loader import get_platform
|
||||
from homeassistant.helpers import discovery
|
||||
from homeassistant.helpers.entity import generate_entity_id
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
|
||||
|
@ -55,6 +56,7 @@ CONF_DEVICE_CONFIG = 'device_config'
|
|||
CONF_DEVICE_CONFIG_GLOB = 'device_config_glob'
|
||||
CONF_DEVICE_CONFIG_DOMAIN = 'device_config_domain'
|
||||
CONF_NETWORK_KEY = 'network_key'
|
||||
CONF_NEW_ENTITY_IDS = 'new_entity_ids'
|
||||
|
||||
ATTR_POWER = 'power_consumption'
|
||||
|
||||
|
@ -149,6 +151,7 @@ CONFIG_SCHEMA = vol.Schema({
|
|||
cv.positive_int,
|
||||
vol.Optional(CONF_USB_STICK_PATH, default=DEFAULT_CONF_USB_STICK_PATH):
|
||||
cv.string,
|
||||
vol.Optional(CONF_NEW_ENTITY_IDS, default=False): cv.boolean,
|
||||
}),
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
|
@ -162,7 +165,7 @@ def _obj_to_dict(obj):
|
|||
|
||||
def _value_name(value):
|
||||
"""Return the name of the value."""
|
||||
return '{} {}'.format(node_name(value.node), value.label)
|
||||
return '{} {}'.format(node_name(value.node), value.label).strip()
|
||||
|
||||
|
||||
def _node_object_id(node):
|
||||
|
@ -250,6 +253,13 @@ def setup(hass, config):
|
|||
config[DOMAIN][CONF_DEVICE_CONFIG],
|
||||
config[DOMAIN][CONF_DEVICE_CONFIG_DOMAIN],
|
||||
config[DOMAIN][CONF_DEVICE_CONFIG_GLOB])
|
||||
new_entity_ids = config[DOMAIN][CONF_NEW_ENTITY_IDS]
|
||||
if not new_entity_ids:
|
||||
_LOGGER.warning(
|
||||
"ZWave entity_ids will soon be changing. To opt in to new "
|
||||
"entity_ids now, set `new_entity_ids: true` under zwave in your "
|
||||
"configuration.yaml. See the following blog post for details: "
|
||||
"https://home-assistant.io/blog/2017/06/15/zwave-entity-ids/")
|
||||
|
||||
# Setup options
|
||||
options = ZWaveOption(
|
||||
|
@ -311,30 +321,20 @@ def setup(hass, config):
|
|||
|
||||
def node_added(node):
|
||||
"""Handle a new node on the network."""
|
||||
entity = ZWaveNodeEntity(node, network)
|
||||
node_config = device_config.get(entity.entity_id)
|
||||
entity = ZWaveNodeEntity(node, network, new_entity_ids)
|
||||
name = node_name(node)
|
||||
if new_entity_ids:
|
||||
generated_id = generate_entity_id(DOMAIN + '.{}', name, [])
|
||||
else:
|
||||
generated_id = entity.entity_id
|
||||
node_config = device_config.get(generated_id)
|
||||
if node_config.get(CONF_IGNORED):
|
||||
_LOGGER.info(
|
||||
"Ignoring node entity %s due to device settings",
|
||||
entity.entity_id)
|
||||
generated_id)
|
||||
return
|
||||
component.add_entities([entity])
|
||||
|
||||
def scene_activated(node, scene_id):
|
||||
"""Handle an activated scene on any node in the network."""
|
||||
hass.bus.fire(const.EVENT_SCENE_ACTIVATED, {
|
||||
ATTR_ENTITY_ID: _node_object_id(node),
|
||||
const.ATTR_OBJECT_ID: _node_object_id(node),
|
||||
const.ATTR_SCENE_ID: scene_id
|
||||
})
|
||||
|
||||
def node_event_activated(node, value):
|
||||
"""Handle a nodeevent on any node in the network."""
|
||||
hass.bus.fire(const.EVENT_NODE_EVENT, {
|
||||
const.ATTR_OBJECT_ID: _node_object_id(node),
|
||||
const.ATTR_BASIC_LEVEL: value
|
||||
})
|
||||
|
||||
def network_ready():
|
||||
"""Handle the query of all awake nodes."""
|
||||
_LOGGER.info("Zwave network is ready for use. All awake nodes "
|
||||
|
@ -352,10 +352,6 @@ def setup(hass, config):
|
|||
value_added, ZWaveNetwork.SIGNAL_VALUE_ADDED, weak=False)
|
||||
dispatcher.connect(
|
||||
node_added, ZWaveNetwork.SIGNAL_NODE_ADDED, weak=False)
|
||||
dispatcher.connect(
|
||||
scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT, weak=False)
|
||||
dispatcher.connect(
|
||||
node_event_activated, ZWaveNetwork.SIGNAL_NODE_EVENT, weak=False)
|
||||
dispatcher.connect(
|
||||
network_ready, ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED, weak=False)
|
||||
dispatcher.connect(
|
||||
|
@ -757,9 +753,8 @@ class ZWaveDeviceEntityValues():
|
|||
self.primary)
|
||||
if workaround_component and workaround_component != component:
|
||||
if workaround_component == workaround.WORKAROUND_IGNORE:
|
||||
_LOGGER.info("Ignoring device %s due to workaround.",
|
||||
"{}.{}".format(
|
||||
component, object_id(self.primary)))
|
||||
_LOGGER.info("Ignoring Node %d Value %d due to workaround.",
|
||||
self.primary.node.node_id, self.primary.value_id)
|
||||
# No entity will be created for this value
|
||||
self._workaround_ignore = True
|
||||
return
|
||||
|
@ -767,8 +762,13 @@ class ZWaveDeviceEntityValues():
|
|||
workaround_component, component)
|
||||
component = workaround_component
|
||||
|
||||
name = "{}.{}".format(component, object_id(self.primary))
|
||||
node_config = self._device_config.get(name)
|
||||
value_name = _value_name(self.primary)
|
||||
if self._zwave_config[DOMAIN][CONF_NEW_ENTITY_IDS]:
|
||||
generated_id = generate_entity_id(
|
||||
component + '.{}', value_name, [])
|
||||
else:
|
||||
generated_id = "{}.{}".format(component, object_id(self.primary))
|
||||
node_config = self._device_config.get(generated_id)
|
||||
|
||||
# Configure node
|
||||
_LOGGER.debug("Adding Node_id=%s Generic_command_class=%s, "
|
||||
|
@ -781,7 +781,7 @@ class ZWaveDeviceEntityValues():
|
|||
|
||||
if node_config.get(CONF_IGNORED):
|
||||
_LOGGER.info(
|
||||
"Ignoring entity %s due to device settings", name)
|
||||
"Ignoring entity %s due to device settings", generated_id)
|
||||
# No entity will be created for this value
|
||||
self._workaround_ignore = True
|
||||
return
|
||||
|
@ -802,6 +802,12 @@ class ZWaveDeviceEntityValues():
|
|||
self._workaround_ignore = True
|
||||
return
|
||||
|
||||
device.old_entity_id = "{}.{}".format(
|
||||
component, object_id(self.primary))
|
||||
device.new_entity_id = "{}.{}".format(component, slugify(device.name))
|
||||
if not self._zwave_config[DOMAIN][CONF_NEW_ENTITY_IDS]:
|
||||
device.entity_id = device.old_entity_id
|
||||
|
||||
self._entity = device
|
||||
|
||||
dict_id = id(self)
|
||||
|
@ -828,7 +834,6 @@ class ZWaveDeviceEntity(ZWaveBaseEntity):
|
|||
self.values = values
|
||||
self.node = values.primary.node
|
||||
self.values.primary.set_change_verified(False)
|
||||
self.entity_id = "{}.{}".format(domain, object_id(values.primary))
|
||||
|
||||
self._name = _value_name(self.values.primary)
|
||||
self._unique_id = "ZWAVE-{}-{}".format(self.node.node_id,
|
||||
|
@ -895,6 +900,10 @@ class ZWaveDeviceEntity(ZWaveBaseEntity):
|
|||
"""Return the device specific state attributes."""
|
||||
attrs = {
|
||||
const.ATTR_NODE_ID: self.node_id,
|
||||
const.ATTR_VALUE_INDEX: self.values.primary.index,
|
||||
const.ATTR_VALUE_INSTANCE: self.values.primary.instance,
|
||||
'old_entity_id': self.old_entity_id,
|
||||
'new_entity_id': self.new_entity_id,
|
||||
}
|
||||
|
||||
if self.power_consumption is not None:
|
||||
|
|
|
@ -31,6 +31,8 @@ class ZWaveNodeValueView(HomeAssistantView):
|
|||
|
||||
values_data[entity_values.primary.value_id] = {
|
||||
'label': entity_values.primary.label,
|
||||
'index': entity_values.primary.index,
|
||||
'instance': entity_values.primary.instance,
|
||||
}
|
||||
return self.json(values_data)
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ ATTR_BASIC_LEVEL = "basic_level"
|
|||
ATTR_CONFIG_PARAMETER = "parameter"
|
||||
ATTR_CONFIG_SIZE = "size"
|
||||
ATTR_CONFIG_VALUE = "value"
|
||||
ATTR_VALUE_INDEX = "value_index"
|
||||
ATTR_VALUE_INSTANCE = "value_instance"
|
||||
NETWORK_READY_WAIT_SECS = 30
|
||||
|
||||
DISCOVERY_DEVICE = 'device'
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
import logging
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.const import ATTR_BATTERY_LEVEL, ATTR_WAKEUP
|
||||
from homeassistant.const import ATTR_BATTERY_LEVEL, ATTR_WAKEUP, ATTR_ENTITY_ID
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.util import slugify
|
||||
|
||||
from .const import ATTR_NODE_ID, DOMAIN, COMMAND_CLASS_WAKE_UP
|
||||
from .const import (
|
||||
ATTR_NODE_ID, COMMAND_CLASS_WAKE_UP, ATTR_SCENE_ID, ATTR_BASIC_LEVEL,
|
||||
EVENT_NODE_EVENT, EVENT_SCENE_ACTIVATED, DOMAIN)
|
||||
from .util import node_name
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -38,6 +40,8 @@ class ZWaveBaseEntity(Entity):
|
|||
def __init__(self):
|
||||
"""Initialize the base Z-Wave class."""
|
||||
self._update_scheduled = False
|
||||
self.old_entity_id = None
|
||||
self.new_entity_id = None
|
||||
|
||||
def maybe_schedule_update(self):
|
||||
"""Maybe schedule state update.
|
||||
|
@ -72,7 +76,7 @@ def sub_status(status, stage):
|
|||
class ZWaveNodeEntity(ZWaveBaseEntity):
|
||||
"""Representation of a Z-Wave node."""
|
||||
|
||||
def __init__(self, node, network):
|
||||
def __init__(self, node, network, new_entity_ids):
|
||||
"""Initialize node."""
|
||||
# pylint: disable=import-error
|
||||
super().__init__()
|
||||
|
@ -84,8 +88,11 @@ class ZWaveNodeEntity(ZWaveBaseEntity):
|
|||
self._name = node_name(self.node)
|
||||
self._product_name = node.product_name
|
||||
self._manufacturer_name = node.manufacturer_name
|
||||
self.entity_id = "{}.{}_{}".format(
|
||||
self.old_entity_id = "{}.{}_{}".format(
|
||||
DOMAIN, slugify(self._name), self.node_id)
|
||||
self.new_entity_id = "{}.{}".format(DOMAIN, slugify(self._name))
|
||||
if not new_entity_ids:
|
||||
self.entity_id = self.old_entity_id
|
||||
self._attributes = {}
|
||||
self.wakeup_interval = None
|
||||
self.location = None
|
||||
|
@ -95,6 +102,10 @@ class ZWaveNodeEntity(ZWaveBaseEntity):
|
|||
dispatcher.connect(self.network_node_changed, ZWaveNetwork.SIGNAL_NODE)
|
||||
dispatcher.connect(
|
||||
self.network_node_changed, ZWaveNetwork.SIGNAL_NOTIFICATION)
|
||||
dispatcher.connect(
|
||||
self.network_node_event, ZWaveNetwork.SIGNAL_NODE_EVENT)
|
||||
dispatcher.connect(
|
||||
self.network_scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT)
|
||||
|
||||
def network_node_changed(self, node=None, args=None):
|
||||
"""Handle a changed node on the network."""
|
||||
|
@ -134,6 +145,38 @@ class ZWaveNodeEntity(ZWaveBaseEntity):
|
|||
|
||||
self.maybe_schedule_update()
|
||||
|
||||
def network_node_event(self, node, value):
|
||||
"""Handle a node activated event on the network."""
|
||||
if node.node_id == self.node.node_id:
|
||||
self.node_event(value)
|
||||
|
||||
def node_event(self, value):
|
||||
"""Handle a node activated event for this node."""
|
||||
if self.hass is None:
|
||||
return
|
||||
|
||||
self.hass.bus.fire(EVENT_NODE_EVENT, {
|
||||
ATTR_ENTITY_ID: self.entity_id,
|
||||
ATTR_NODE_ID: self.node.node_id,
|
||||
ATTR_BASIC_LEVEL: value
|
||||
})
|
||||
|
||||
def network_scene_activated(self, node, scene_id):
|
||||
"""Handle a scene activated event on the network."""
|
||||
if node.node_id == self.node.node_id:
|
||||
self.scene_activated(scene_id)
|
||||
|
||||
def scene_activated(self, scene_id):
|
||||
"""Handle an activated scene for this node."""
|
||||
if self.hass is None:
|
||||
return
|
||||
|
||||
self.hass.bus.fire(EVENT_SCENE_ACTIVATED, {
|
||||
ATTR_ENTITY_ID: self.entity_id,
|
||||
ATTR_NODE_ID: self.node.node_id,
|
||||
ATTR_SCENE_ID: scene_id
|
||||
})
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state."""
|
||||
|
@ -169,6 +212,8 @@ class ZWaveNodeEntity(ZWaveBaseEntity):
|
|||
ATTR_NODE_NAME: self._name,
|
||||
ATTR_MANUFACTURER_NAME: self._manufacturer_name,
|
||||
ATTR_PRODUCT_NAME: self._product_name,
|
||||
'old_entity_id': self.old_entity_id,
|
||||
'new_entity_id': self.new_entity_id,
|
||||
}
|
||||
attrs.update(self._attributes)
|
||||
if self.battery_level is not None:
|
||||
|
|
|
@ -16,7 +16,8 @@ def test_get_values(hass, test_client):
|
|||
ZWaveNodeValueView().register(app.router)
|
||||
|
||||
node = MockNode(node_id=1)
|
||||
value = MockValue(value_id=123456, node=node, label='Test Label')
|
||||
value = MockValue(value_id=123456, node=node, label='Test Label',
|
||||
instance=1, index=2)
|
||||
values = MockEntityValues(primary=value)
|
||||
node2 = MockNode(node_id=2)
|
||||
value2 = MockValue(value_id=234567, node=node2, label='Test Label 2')
|
||||
|
@ -33,6 +34,8 @@ def test_get_values(hass, test_client):
|
|||
assert result == {
|
||||
'123456': {
|
||||
'label': 'Test Label',
|
||||
'instance': 1,
|
||||
'index': 2,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -214,7 +214,9 @@ def test_node_discovery(hass, mock_openzwave):
|
|||
mock_receivers.append(receiver)
|
||||
|
||||
with patch('pydispatch.dispatcher.connect', new=mock_connect):
|
||||
yield from async_setup_component(hass, 'zwave', {'zwave': {}})
|
||||
yield from async_setup_component(hass, 'zwave', {'zwave': {
|
||||
'new_entity_ids': True,
|
||||
}})
|
||||
|
||||
assert len(mock_receivers) == 1
|
||||
|
||||
|
@ -222,7 +224,7 @@ def test_node_discovery(hass, mock_openzwave):
|
|||
hass.async_add_job(mock_receivers[0], node)
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get('zwave.mock_node_14').state is 'unknown'
|
||||
assert hass.states.get('zwave.mock_node').state is 'unknown'
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
|
@ -236,8 +238,9 @@ def test_node_ignored(hass, mock_openzwave):
|
|||
|
||||
with patch('pydispatch.dispatcher.connect', new=mock_connect):
|
||||
yield from async_setup_component(hass, 'zwave', {'zwave': {
|
||||
'new_entity_ids': True,
|
||||
'device_config': {
|
||||
'zwave.mock_node_14': {
|
||||
'zwave.mock_node': {
|
||||
'ignored': True,
|
||||
}}}})
|
||||
|
||||
|
@ -247,7 +250,7 @@ def test_node_ignored(hass, mock_openzwave):
|
|||
hass.async_add_job(mock_receivers[0], node)
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get('zwave.mock_node_14') is None
|
||||
assert hass.states.get('zwave.mock_node') is None
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
|
@ -260,7 +263,9 @@ def test_value_discovery(hass, mock_openzwave):
|
|||
mock_receivers.append(receiver)
|
||||
|
||||
with patch('pydispatch.dispatcher.connect', new=mock_connect):
|
||||
yield from async_setup_component(hass, 'zwave', {'zwave': {}})
|
||||
yield from async_setup_component(hass, 'zwave', {'zwave': {
|
||||
'new_entity_ids': True,
|
||||
}})
|
||||
|
||||
assert len(mock_receivers) == 1
|
||||
|
||||
|
@ -272,7 +277,7 @@ def test_value_discovery(hass, mock_openzwave):
|
|||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get(
|
||||
'binary_sensor.mock_node_mock_value_11_12_13').state is 'off'
|
||||
'binary_sensor.mock_node_mock_value').state is 'off'
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
|
@ -285,7 +290,9 @@ def test_value_discovery_existing_entity(hass, mock_openzwave):
|
|||
mock_receivers.append(receiver)
|
||||
|
||||
with patch('pydispatch.dispatcher.connect', new=mock_connect):
|
||||
yield from async_setup_component(hass, 'zwave', {'zwave': {}})
|
||||
yield from async_setup_component(hass, 'zwave', {'zwave': {
|
||||
'new_entity_ids': True,
|
||||
}})
|
||||
|
||||
assert len(mock_receivers) == 1
|
||||
|
||||
|
@ -297,9 +304,9 @@ def test_value_discovery_existing_entity(hass, mock_openzwave):
|
|||
hass.async_add_job(mock_receivers[0], node, setpoint)
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get('climate.mock_node_mock_value_11_12_13').attributes[
|
||||
assert hass.states.get('climate.mock_node_mock_value').attributes[
|
||||
'temperature'] == 22.0
|
||||
assert hass.states.get('climate.mock_node_mock_value_11_12_13').attributes[
|
||||
assert hass.states.get('climate.mock_node_mock_value').attributes[
|
||||
'current_temperature'] is None
|
||||
|
||||
def mock_update(self):
|
||||
|
@ -314,75 +321,12 @@ def test_value_discovery_existing_entity(hass, mock_openzwave):
|
|||
hass.async_add_job(mock_receivers[0], node, temperature)
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get('climate.mock_node_mock_value_11_12_13').attributes[
|
||||
assert hass.states.get('climate.mock_node_mock_value').attributes[
|
||||
'temperature'] == 22.0
|
||||
assert hass.states.get('climate.mock_node_mock_value_11_12_13').attributes[
|
||||
assert hass.states.get('climate.mock_node_mock_value').attributes[
|
||||
'current_temperature'] == 23.5
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_scene_activated(hass, mock_openzwave):
|
||||
"""Test scene activated event."""
|
||||
mock_receivers = []
|
||||
|
||||
def mock_connect(receiver, signal, *args, **kwargs):
|
||||
if signal == MockNetwork.SIGNAL_SCENE_EVENT:
|
||||
mock_receivers.append(receiver)
|
||||
|
||||
with patch('pydispatch.dispatcher.connect', new=mock_connect):
|
||||
yield from async_setup_component(hass, 'zwave', {'zwave': {}})
|
||||
|
||||
assert len(mock_receivers) == 1
|
||||
|
||||
events = []
|
||||
|
||||
def listener(event):
|
||||
events.append(event)
|
||||
|
||||
hass.bus.async_listen(const.EVENT_SCENE_ACTIVATED, listener)
|
||||
|
||||
node = MockNode(node_id=11)
|
||||
scene_id = 123
|
||||
hass.async_add_job(mock_receivers[0], node, scene_id)
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert len(events) == 1
|
||||
assert events[0].data[ATTR_ENTITY_ID] == "mock_node_11"
|
||||
assert events[0].data[const.ATTR_OBJECT_ID] == "mock_node_11"
|
||||
assert events[0].data[const.ATTR_SCENE_ID] == scene_id
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_node_event_activated(hass, mock_openzwave):
|
||||
"""Test Node event activated event."""
|
||||
mock_receivers = []
|
||||
|
||||
def mock_connect(receiver, signal, *args, **kwargs):
|
||||
if signal == MockNetwork.SIGNAL_NODE_EVENT:
|
||||
mock_receivers.append(receiver)
|
||||
|
||||
with patch('pydispatch.dispatcher.connect', new=mock_connect):
|
||||
yield from async_setup_component(hass, 'zwave', {'zwave': {}})
|
||||
|
||||
assert len(mock_receivers) == 1
|
||||
|
||||
events = []
|
||||
|
||||
def listener(event):
|
||||
events.append(event)
|
||||
|
||||
hass.bus.async_listen(const.EVENT_NODE_EVENT, listener)
|
||||
|
||||
node = MockNode(node_id=11)
|
||||
value = 234
|
||||
hass.async_add_job(mock_receivers[0], node, value)
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert len(events) == 1
|
||||
assert events[0].data[const.ATTR_OBJECT_ID] == "mock_node_11"
|
||||
assert events[0].data[const.ATTR_BASIC_LEVEL] == value
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_network_ready(hass, mock_openzwave):
|
||||
"""Test Node network ready event."""
|
||||
|
@ -393,7 +337,9 @@ def test_network_ready(hass, mock_openzwave):
|
|||
mock_receivers.append(receiver)
|
||||
|
||||
with patch('pydispatch.dispatcher.connect', new=mock_connect):
|
||||
yield from async_setup_component(hass, 'zwave', {'zwave': {}})
|
||||
yield from async_setup_component(hass, 'zwave', {'zwave': {
|
||||
'new_entity_ids': True,
|
||||
}})
|
||||
|
||||
assert len(mock_receivers) == 1
|
||||
|
||||
|
@ -420,7 +366,9 @@ def test_network_complete(hass, mock_openzwave):
|
|||
mock_receivers.append(receiver)
|
||||
|
||||
with patch('pydispatch.dispatcher.connect', new=mock_connect):
|
||||
yield from async_setup_component(hass, 'zwave', {'zwave': {}})
|
||||
yield from async_setup_component(hass, 'zwave', {'zwave': {
|
||||
'new_entity_ids': True,
|
||||
}})
|
||||
|
||||
assert len(mock_receivers) == 1
|
||||
|
||||
|
@ -450,7 +398,9 @@ class TestZWaveDeviceEntityValues(unittest.TestCase):
|
|||
self.hass = get_test_home_assistant()
|
||||
self.hass.start()
|
||||
|
||||
setup_component(self.hass, 'zwave', {'zwave': {}})
|
||||
setup_component(self.hass, 'zwave', {'zwave': {
|
||||
'new_entity_ids': True,
|
||||
}})
|
||||
self.hass.block_till_done()
|
||||
|
||||
self.node = MockNode()
|
||||
|
@ -478,9 +428,10 @@ class TestZWaveDeviceEntityValues(unittest.TestCase):
|
|||
self.no_match_value = MockValue(
|
||||
command_class='mock_bad_class', node=self.node)
|
||||
|
||||
self.entity_id = '{}.{}'.format('mock_component',
|
||||
zwave.object_id(self.primary))
|
||||
self.zwave_config = {}
|
||||
self.entity_id = 'mock_component.mock_node_mock_value'
|
||||
self.zwave_config = {'zwave': {
|
||||
'new_entity_ids': True,
|
||||
}}
|
||||
self.device_config = {self.entity_id: {}}
|
||||
|
||||
def tearDown(self): # pylint: disable=invalid-name
|
||||
|
@ -491,6 +442,11 @@ class TestZWaveDeviceEntityValues(unittest.TestCase):
|
|||
@patch.object(zwave, 'discovery')
|
||||
def test_entity_discovery(self, discovery, get_platform):
|
||||
"""Test the creation of a new entity."""
|
||||
mock_platform = MagicMock()
|
||||
get_platform.return_value = mock_platform
|
||||
mock_device = MagicMock()
|
||||
mock_device.name = 'test_device'
|
||||
mock_platform.get_device.return_value = mock_device
|
||||
values = zwave.ZWaveDeviceEntityValues(
|
||||
hass=self.hass,
|
||||
schema=self.mock_schema,
|
||||
|
@ -550,6 +506,11 @@ class TestZWaveDeviceEntityValues(unittest.TestCase):
|
|||
@patch.object(zwave, 'discovery')
|
||||
def test_entity_existing_values(self, discovery, get_platform):
|
||||
"""Test the loading of already discovered values."""
|
||||
mock_platform = MagicMock()
|
||||
get_platform.return_value = mock_platform
|
||||
mock_device = MagicMock()
|
||||
mock_device.name = 'test_device'
|
||||
mock_platform.get_device.return_value = mock_device
|
||||
self.node.values = {
|
||||
self.primary.value_id: self.primary,
|
||||
self.secondary.value_id: self.secondary,
|
||||
|
@ -613,11 +574,15 @@ class TestZWaveDeviceEntityValues(unittest.TestCase):
|
|||
@patch.object(zwave, 'discovery')
|
||||
def test_entity_workaround_component(self, discovery, get_platform):
|
||||
"""Test ignore workaround."""
|
||||
mock_platform = MagicMock()
|
||||
get_platform.return_value = mock_platform
|
||||
mock_device = MagicMock()
|
||||
mock_device.name = 'test_device'
|
||||
mock_platform.get_device.return_value = mock_device
|
||||
self.node.manufacturer_id = '010f'
|
||||
self.node.product_type = '0b00'
|
||||
self.primary.command_class = const.COMMAND_CLASS_SENSOR_ALARM
|
||||
self.entity_id = '{}.{}'.format('binary_sensor',
|
||||
zwave.object_id(self.primary))
|
||||
self.entity_id = 'binary_sensor.mock_node_mock_value'
|
||||
self.device_config = {self.entity_id: {}}
|
||||
|
||||
self.mock_schema = {
|
||||
|
@ -721,6 +686,11 @@ class TestZWaveDeviceEntityValues(unittest.TestCase):
|
|||
@patch.object(zwave, 'discovery')
|
||||
def test_config_polling_intensity(self, discovery, get_platform):
|
||||
"""Test polling intensity."""
|
||||
mock_platform = MagicMock()
|
||||
get_platform.return_value = mock_platform
|
||||
mock_device = MagicMock()
|
||||
mock_device.name = 'test_device'
|
||||
mock_platform.get_device.return_value = mock_device
|
||||
self.node.values = {
|
||||
self.primary.value_id: self.primary,
|
||||
self.secondary.value_id: self.secondary,
|
||||
|
@ -770,7 +740,9 @@ class TestZWaveServices(unittest.TestCase):
|
|||
self.hass.start()
|
||||
|
||||
# Initialize zwave
|
||||
setup_component(self.hass, 'zwave', {'zwave': {}})
|
||||
setup_component(self.hass, 'zwave', {'zwave': {
|
||||
'new_entity_ids': True,
|
||||
}})
|
||||
self.hass.block_till_done()
|
||||
self.zwave_network = self.hass.data[DATA_NETWORK]
|
||||
self.zwave_network.state = MockNetwork.STATE_READY
|
||||
|
|
|
@ -4,7 +4,8 @@ import unittest
|
|||
from unittest.mock import patch, MagicMock
|
||||
import tests.mock.zwave as mock_zwave
|
||||
import pytest
|
||||
from homeassistant.components.zwave import node_entity
|
||||
from homeassistant.components.zwave import node_entity, const
|
||||
from homeassistant.const import ATTR_ENTITY_ID
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
|
@ -30,6 +31,92 @@ def test_maybe_schedule_update(hass, mock_openzwave):
|
|||
assert len(mock_call_later.mock_calls) == 2
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_node_event_activated(hass, mock_openzwave):
|
||||
"""Test Node event activated event."""
|
||||
mock_receivers = []
|
||||
|
||||
def mock_connect(receiver, signal, *args, **kwargs):
|
||||
if signal == mock_zwave.MockNetwork.SIGNAL_NODE_EVENT:
|
||||
mock_receivers.append(receiver)
|
||||
|
||||
node = mock_zwave.MockNode(node_id=11)
|
||||
|
||||
with patch('pydispatch.dispatcher.connect', new=mock_connect):
|
||||
entity = node_entity.ZWaveNodeEntity(node, mock_openzwave, True)
|
||||
|
||||
assert len(mock_receivers) == 1
|
||||
|
||||
events = []
|
||||
|
||||
def listener(event):
|
||||
events.append(event)
|
||||
|
||||
hass.bus.async_listen(const.EVENT_NODE_EVENT, listener)
|
||||
|
||||
# Test event before entity added to hass
|
||||
value = 234
|
||||
hass.async_add_job(mock_receivers[0], node, value)
|
||||
yield from hass.async_block_till_done()
|
||||
assert len(events) == 0
|
||||
|
||||
# Add entity to hass
|
||||
entity.hass = hass
|
||||
entity.entity_id = 'zwave.mock_node'
|
||||
|
||||
value = 234
|
||||
hass.async_add_job(mock_receivers[0], node, value)
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert len(events) == 1
|
||||
assert events[0].data[ATTR_ENTITY_ID] == "zwave.mock_node"
|
||||
assert events[0].data[const.ATTR_NODE_ID] == 11
|
||||
assert events[0].data[const.ATTR_BASIC_LEVEL] == value
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_scene_activated(hass, mock_openzwave):
|
||||
"""Test scene activated event."""
|
||||
mock_receivers = []
|
||||
|
||||
def mock_connect(receiver, signal, *args, **kwargs):
|
||||
if signal == mock_zwave.MockNetwork.SIGNAL_SCENE_EVENT:
|
||||
mock_receivers.append(receiver)
|
||||
|
||||
node = mock_zwave.MockNode(node_id=11)
|
||||
|
||||
with patch('pydispatch.dispatcher.connect', new=mock_connect):
|
||||
entity = node_entity.ZWaveNodeEntity(node, mock_openzwave, True)
|
||||
|
||||
assert len(mock_receivers) == 1
|
||||
|
||||
events = []
|
||||
|
||||
def listener(event):
|
||||
events.append(event)
|
||||
|
||||
hass.bus.async_listen(const.EVENT_SCENE_ACTIVATED, listener)
|
||||
|
||||
# Test event before entity added to hass
|
||||
scene_id = 123
|
||||
hass.async_add_job(mock_receivers[0], node, scene_id)
|
||||
yield from hass.async_block_till_done()
|
||||
assert len(events) == 0
|
||||
|
||||
# Add entity to hass
|
||||
entity.hass = hass
|
||||
entity.entity_id = 'zwave.mock_node'
|
||||
|
||||
scene_id = 123
|
||||
hass.async_add_job(mock_receivers[0], node, scene_id)
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert len(events) == 1
|
||||
assert events[0].data[ATTR_ENTITY_ID] == "zwave.mock_node"
|
||||
assert events[0].data[const.ATTR_NODE_ID] == 11
|
||||
assert events[0].data[const.ATTR_SCENE_ID] == scene_id
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('mock_openzwave')
|
||||
class TestZWaveNodeEntity(unittest.TestCase):
|
||||
"""Class to test ZWaveNodeEntity."""
|
||||
|
@ -44,7 +131,7 @@ class TestZWaveNodeEntity(unittest.TestCase):
|
|||
self.node.manufacturer_name = 'Test Manufacturer'
|
||||
self.node.product_name = 'Test Product'
|
||||
self.entity = node_entity.ZWaveNodeEntity(self.node,
|
||||
self.zwave_network)
|
||||
self.zwave_network, True)
|
||||
|
||||
def test_network_node_changed_from_value(self):
|
||||
"""Test for network_node_changed."""
|
||||
|
@ -85,6 +172,8 @@ class TestZWaveNodeEntity(unittest.TestCase):
|
|||
{'node_id': self.node.node_id,
|
||||
'node_name': 'Mock Node',
|
||||
'manufacturer_name': 'Test Manufacturer',
|
||||
'old_entity_id': 'zwave.mock_node_567',
|
||||
'new_entity_id': 'zwave.mock_node',
|
||||
'product_name': 'Test Product'},
|
||||
self.entity.device_state_attributes)
|
||||
|
||||
|
@ -143,6 +232,8 @@ class TestZWaveNodeEntity(unittest.TestCase):
|
|||
{'node_id': self.node.node_id,
|
||||
'node_name': 'Mock Node',
|
||||
'manufacturer_name': 'Test Manufacturer',
|
||||
'old_entity_id': 'zwave.mock_node_567',
|
||||
'new_entity_id': 'zwave.mock_node',
|
||||
'product_name': 'Test Product',
|
||||
'query_stage': 'Dynamic',
|
||||
'is_awake': True,
|
||||
|
|
Loading…
Reference in New Issue