Add new services for set/refresh Z-Wave device values (#16638)

* Add services for getting and setting indicator values for Z-Wave

* Add service to manually refresh Z-Wave node value by value_id

* Remove refresh_indicator service

* Coerce to int

* Add generic set_node_value service

* Remove set_indicator service
This commit is contained in:
Blake Blackshear 2018-09-27 05:34:42 -05:00 committed by Paulus Schoutsen
parent ad79dc673d
commit 2cc6263092
5 changed files with 103 additions and 1 deletions

View File

@ -84,6 +84,17 @@ SET_CONFIG_PARAMETER_SCHEMA = vol.Schema({
vol.Optional(const.ATTR_CONFIG_SIZE, default=2): vol.Coerce(int)
})
SET_NODE_VALUE_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_CONFIG_VALUE): vol.Coerce(int)
})
REFRESH_NODE_VALUE_SCHEMA = vol.Schema({
vol.Required(const.ATTR_NODE_ID): vol.Coerce(int),
vol.Required(const.ATTR_VALUE_ID): 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),
@ -492,6 +503,23 @@ async def async_setup(hass, config):
"with selection %s", param, node_id,
selection)
def refresh_node_value(service):
"""Refresh the specified value from a node."""
node_id = service.data.get(const.ATTR_NODE_ID)
value_id = service.data.get(const.ATTR_VALUE_ID)
node = network.nodes[node_id]
node.values[value_id].refresh()
_LOGGER.info("Node %s value %s refreshed", node_id, value_id)
def set_node_value(service):
"""Set the specified value on a node."""
node_id = service.data.get(const.ATTR_NODE_ID)
value_id = service.data.get(const.ATTR_VALUE_ID)
value = service.data.get(const.ATTR_CONFIG_VALUE)
node = network.nodes[node_id]
node.values[value_id].data = value
_LOGGER.info("Node %s value %s set to %s", node_id, value_id, value)
def print_config_parameter(service):
"""Print a config parameter from a node."""
node_id = service.data.get(const.ATTR_NODE_ID)
@ -662,6 +690,12 @@ async def async_setup(hass, config):
hass.services.register(DOMAIN, const.SERVICE_SET_CONFIG_PARAMETER,
set_config_parameter,
schema=SET_CONFIG_PARAMETER_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_SET_NODE_VALUE,
set_node_value,
schema=SET_NODE_VALUE_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_REFRESH_NODE_VALUE,
refresh_node_value,
schema=REFRESH_NODE_VALUE_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_PRINT_CONFIG_PARAMETER,
print_config_parameter,
schema=PRINT_CONFIG_PARAMETER_SCHEMA)

View File

@ -39,6 +39,8 @@ SERVICE_SOFT_RESET = "soft_reset"
SERVICE_TEST_NODE = "test_node"
SERVICE_TEST_NETWORK = "test_network"
SERVICE_SET_CONFIG_PARAMETER = "set_config_parameter"
SERVICE_SET_NODE_VALUE = "set_node_value"
SERVICE_REFRESH_NODE_VALUE = "refresh_node_value"
SERVICE_PRINT_CONFIG_PARAMETER = "print_config_parameter"
SERVICE_PRINT_NODE = "print_node"
SERVICE_REMOVE_FAILED_NODE = "remove_failed_node"

View File

@ -211,7 +211,8 @@ DISCOVERY_SCHEMAS = [
const.COMMAND_CLASS_SENSOR_MULTILEVEL,
const.COMMAND_CLASS_METER,
const.COMMAND_CLASS_ALARM,
const.COMMAND_CLASS_SENSOR_ALARM],
const.COMMAND_CLASS_SENSOR_ALARM,
const.COMMAND_CLASS_INDICATOR],
const.DISC_GENRE: const.GENRE_USER,
}})},
{const.DISC_COMPONENT: 'switch',

View File

@ -69,6 +69,24 @@ set_config_parameter:
size:
description: (Optional) Set the size of the parameter value. Only needed if no parameters are available.
set_node_value:
description: Set the value for a given value_id on a Z-Wave device.
fields:
node_id:
description: Node id of the device to set the value on (integer).
value_id:
description: Value id of the value to set (integer).
value:
description: Value to set (integer).
refresh_node_value:
description: Refresh the value for a given value_id on a Z-Wave device.
fields:
node_id:
description: Node id of the device to refresh value from (integer).
value_id:
description: Value id of the value to refresh.
set_poll_intensity:
description: Set the polling interval to a nodes value
fields:

View File

@ -1361,6 +1361,53 @@ class TestZWaveServices(unittest.TestCase):
assert node.refresh_info.called
assert len(node.refresh_info.mock_calls) == 1
def test_set_node_value(self):
"""Test zwave set_node_value service."""
value = MockValue(
index=12,
command_class=const.COMMAND_CLASS_INDICATOR,
data=4
)
node = MockNode(node_id=14,
command_classes=[const.COMMAND_CLASS_INDICATOR])
node.values = {12: value}
node.get_values.return_value = node.values
self.zwave_network.nodes = {14: node}
self.hass.services.call('zwave', 'set_node_value', {
const.ATTR_NODE_ID: 14,
const.ATTR_VALUE_ID: 12,
const.ATTR_CONFIG_VALUE: 2,
})
self.hass.block_till_done()
assert self.zwave_network.nodes[14].values[12].data == 2
def test_refresh_node_value(self):
"""Test zwave refresh_node_value service."""
node = MockNode(node_id=14,
command_classes=[const.COMMAND_CLASS_INDICATOR],
network=self.zwave_network)
value = MockValue(
node=node,
index=12,
command_class=const.COMMAND_CLASS_INDICATOR,
data=2
)
value.refresh = MagicMock()
node.values = {12: value}
node.get_values.return_value = node.values
self.zwave_network.nodes = {14: node}
self.hass.services.call('zwave', 'refresh_node_value', {
const.ATTR_NODE_ID: 14,
const.ATTR_VALUE_ID: 12
})
self.hass.block_till_done()
assert value.refresh.called
def test_heal_node(self):
"""Test zwave heal_node service."""
node = MockNode(node_id=19)