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"
# Common Attributes
ATTR_CONFIG_PARAMETER = "parameter"
ATTR_CONFIG_VALUE = "value"
ATTR_INSTANCE_ID = "instance_id"
ATTR_SECURE = "secure"
ATTR_NODE_ID = "node_id"
@ -36,6 +38,7 @@ ATTR_SCENE_VALUE_LABEL = "scene_value_label"
# Service specific
SERVICE_ADD_NODE = "add_node"
SERVICE_REMOVE_NODE = "remove_node"
SERVICE_SET_CONFIG_PARAMETER = "set_config_parameter"
# Home Assistant Events
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."""
import logging
from openzwavemqtt.const import CommandClass, ValueType
import voluptuous as vol
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from . import const
_LOGGER = logging.getLogger(__name__)
class ZWaveServices:
"""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
def async_add_node(self, service):
"""Enter inclusion mode on the controller."""

View file

@ -12,3 +12,18 @@ remove_node:
fields:
instance_id:
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