mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 12:47:08 +00:00
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 description
This commit is contained in:
parent
a8536e3ce5
commit
e1c6ccb198
@ -49,24 +49,24 @@ ATTR_NODE = "node"
|
|||||||
ATTR_ZWAVE_VALUE = "zwave_value"
|
ATTR_ZWAVE_VALUE = "zwave_value"
|
||||||
|
|
||||||
# service constants
|
# 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_SET_CONFIG_PARAMETER = "set_config_parameter"
|
||||||
SERVICE_BULK_SET_PARTIAL_CONFIG_PARAMETERS = "bulk_set_partial_config_parameters"
|
SERVICE_BULK_SET_PARTIAL_CONFIG_PARAMETERS = "bulk_set_partial_config_parameters"
|
||||||
|
|
||||||
|
ATTR_NODES = "nodes"
|
||||||
|
# config parameter
|
||||||
ATTR_CONFIG_PARAMETER = "parameter"
|
ATTR_CONFIG_PARAMETER = "parameter"
|
||||||
ATTR_CONFIG_PARAMETER_BITMASK = "bitmask"
|
ATTR_CONFIG_PARAMETER_BITMASK = "bitmask"
|
||||||
ATTR_CONFIG_VALUE = "value"
|
ATTR_CONFIG_VALUE = "value"
|
||||||
|
# refresh value
|
||||||
SERVICE_REFRESH_VALUE = "refresh_value"
|
|
||||||
|
|
||||||
ATTR_REFRESH_ALL_VALUES = "refresh_all_values"
|
ATTR_REFRESH_ALL_VALUES = "refresh_all_values"
|
||||||
|
# multicast
|
||||||
SERVICE_SET_VALUE = "set_value"
|
|
||||||
SERVICE_MULTICAST_SET_VALUE = "multicast_set_value"
|
|
||||||
|
|
||||||
ATTR_BROADCAST = "broadcast"
|
ATTR_BROADCAST = "broadcast"
|
||||||
|
# meter reset
|
||||||
SERVICE_PING = "ping"
|
ATTR_METER_TYPE = "meter_type"
|
||||||
|
|
||||||
ADDON_SLUG = "core_zwave_js"
|
ADDON_SLUG = "core_zwave_js"
|
||||||
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
|||||||
import logging
|
import logging
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
|
import voluptuous as vol
|
||||||
from zwave_js_server.client import Client as ZwaveClient
|
from zwave_js_server.client import Client as ZwaveClient
|
||||||
from zwave_js_server.const import CommandClass, ConfigurationValueType
|
from zwave_js_server.const import CommandClass, ConfigurationValueType
|
||||||
from zwave_js_server.model.node import Node as ZwaveNode
|
from zwave_js_server.model.node import Node as ZwaveNode
|
||||||
@ -26,10 +27,11 @@ from homeassistant.const import (
|
|||||||
TEMP_FAHRENHEIT,
|
TEMP_FAHRENHEIT,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.helpers import entity_platform
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
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 .discovery import ZwaveDiscoveryInfo
|
||||||
from .entity import ZWaveBaseEntity
|
from .entity import ZWaveBaseEntity
|
||||||
from .helpers import get_device_id
|
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):
|
class ZwaveSensorBase(ZWaveBaseEntity, SensorEntity):
|
||||||
"""Basic Representation of a Z-Wave sensor."""
|
"""Basic Representation of a Z-Wave sensor."""
|
||||||
@ -218,6 +230,30 @@ class ZWaveNumericSensor(ZwaveSensorBase):
|
|||||||
|
|
||||||
return str(self.info.primary_value.metadata.unit)
|
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):
|
class ZWaveListSensor(ZwaveSensorBase):
|
||||||
"""Representation of a Z-Wave Numeric sensor with multiple states."""
|
"""Representation of a Z-Wave Numeric sensor with multiple states."""
|
||||||
|
@ -229,3 +229,26 @@ ping:
|
|||||||
target:
|
target:
|
||||||
entity:
|
entity:
|
||||||
integration: zwave_js
|
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."""
|
"""Test the Z-Wave JS sensor platform."""
|
||||||
from zwave_js_server.event import Event
|
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 (
|
from homeassistant.const import (
|
||||||
|
ATTR_ENTITY_ID,
|
||||||
DEVICE_CLASS_ENERGY,
|
DEVICE_CLASS_ENERGY,
|
||||||
DEVICE_CLASS_HUMIDITY,
|
DEVICE_CLASS_HUMIDITY,
|
||||||
DEVICE_CLASS_POWER,
|
DEVICE_CLASS_POWER,
|
||||||
@ -131,3 +138,55 @@ async def test_node_status_sensor(hass, lock_id_lock_as_id150, integration):
|
|||||||
)
|
)
|
||||||
node.receive_event(event)
|
node.receive_event(event)
|
||||||
assert hass.states.get(NODE_STATUS_ENTITY).state == "alive"
|
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…
x
Reference in New Issue
Block a user