Add pulse counter sensors for Shelly (#110248)

* Add pulse counter sensors to Shelly

* Add a unit for the pulse counter

* Fix removal condition

* xtotal key is not present in the payload if it has not been configured

* Update test

---------

Co-authored-by: Maciej Bieniek <478555+bieniu@users.noreply.github.com>
pull/110346/head
Maciej Bieniek 2024-02-12 09:42:38 +01:00 committed by GitHub
parent 5528ae9707
commit 4f277b9509
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 94 additions and 1 deletions

View File

@ -963,6 +963,25 @@ RPC_SENSORS: Final = {
sub_key="xpercent",
name="Analog value",
),
"pulse_counter": RpcSensorDescription(
key="input",
sub_key="counts",
name="Pulse counter",
native_unit_of_measurement="pulse",
state_class=SensorStateClass.TOTAL,
value=lambda status, _: status["total"],
removal_condition=lambda config, _status, key: (config[key]["enable"] is False),
),
"counter_value": RpcSensorDescription(
key="input",
sub_key="counts",
name="Counter value",
value=lambda status, _: status["xtotal"],
removal_condition=lambda config, status, key: (
config[key]["enable"] is False
or status[key]["counts"].get("xtotal") is None
),
),
}

View File

@ -167,6 +167,12 @@ MOCK_BLOCKS = [
MOCK_CONFIG = {
"input:0": {"id": 0, "name": "Test name input 0", "type": "button"},
"input:2": {
"id": 2,
"name": "Gas",
"type": "count",
"enable": True,
},
"light:0": {"name": "test light_0"},
"switch:0": {"name": "test switch_0"},
"cover:0": {"name": "test cover_0"},
@ -220,6 +226,7 @@ MOCK_STATUS_COAP = {
MOCK_STATUS_RPC = {
"switch:0": {"output": True},
"input:0": {"id": 0, "state": None, "xpercent": 8.9},
"input:2": {"id": 2, "counts": {"total": 56174, "xtotal": 561.74}},
"light:0": {"output": True, "brightness": 53.0},
"cloud": {"connected": False},
"cover:0": {

View File

@ -1,4 +1,7 @@
"""Tests for Shelly sensor platform."""
from copy import deepcopy
from unittest.mock import Mock
from freezegun.api import FrozenDateTimeFactory
import pytest
@ -23,7 +26,7 @@ from homeassistant.const import (
UnitOfEnergy,
)
from homeassistant.core import HomeAssistant, State
from homeassistant.helpers.entity_registry import async_get
from homeassistant.helpers.entity_registry import EntityRegistry, async_get
from homeassistant.setup import async_setup_component
from . import (
@ -608,3 +611,67 @@ async def test_rpc_analog_input_xpercent_sensor(
entry = entity_registry.async_get(entity_id)
assert entry
assert entry.unique_id == "123456789ABC-input:0-analoginput_xpercent"
async def test_rpc_pulse_counter_sensors(
hass: HomeAssistant,
mock_rpc_device: Mock,
entity_registry: EntityRegistry,
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Test RPC counter sensor."""
await init_integration(hass, 2)
entity_id = f"{SENSOR_DOMAIN}.gas_pulse_counter"
state = hass.states.get(entity_id)
assert state.state == "56174"
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "pulse"
assert state.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.TOTAL
entry = entity_registry.async_get(entity_id)
assert entry
assert entry.unique_id == "123456789ABC-input:2-pulse_counter"
entity_id = f"{SENSOR_DOMAIN}.gas_counter_value"
assert hass.states.get(entity_id).state == "561.74"
entry = entity_registry.async_get(entity_id)
assert entry
assert entry.unique_id == "123456789ABC-input:2-counter_value"
async def test_rpc_disabled_pulse_counter_sensors(
hass: HomeAssistant, mock_rpc_device: Mock, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test RPC disabled counter sensor."""
new_config = deepcopy(mock_rpc_device.config)
new_config["input:2"]["enable"] = False
monkeypatch.setattr(mock_rpc_device, "config", new_config)
await init_integration(hass, 2)
entity_id = f"{SENSOR_DOMAIN}.gas_pulse_counter"
assert hass.states.get(entity_id) is None
entity_id = f"{SENSOR_DOMAIN}.gas_counter_value"
assert hass.states.get(entity_id) is None
async def test_rpc_disabled_xtotal_counter(
hass: HomeAssistant, mock_rpc_device: Mock, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Test RPC disabled xtotal counter."""
mutate_rpc_device_status(
monkeypatch,
mock_rpc_device,
"input:2",
"counts",
{"total": 20635},
)
await init_integration(hass, 2)
entity_id = f"{SENSOR_DOMAIN}.gas_pulse_counter"
assert hass.states.get(entity_id).state == "20635"
entity_id = f"{SENSOR_DOMAIN}.gas_counter_value"
assert hass.states.get(entity_id) is None