diff --git a/homeassistant/components/zwave/const.py b/homeassistant/components/zwave/const.py index b72d9eb0cff..a238d01d520 100644 --- a/homeassistant/components/zwave/const.py +++ b/homeassistant/components/zwave/const.py @@ -10,6 +10,7 @@ ATTR_VALUE_ID = "value_id" ATTR_OBJECT_ID = "object_id" ATTR_NAME = "name" ATTR_SCENE_ID = "scene_id" +ATTR_SCENE_DATA = "scene_data" ATTR_BASIC_LEVEL = "basic_level" ATTR_CONFIG_PARAMETER = "parameter" ATTR_CONFIG_SIZE = "size" diff --git a/homeassistant/components/zwave/node_entity.py b/homeassistant/components/zwave/node_entity.py index 3a810d00d2d..44a30cdc529 100644 --- a/homeassistant/components/zwave/node_entity.py +++ b/homeassistant/components/zwave/node_entity.py @@ -7,8 +7,9 @@ from homeassistant.helpers.entity import Entity from homeassistant.util import slugify from .const import ( - ATTR_NODE_ID, COMMAND_CLASS_WAKE_UP, ATTR_SCENE_ID, ATTR_BASIC_LEVEL, - EVENT_NODE_EVENT, EVENT_SCENE_ACTIVATED, DOMAIN) + ATTR_NODE_ID, COMMAND_CLASS_WAKE_UP, ATTR_SCENE_ID, ATTR_SCENE_DATA, + ATTR_BASIC_LEVEL, EVENT_NODE_EVENT, EVENT_SCENE_ACTIVATED, DOMAIN, + COMMAND_CLASS_CENTRAL_SCENE) from .util import node_name _LOGGER = logging.getLogger(__name__) @@ -107,13 +108,19 @@ class ZWaveNodeEntity(ZWaveBaseEntity): dispatcher.connect( self.network_scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT) - def network_node_changed(self, node=None, args=None): + def network_node_changed(self, node=None, value=None, args=None): """Handle a changed node on the network.""" if node and node.node_id != self.node_id: return if args is not None and 'nodeId' in args and \ args['nodeId'] != self.node_id: return + + # Process central scene activation + if (value is not None and + value.command_class == COMMAND_CLASS_CENTRAL_SCENE): + self.central_scene_activated(value.index, value.data) + self.node_changed() def get_node_statistics(self): @@ -177,6 +184,18 @@ class ZWaveNodeEntity(ZWaveBaseEntity): ATTR_SCENE_ID: scene_id }) + def central_scene_activated(self, scene_id, scene_data): + """Handle an activated central 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_id, + ATTR_SCENE_ID: scene_id, + ATTR_SCENE_DATA: scene_data + }) + @property def state(self): """Return the state.""" diff --git a/tests/components/zwave/test_node_entity.py b/tests/components/zwave/test_node_entity.py index b7148dd982e..32351234ad3 100644 --- a/tests/components/zwave/test_node_entity.py +++ b/tests/components/zwave/test_node_entity.py @@ -117,6 +117,60 @@ def test_scene_activated(hass, mock_openzwave): assert events[0].data[const.ATTR_SCENE_ID] == scene_id +@asyncio.coroutine +def test_central_scene_activated(hass, mock_openzwave): + """Test central scene activated event.""" + mock_receivers = [] + + def mock_connect(receiver, signal, *args, **kwargs): + if signal == mock_zwave.MockNetwork.SIGNAL_VALUE_CHANGED: + 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 = 1 + scene_data = 3 + value = mock_zwave.MockValue( + command_class=const.COMMAND_CLASS_CENTRAL_SCENE, + index=scene_id, + data=scene_data) + 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' + + scene_id = 1 + scene_data = 3 + value = mock_zwave.MockValue( + command_class=const.COMMAND_CLASS_CENTRAL_SCENE, + index=scene_id, + data=scene_data) + 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_SCENE_ID] == scene_id + assert events[0].data[const.ATTR_SCENE_DATA] == scene_data + + @pytest.mark.usefixtures('mock_openzwave') class TestZWaveNodeEntity(unittest.TestCase): """Class to test ZWaveNodeEntity."""