mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
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:
parent
03ce1f46f6
commit
aa8f3ad307
@ -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"
|
||||||
|
@ -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."""
|
||||||
|
@ -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.
|
||||||
|
73
tests/components/ozw/test_services.py
Normal file
73
tests/components/ozw/test_services.py
Normal 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
|
Loading…
x
Reference in New Issue
Block a user