Add OZW node config parameters websocket commands (#40527)
* add websocket commands to retrieve and set config parameters for a node * move set_config_parameter into generic function and refactor service and WS API * add payload to return to make service call behave the same way it did before * create response class * update error message to pass tests * move things a bit to reduce LOC * add tests * handle logging errors better and make new response class more generic to prepare for lock user code work * remove unused function parameter * invert check * add additional error checking * refactor a bit to remove repeat code * revert log msg change * one more refactor to create generic get_config_parameters function * change if logic for consistency * fix test * add support to provide bool value in set_config_parameter service call * standardize parameter names on service call * add test coverage * fix tests and message sending * remove unnecessary logging import * fix one test to get missing coverage * update per martin and kpines reviews * remove false assertion * string line length * add support for Decimal config param, remove node instance ID as input, and move helper functions to node.py * cast Decimal appropriately * revert change to support Decimal for config params since they are not supported as a config param type * revert to using error arguments to make next PR for WS lock commands easier * switch to class method and add guard for list Value not being a number * update logic to use new openzwavemqtt util methods * add support for bitsets * use parent exception class * bump openzwavemqtt version, remove node.py from .coveragerc and put file references in the right place * add comment * improve config validation * remove bitset support from config validation * re-add bitset support with some additional tests * move send_result out of try block
This commit is contained in:
parent
c777647233
commit
6db4075a23
8 changed files with 357 additions and 104 deletions
|
@ -1,7 +1,8 @@
|
|||
"""Methods and classes related to executing Z-Wave commands and publishing these to hass."""
|
||||
import logging
|
||||
|
||||
from openzwavemqtt.const import CommandClass, ValueType
|
||||
from openzwavemqtt.const import ATTR_LABEL, ATTR_POSITION, ATTR_VALUE
|
||||
from openzwavemqtt.util.node import get_node_from_manager, set_config_parameter
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.core import callback
|
||||
|
@ -53,7 +54,24 @@ class ZWaveServices:
|
|||
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
|
||||
vol.All(
|
||||
cv.ensure_list,
|
||||
[
|
||||
vol.All(
|
||||
{
|
||||
vol.Exclusive(ATTR_LABEL, "bit"): cv.string,
|
||||
vol.Exclusive(ATTR_POSITION, "bit"): vol.Coerce(
|
||||
int
|
||||
),
|
||||
vol.Required(ATTR_VALUE): bool,
|
||||
},
|
||||
cv.has_at_least_one_key(ATTR_LABEL, ATTR_POSITION),
|
||||
)
|
||||
],
|
||||
),
|
||||
vol.Coerce(int),
|
||||
bool,
|
||||
cv.string,
|
||||
),
|
||||
}
|
||||
),
|
||||
|
@ -66,57 +84,12 @@ class ZWaveServices:
|
|||
node_id = service.data[const.ATTR_NODE_ID]
|
||||
param = service.data[const.ATTR_CONFIG_PARAMETER]
|
||||
selection = service.data[const.ATTR_CONFIG_VALUE]
|
||||
payload = None
|
||||
|
||||
value = (
|
||||
self._manager.get_instance(instance_id)
|
||||
.get_node(node_id)
|
||||
.get_value(CommandClass.CONFIGURATION, param)
|
||||
)
|
||||
# These function calls may raise an exception but that's ok because
|
||||
# the exception will show in the UI to the user
|
||||
node = get_node_from_manager(self._manager, instance_id, node_id)
|
||||
payload = set_config_parameter(node, param, selection)
|
||||
|
||||
if value.type == ValueType.BOOL:
|
||||
payload = selection == "True"
|
||||
|
||||
if value.type == ValueType.LIST:
|
||||
# accept either string from the list value OR the int value
|
||||
for selected in value.value["List"]:
|
||||
if selection not in (selected["Label"], selected["Value"]):
|
||||
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
|
||||
or value.type == ValueType.SHORT
|
||||
):
|
||||
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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue