core/homeassistant/components/ozw/services.py

135 lines
5.0 KiB
Python
Raw Normal View History

2020-05-03 00:54:16 +00:00
"""Methods and classes related to executing Z-Wave commands and publishing these to hass."""
import logging
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
2020-10-05 19:47:28 +00:00
from openzwavemqtt.const import ATTR_LABEL, ATTR_POSITION, ATTR_VALUE
from openzwavemqtt.util.node import get_node_from_manager, set_config_parameter
2020-05-03 00:54:16 +00:00
import voluptuous as vol
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
2020-05-03 00:54:16 +00:00
from . import const
_LOGGER = logging.getLogger(__name__)
2020-05-03 00:54:16 +00:00
class ZWaveServices:
"""Class that holds our services ( Zwave Commands) that should be published to hass."""
def __init__(self, hass, manager):
"""Initialize with both hass and ozwmanager objects."""
self._hass = hass
self._manager = manager
@callback
def async_register(self):
"""Register all our services."""
self._hass.services.async_register(
const.DOMAIN,
const.SERVICE_ADD_NODE,
self.async_add_node,
schema=vol.Schema(
{
vol.Optional(const.ATTR_INSTANCE_ID, default=1): vol.Coerce(int),
vol.Optional(const.ATTR_SECURE, default=False): vol.Coerce(bool),
}
),
)
self._hass.services.async_register(
const.DOMAIN,
const.SERVICE_REMOVE_NODE,
self.async_remove_node,
schema=vol.Schema(
{vol.Optional(const.ATTR_INSTANCE_ID, default=1): vol.Coerce(int)}
),
)
self._hass.services.async_register(
const.DOMAIN,
const.SERVICE_CANCEL_COMMAND,
self.async_cancel_command,
schema=vol.Schema(
{vol.Optional(const.ATTR_INSTANCE_ID, default=1): vol.Coerce(int)}
),
)
2020-05-03 00:54:16 +00:00
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(
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
2020-10-05 19:47:28 +00:00
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,
),
}
),
)
@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]
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
2020-10-05 19:47:28 +00:00
# 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)
_LOGGER.info(
"Setting configuration parameter %s on Node %s with value %s",
param,
node_id,
payload,
)
2020-05-03 00:54:16 +00:00
@callback
def async_add_node(self, service):
"""Enter inclusion mode on the controller."""
instance_id = service.data[const.ATTR_INSTANCE_ID]
secure = service.data[const.ATTR_SECURE]
instance = self._manager.get_instance(instance_id)
if instance is None:
raise ValueError(f"No OpenZWave Instance with ID {instance_id}")
2020-05-03 00:54:16 +00:00
instance.add_node(secure)
@callback
def async_remove_node(self, service):
"""Enter exclusion mode on the controller."""
instance_id = service.data[const.ATTR_INSTANCE_ID]
instance = self._manager.get_instance(instance_id)
if instance is None:
raise ValueError(f"No OpenZWave Instance with ID {instance_id}")
2020-05-03 00:54:16 +00:00
instance.remove_node()
@callback
def async_cancel_command(self, service):
"""Tell the controller to cancel an add or remove command."""
instance_id = service.data[const.ATTR_INSTANCE_ID]
instance = self._manager.get_instance(instance_id)
if instance is None:
raise ValueError(f"No OpenZWave Instance with ID {instance_id}")
instance.cancel_controller_command()