From cc1979691e33609a59b4508499874f1986facca3 Mon Sep 17 00:00:00 2001 From: John Arild Berentsen Date: Mon, 11 Sep 2017 20:30:48 +0200 Subject: [PATCH] Add polling interval service and setting available through zwave node entity panel (#9056) * Add polling interval to value panel * Blank lines removal * Update tests * Remove old config method * Raound 1 * Round 2 * Comment spacing * Expose value_id in attributes --- homeassistant/components/config/zwave.py | 1 + homeassistant/components/zwave/__init__.py | 36 ++++++++- homeassistant/components/zwave/const.py | 2 + homeassistant/components/zwave/services.yaml | 14 ++++ tests/components/config/test_zwave.py | 3 +- tests/components/zwave/test_init.py | 81 +++++++++++++++++++- 6 files changed, 132 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/config/zwave.py b/homeassistant/components/config/zwave.py index a40e1f64043..53fa200a1b1 100644 --- a/homeassistant/components/config/zwave.py +++ b/homeassistant/components/config/zwave.py @@ -55,6 +55,7 @@ class ZWaveNodeValueView(HomeAssistantView): 'label': entity_values.primary.label, 'index': entity_values.primary.index, 'instance': entity_values.primary.instance, + 'poll_intensity': entity_values.primary.poll_intensity, } return self.json(values_data) diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py index 853966279b6..c88c55e258f 100755 --- a/homeassistant/components/zwave/__init__.py +++ b/homeassistant/components/zwave/__init__.py @@ -85,6 +85,12 @@ SET_CONFIG_PARAMETER_SCHEMA = vol.Schema({ vol.Optional(const.ATTR_CONFIG_SIZE, default=2): vol.Coerce(int) }) +SET_POLL_INTENSITY_SCHEMA = vol.Schema({ + vol.Required(const.ATTR_NODE_ID): vol.Coerce(int), + vol.Required(const.ATTR_VALUE_ID): vol.Coerce(int), + vol.Required(const.ATTR_POLL_INTENSITY): vol.Coerce(int), +}) + PRINT_CONFIG_PARAMETER_SCHEMA = vol.Schema({ vol.Required(const.ATTR_NODE_ID): vol.Coerce(int), vol.Required(const.ATTR_CONFIG_PARAMETER): vol.Coerce(int), @@ -415,6 +421,29 @@ def setup(hass, config): "Renamed Z-Wave value (Node %d Value %d) to %s", node_id, value_id, name) + def set_poll_intensity(service): + """Set the polling intensity of a node value.""" + node_id = service.data.get(const.ATTR_NODE_ID) + value_id = service.data.get(const.ATTR_VALUE_ID) + node = network.nodes[node_id] + value = node.values[value_id] + intensity = service.data.get(const.ATTR_POLL_INTENSITY) + if intensity == 0: + if value.disable_poll(): + _LOGGER.info("Polling disabled (Node %d Value %d)", + node_id, value_id) + return + _LOGGER.info("Polling disabled failed (Node %d Value %d)", + node_id, value_id) + else: + if value.enable_poll(intensity): + _LOGGER.info( + "Set polling intensity (Node %d Value %d) to %s", + node_id, value_id, intensity) + return + _LOGGER.info("Set polling intensity failed (Node %d Value %d)", + node_id, value_id) + def remove_failed_node(service): """Remove failed node.""" node_id = service.data.get(const.ATTR_NODE_ID) @@ -651,6 +680,10 @@ def setup(hass, config): descriptions[ const.SERVICE_RESET_NODE_METERS], schema=RESET_NODE_METERS_SCHEMA) + hass.services.register(DOMAIN, const.SERVICE_SET_POLL_INTENSITY, + set_poll_intensity, + descriptions[const.SERVICE_SET_POLL_INTENSITY], + schema=SET_POLL_INTENSITY_SCHEMA) # Setup autoheal if autoheal: @@ -775,8 +808,6 @@ class ZWaveDeviceEntityValues(): node_config.get(CONF_POLLING_INTENSITY), int) if polling_intensity: self.primary.enable_poll(polling_intensity) - else: - self.primary.disable_poll() platform = get_platform(component, DOMAIN) device = platform.get_device( @@ -887,6 +918,7 @@ class ZWaveDeviceEntity(ZWaveBaseEntity): const.ATTR_NODE_ID: self.node_id, const.ATTR_VALUE_INDEX: self.values.primary.index, const.ATTR_VALUE_INSTANCE: self.values.primary.instance, + const.ATTR_VALUE_ID: str(self.values.primary.value_id), 'old_entity_id': self.old_entity_id, 'new_entity_id': self.new_entity_id, } diff --git a/homeassistant/components/zwave/const.py b/homeassistant/components/zwave/const.py index a238d01d520..dced1689dba 100644 --- a/homeassistant/components/zwave/const.py +++ b/homeassistant/components/zwave/const.py @@ -15,6 +15,7 @@ ATTR_BASIC_LEVEL = "basic_level" ATTR_CONFIG_PARAMETER = "parameter" ATTR_CONFIG_SIZE = "size" ATTR_CONFIG_VALUE = "value" +ATTR_POLL_INTENSITY = "poll_intensity" ATTR_VALUE_INDEX = "value_index" ATTR_VALUE_INSTANCE = "value_instance" NETWORK_READY_WAIT_SECS = 30 @@ -38,6 +39,7 @@ SERVICE_PRINT_CONFIG_PARAMETER = "print_config_parameter" SERVICE_PRINT_NODE = "print_node" SERVICE_REMOVE_FAILED_NODE = "remove_failed_node" SERVICE_REPLACE_FAILED_NODE = "replace_failed_node" +SERVICE_SET_POLL_INTENSITY = "set_poll_intensity" SERVICE_SET_WAKEUP = "set_wakeup" SERVICE_STOP_NETWORK = "stop_network" SERVICE_START_NETWORK = "start_network" diff --git a/homeassistant/components/zwave/services.yaml b/homeassistant/components/zwave/services.yaml index ea8a6eaa036..92b5fa25d20 100644 --- a/homeassistant/components/zwave/services.yaml +++ b/homeassistant/components/zwave/services.yaml @@ -56,6 +56,20 @@ set_config_parameter: size: description: (Optional) Set the size of the parameter value. Only needed if no parameters are available. +set_poll_intensity: + description: Set the polling interval to a nodes value + fields: + node_id: + description: ID of the node to set polling to. + example: 10 + value_id: + description: ID of the value to set polling to. + example: 72037594255792737 + poll_intensity: + description: The intensity to poll, 0 = disabled, 1 = Every time through list, 2 = Every second time through list... + example: 2 + + print_config_parameter: description: Prints a Z-Wave node config parameter value to log. fields: diff --git a/tests/components/config/test_zwave.py b/tests/components/config/test_zwave.py index ecf4d6ecb29..fc359dc7ff7 100644 --- a/tests/components/config/test_zwave.py +++ b/tests/components/config/test_zwave.py @@ -143,7 +143,7 @@ def test_get_values(hass, test_client): node = MockNode(node_id=1) value = MockValue(value_id=123456, node=node, label='Test Label', - instance=1, index=2) + instance=1, index=2, poll_intensity=4) values = MockEntityValues(primary=value) node2 = MockNode(node_id=2) value2 = MockValue(value_id=234567, node=node2, label='Test Label 2') @@ -162,6 +162,7 @@ def test_get_values(hass, test_client): 'label': 'Test Label', 'instance': 1, 'index': 2, + 'poll_intensity': 4, } } diff --git a/tests/components/zwave/test_init.py b/tests/components/zwave/test_init.py index 2fa4dd0b929..1e759949a46 100644 --- a/tests/components/zwave/test_init.py +++ b/tests/components/zwave/test_init.py @@ -576,7 +576,6 @@ class TestZWaveDeviceEntityValues(unittest.TestCase): assert args[3] == {const.DISCOVERY_DEVICE: id(values)} assert args[4] == self.zwave_config assert not self.primary.enable_poll.called - assert self.primary.disable_poll.called @patch.object(zwave, 'get_platform') @patch.object(zwave, 'discovery') @@ -742,7 +741,6 @@ class TestZWaveDeviceEntityValues(unittest.TestCase): assert self.primary.enable_poll.called assert len(self.primary.enable_poll.mock_calls) == 1 assert self.primary.enable_poll.mock_calls[0][1][0] == 123 - assert not self.primary.disable_poll.called class TestZwave(unittest.TestCase): @@ -887,6 +885,85 @@ class TestZWaveServices(unittest.TestCase): assert value.label == "New Label" + def test_set_poll_intensity_enable(self): + """Test zwave set_poll_intensity service, succsessful set.""" + node = MockNode(node_id=14) + value = MockValue(index=12, value_id=123456, poll_intensity=0) + node.values = {123456: value} + self.zwave_network.nodes = {11: node} + + assert value.poll_intensity == 0 + self.hass.services.call('zwave', 'set_poll_intensity', { + const.ATTR_NODE_ID: 11, + const.ATTR_VALUE_ID: 123456, + const.ATTR_POLL_INTENSITY: 4, + }) + self.hass.block_till_done() + + enable_poll = value.enable_poll + assert value.enable_poll.called + assert len(enable_poll.mock_calls) == 2 + assert enable_poll.mock_calls[0][1][0] == 4 + + def test_set_poll_intensity_enable_failed(self): + """Test zwave set_poll_intensity service, failed set.""" + node = MockNode(node_id=14) + value = MockValue(index=12, value_id=123456, poll_intensity=0) + value.enable_poll.return_value = False + node.values = {123456: value} + self.zwave_network.nodes = {11: node} + + assert value.poll_intensity == 0 + self.hass.services.call('zwave', 'set_poll_intensity', { + const.ATTR_NODE_ID: 11, + const.ATTR_VALUE_ID: 123456, + const.ATTR_POLL_INTENSITY: 4, + }) + self.hass.block_till_done() + + enable_poll = value.enable_poll + assert value.enable_poll.called + assert len(enable_poll.mock_calls) == 1 + + def test_set_poll_intensity_disable(self): + """Test zwave set_poll_intensity service, successful disable.""" + node = MockNode(node_id=14) + value = MockValue(index=12, value_id=123456, poll_intensity=4) + node.values = {123456: value} + self.zwave_network.nodes = {11: node} + + assert value.poll_intensity == 4 + self.hass.services.call('zwave', 'set_poll_intensity', { + const.ATTR_NODE_ID: 11, + const.ATTR_VALUE_ID: 123456, + const.ATTR_POLL_INTENSITY: 0, + }) + self.hass.block_till_done() + + disable_poll = value.disable_poll + assert value.disable_poll.called + assert len(disable_poll.mock_calls) == 2 + + def test_set_poll_intensity_disable_failed(self): + """Test zwave set_poll_intensity service, failed disable.""" + node = MockNode(node_id=14) + value = MockValue(index=12, value_id=123456, poll_intensity=4) + value.disable_poll.return_value = False + node.values = {123456: value} + self.zwave_network.nodes = {11: node} + + assert value.poll_intensity == 4 + self.hass.services.call('zwave', 'set_poll_intensity', { + const.ATTR_NODE_ID: 11, + const.ATTR_VALUE_ID: 123456, + const.ATTR_POLL_INTENSITY: 0, + }) + self.hass.block_till_done() + + disable_poll = value.disable_poll + assert value.disable_poll.called + assert len(disable_poll.mock_calls) == 1 + def test_remove_failed_node(self): """Test zwave remove_failed_node service.""" self.hass.services.call('zwave', 'remove_failed_node', {