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:
Raman Gupta 2020-10-05 15:47:28 -04:00 committed by GitHub
parent c777647233
commit 6db4075a23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 357 additions and 104 deletions

View file

@ -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,