Add OZW support for set_config_parameter service (#37523)

* Add support for set_config_parameter service

* Adjusted elif to if

* More if/else cleanup

* More if/else cleanup

* Less nesting

* End loop properly

* Added byte type

* Convert break to return
This commit is contained in:
Chris 2020-07-08 11:59:52 -07:00 committed by GitHub
parent 03ce1f46f6
commit aa8f3ad307
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 189 additions and 0 deletions

View File

@ -25,6 +25,8 @@ PLATFORMS = [
TOPIC_OPENZWAVE = "OpenZWave" TOPIC_OPENZWAVE = "OpenZWave"
# Common Attributes # Common Attributes
ATTR_CONFIG_PARAMETER = "parameter"
ATTR_CONFIG_VALUE = "value"
ATTR_INSTANCE_ID = "instance_id" ATTR_INSTANCE_ID = "instance_id"
ATTR_SECURE = "secure" ATTR_SECURE = "secure"
ATTR_NODE_ID = "node_id" ATTR_NODE_ID = "node_id"
@ -36,6 +38,7 @@ ATTR_SCENE_VALUE_LABEL = "scene_value_label"
# Service specific # Service specific
SERVICE_ADD_NODE = "add_node" SERVICE_ADD_NODE = "add_node"
SERVICE_REMOVE_NODE = "remove_node" SERVICE_REMOVE_NODE = "remove_node"
SERVICE_SET_CONFIG_PARAMETER = "set_config_parameter"
# Home Assistant Events # Home Assistant Events
EVENT_SCENE_ACTIVATED = f"{DOMAIN}.scene_activated" EVENT_SCENE_ACTIVATED = f"{DOMAIN}.scene_activated"

View File

@ -1,10 +1,16 @@
"""Methods and classes related to executing Z-Wave commands and publishing these to hass.""" """Methods and classes related to executing Z-Wave commands and publishing these to hass."""
import logging
from openzwavemqtt.const import CommandClass, ValueType
import voluptuous as vol import voluptuous as vol
from homeassistant.core import callback from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from . import const from . import const
_LOGGER = logging.getLogger(__name__)
class ZWaveServices: class ZWaveServices:
"""Class that holds our services ( Zwave Commands) that should be published to hass.""" """Class that holds our services ( Zwave Commands) that should be published to hass."""
@ -37,6 +43,98 @@ class ZWaveServices:
), ),
) )
self._hass.services.async_register(
const.DOMAIN,
const.SERVICE_SET_CONFIG_PARAMETER,
self.async_set_config_parameter,
schema=vol.Schema(
{
vol.Optional(const.ATTR_INSTANCE_ID, default=1): vol.Coerce(int),
vol.Required(const.ATTR_NODE_ID): vol.Coerce(int),
vol.Required(const.ATTR_CONFIG_PARAMETER): vol.Coerce(int),
vol.Required(const.ATTR_CONFIG_VALUE): vol.Any(
vol.Coerce(int), cv.string
),
}
),
)
@callback
def async_set_config_parameter(self, service):
"""Set a config parameter to a node."""
instance_id = service.data[const.ATTR_INSTANCE_ID]
node_id = service.data[const.ATTR_NODE_ID]
param = service.data[const.ATTR_CONFIG_PARAMETER]
selection = service.data[const.ATTR_CONFIG_VALUE]
payload = None
node = self._manager.get_instance(instance_id).get_node(node_id).values()
for value in node:
if (
value.command_class != CommandClass.CONFIGURATION
or value.index != param
):
continue
if value.type == ValueType.BOOL:
payload = selection == "True"
if value.type == ValueType.LIST:
# accept either string from the list value OR the int value
if isinstance(selection, int):
if selection > value.max or selection < value.min:
_LOGGER.error(
"Value %s out of range for parameter %s (Min: %s Max: %s)",
selection,
param,
value.min,
value.max,
)
return
payload = int(selection)
# iterate list labels to get value
for selected in value.value["List"]:
if selected["Label"] != selection:
continue
payload = int(selected["Value"])
if payload is None:
_LOGGER.error(
"Invalid value %s for parameter %s", selection, param,
)
return
if value.type == ValueType.BUTTON:
# Unsupported at this time
_LOGGER.info("Button type not supported yet")
return
if value.type == ValueType.STRING:
payload = selection
if value.type == ValueType.INT or value.type == ValueType.BYTE:
if selection > value.max or selection < value.min:
_LOGGER.error(
"Value %s out of range for parameter %s (Min: %s Max: %s)",
selection,
param,
value.min,
value.max,
)
return
payload = int(selection)
value.send_value(payload) # send the payload
_LOGGER.info(
"Setting configuration parameter %s on Node %s with value %s",
param,
node_id,
payload,
)
return
@callback @callback
def async_add_node(self, service): def async_add_node(self, service):
"""Enter inclusion mode on the controller.""" """Enter inclusion mode on the controller."""

View File

@ -12,3 +12,18 @@ remove_node:
fields: fields:
instance_id: instance_id:
description: (Optional) The OZW Instance/Controller to use, defaults to 1. description: (Optional) The OZW Instance/Controller to use, defaults to 1.
set_config_parameter:
description: Set a config parameter to a node on the Z-Wave network.
fields:
node_id:
description: Node id of the device to set config parameter to (integer).
example: 10
parameter:
description: Parameter number to set (integer).
example: 8
value:
description: Value to set for parameter. (String value for list and bool parameters, integer for others).
example: 50268673
instance_id:
description: (Optional) The OZW Instance/Controller to use, defaults to 1.

View File

@ -0,0 +1,73 @@
"""Test Z-Wave Services."""
from .common import setup_ozw
async def test_services(hass, lock_data, sent_messages, lock_msg, caplog):
"""Test services on lock."""
await setup_ozw(hass, fixture=lock_data)
# Test set_config_parameter list by label
await hass.services.async_call(
"ozw",
"set_config_parameter",
{"node_id": 10, "parameter": 1, "value": "Disabled"},
blocking=True,
)
assert len(sent_messages) == 1
msg = sent_messages[0]
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
assert msg["payload"] == {"Value": 0, "ValueIDKey": 281475154706452}
# Test set_config_parameter list by index int
await hass.services.async_call(
"ozw",
"set_config_parameter",
{"node_id": 10, "parameter": 1, "value": 0},
blocking=True,
)
assert len(sent_messages) == 2
msg = sent_messages[1]
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
assert msg["payload"] == {"Value": 0, "ValueIDKey": 281475154706452}
# Test set_config_parameter int
await hass.services.async_call(
"ozw",
"set_config_parameter",
{"node_id": 10, "parameter": 6, "value": 0},
blocking=True,
)
assert len(sent_messages) == 3
msg = sent_messages[2]
assert msg["topic"] == "OpenZWave/1/command/setvalue/"
assert msg["payload"] == {"Value": 0, "ValueIDKey": 1688850038259731}
# Test set_config_parameter invalid list int
await hass.services.async_call(
"ozw",
"set_config_parameter",
{"node_id": 10, "parameter": 1, "value": 12},
blocking=True,
)
assert len(sent_messages) == 3
assert "Value 12 out of range for parameter 1" in caplog.text
# Test set_config_parameter invalid list string
await hass.services.async_call(
"ozw",
"set_config_parameter",
{"node_id": 10, "parameter": 1, "value": "Blah"},
blocking=True,
)
assert len(sent_messages) == 3
assert "Invalid value Blah for parameter 1" in caplog.text
# Test set_config_parameter int out of range
await hass.services.async_call(
"ozw",
"set_config_parameter",
{"node_id": 10, "parameter": 6, "value": 2147483657},
blocking=True,
)
assert len(sent_messages) == 3
assert "Value 12 out of range for parameter 1" in caplog.text