Add zwave_js.reset_meter service (#53390)
* Add zwave_js.meter_reset service * fix log statement * Add endpoint attribute to service call and rename service * Make service an entity service * remove endpoint from service descriptionpull/53647/head
parent
a8536e3ce5
commit
e1c6ccb198
|
@ -49,24 +49,24 @@ ATTR_NODE = "node"
|
|||
ATTR_ZWAVE_VALUE = "zwave_value"
|
||||
|
||||
# service constants
|
||||
ATTR_NODES = "nodes"
|
||||
|
||||
SERVICE_SET_VALUE = "set_value"
|
||||
SERVICE_RESET_METER = "reset_meter"
|
||||
SERVICE_MULTICAST_SET_VALUE = "multicast_set_value"
|
||||
SERVICE_PING = "ping"
|
||||
SERVICE_REFRESH_VALUE = "refresh_value"
|
||||
SERVICE_SET_CONFIG_PARAMETER = "set_config_parameter"
|
||||
SERVICE_BULK_SET_PARTIAL_CONFIG_PARAMETERS = "bulk_set_partial_config_parameters"
|
||||
|
||||
ATTR_NODES = "nodes"
|
||||
# config parameter
|
||||
ATTR_CONFIG_PARAMETER = "parameter"
|
||||
ATTR_CONFIG_PARAMETER_BITMASK = "bitmask"
|
||||
ATTR_CONFIG_VALUE = "value"
|
||||
|
||||
SERVICE_REFRESH_VALUE = "refresh_value"
|
||||
|
||||
# refresh value
|
||||
ATTR_REFRESH_ALL_VALUES = "refresh_all_values"
|
||||
|
||||
SERVICE_SET_VALUE = "set_value"
|
||||
SERVICE_MULTICAST_SET_VALUE = "multicast_set_value"
|
||||
|
||||
# multicast
|
||||
ATTR_BROADCAST = "broadcast"
|
||||
|
||||
SERVICE_PING = "ping"
|
||||
# meter reset
|
||||
ATTR_METER_TYPE = "meter_type"
|
||||
|
||||
ADDON_SLUG = "core_zwave_js"
|
||||
|
|
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
|||
import logging
|
||||
from typing import cast
|
||||
|
||||
import voluptuous as vol
|
||||
from zwave_js_server.client import Client as ZwaveClient
|
||||
from zwave_js_server.const import CommandClass, ConfigurationValueType
|
||||
from zwave_js_server.model.node import Node as ZwaveNode
|
||||
|
@ -26,10 +27,11 @@ from homeassistant.const import (
|
|||
TEMP_FAHRENHEIT,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import entity_platform
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import DATA_CLIENT, DOMAIN
|
||||
from .const import ATTR_METER_TYPE, ATTR_VALUE, DATA_CLIENT, DOMAIN, SERVICE_RESET_METER
|
||||
from .discovery import ZwaveDiscoveryInfo
|
||||
from .entity import ZWaveBaseEntity
|
||||
from .helpers import get_device_id
|
||||
|
@ -89,6 +91,16 @@ async def async_setup_entry(
|
|||
)
|
||||
)
|
||||
|
||||
platform = entity_platform.async_get_current_platform()
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_RESET_METER,
|
||||
{
|
||||
vol.Optional(ATTR_METER_TYPE): vol.Coerce(int),
|
||||
vol.Optional(ATTR_VALUE): vol.Coerce(int),
|
||||
},
|
||||
"async_reset_meter",
|
||||
)
|
||||
|
||||
|
||||
class ZwaveSensorBase(ZWaveBaseEntity, SensorEntity):
|
||||
"""Basic Representation of a Z-Wave sensor."""
|
||||
|
@ -218,6 +230,30 @@ class ZWaveNumericSensor(ZwaveSensorBase):
|
|||
|
||||
return str(self.info.primary_value.metadata.unit)
|
||||
|
||||
async def async_reset_meter(
|
||||
self, meter_type: int | None = None, value: int | None = None
|
||||
) -> None:
|
||||
"""Reset meter(s) on device."""
|
||||
node = self.info.node
|
||||
primary_value = self.info.primary_value
|
||||
if primary_value.command_class != CommandClass.METER:
|
||||
raise TypeError("Reset only available for Meter sensors")
|
||||
options = {}
|
||||
if meter_type is not None:
|
||||
options["type"] = meter_type
|
||||
if value is not None:
|
||||
options["targetValue"] = value
|
||||
args = [options] if options else []
|
||||
await node.endpoints[primary_value.endpoint].async_invoke_cc_api(
|
||||
CommandClass.METER, "reset", *args, wait_for_result=False
|
||||
)
|
||||
LOGGER.debug(
|
||||
"Meters on node %s endpoint %s reset with the following options: %s",
|
||||
node,
|
||||
primary_value.endpoint,
|
||||
options,
|
||||
)
|
||||
|
||||
|
||||
class ZWaveListSensor(ZwaveSensorBase):
|
||||
"""Representation of a Z-Wave Numeric sensor with multiple states."""
|
||||
|
|
|
@ -229,3 +229,26 @@ ping:
|
|||
target:
|
||||
entity:
|
||||
integration: zwave_js
|
||||
|
||||
reset_meter:
|
||||
name: Reset meter(s) on a node
|
||||
description: Resets the meter(s) on a node.
|
||||
target:
|
||||
entity:
|
||||
domain: sensor
|
||||
integration: zwave_js
|
||||
fields:
|
||||
meter_type:
|
||||
name: Meter Type
|
||||
description: The type of meter to reset. Not all meters support the ability to pick a meter type to reset.
|
||||
example: 1
|
||||
required: false
|
||||
selector:
|
||||
text:
|
||||
value:
|
||||
name: Target Value
|
||||
description: The value that meter(s) should be reset to. Not all meters support the ability to be reset to a specific value.
|
||||
example: 5
|
||||
required: false
|
||||
selector:
|
||||
text:
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
"""Test the Z-Wave JS sensor platform."""
|
||||
from zwave_js_server.event import Event
|
||||
|
||||
from homeassistant.components.zwave_js.const import (
|
||||
ATTR_METER_TYPE,
|
||||
ATTR_VALUE,
|
||||
DOMAIN,
|
||||
SERVICE_RESET_METER,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
DEVICE_CLASS_POWER,
|
||||
|
@ -131,3 +138,55 @@ async def test_node_status_sensor(hass, lock_id_lock_as_id150, integration):
|
|||
)
|
||||
node.receive_event(event)
|
||||
assert hass.states.get(NODE_STATUS_ENTITY).state == "alive"
|
||||
|
||||
|
||||
async def test_reset_meter(
|
||||
hass,
|
||||
client,
|
||||
aeon_smart_switch_6,
|
||||
integration,
|
||||
):
|
||||
"""Test reset_meter service."""
|
||||
SENSOR = "sensor.smart_switch_6_electric_consumed_v"
|
||||
client.async_send_command.return_value = {}
|
||||
client.async_send_command_no_wait.return_value = {}
|
||||
|
||||
# Test successful meter reset call
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_RESET_METER,
|
||||
{
|
||||
ATTR_ENTITY_ID: SENSOR,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "endpoint.invoke_cc_api"
|
||||
assert args["nodeId"] == aeon_smart_switch_6.node_id
|
||||
assert args["endpoint"] == 0
|
||||
assert args["args"] == []
|
||||
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test successful meter reset call with options
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_RESET_METER,
|
||||
{
|
||||
ATTR_ENTITY_ID: SENSOR,
|
||||
ATTR_METER_TYPE: 1,
|
||||
ATTR_VALUE: 2,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "endpoint.invoke_cc_api"
|
||||
assert args["nodeId"] == aeon_smart_switch_6.node_id
|
||||
assert args["endpoint"] == 0
|
||||
assert args["args"] == [{"type": 1, "targetValue": 2}]
|
||||
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
|
Loading…
Reference in New Issue