Add ZHA metering summation received sensor (#107576)
* Add sensor for exposing Summation Received from Metering cluster * Ruff format * Test updates for new sensor * Update test_sensor.py to support summation_received * Correct report_count for smart meterning and some pylint warning fixes
This commit is contained in:
parent
8fa93f6fe5
commit
af1ba4b22f
6 changed files with 134 additions and 29 deletions
|
@ -5,10 +5,7 @@ from unittest.mock import MagicMock, patch
|
|||
|
||||
import pytest
|
||||
import zigpy.profiles.zha
|
||||
import zigpy.zcl.clusters.general as general
|
||||
import zigpy.zcl.clusters.homeautomation as homeautomation
|
||||
import zigpy.zcl.clusters.measurement as measurement
|
||||
import zigpy.zcl.clusters.smartenergy as smartenergy
|
||||
from zigpy.zcl.clusters import general, homeautomation, measurement, smartenergy
|
||||
|
||||
from homeassistant.components.sensor import SensorDeviceClass
|
||||
from homeassistant.components.zha.core.const import ZHA_CLUSTER_HANDLER_READS_PER_REQ
|
||||
|
@ -70,7 +67,7 @@ def sensor_platform_only():
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
async def elec_measurement_zigpy_dev(hass, zigpy_device_mock):
|
||||
async def elec_measurement_zigpy_dev(hass: HomeAssistant, zigpy_device_mock):
|
||||
"""Electric Measurement zigpy device."""
|
||||
|
||||
zigpy_device = zigpy_device_mock(
|
||||
|
@ -110,19 +107,19 @@ async def elec_measurement_zha_dev(elec_measurement_zigpy_dev, zha_device_joined
|
|||
return zha_dev
|
||||
|
||||
|
||||
async def async_test_humidity(hass, cluster, entity_id):
|
||||
async def async_test_humidity(hass: HomeAssistant, cluster, entity_id):
|
||||
"""Test humidity sensor."""
|
||||
await send_attributes_report(hass, cluster, {1: 1, 0: 1000, 2: 100})
|
||||
assert_state(hass, entity_id, "10.0", PERCENTAGE)
|
||||
|
||||
|
||||
async def async_test_temperature(hass, cluster, entity_id):
|
||||
async def async_test_temperature(hass: HomeAssistant, cluster, entity_id):
|
||||
"""Test temperature sensor."""
|
||||
await send_attributes_report(hass, cluster, {1: 1, 0: 2900, 2: 100})
|
||||
assert_state(hass, entity_id, "29.0", UnitOfTemperature.CELSIUS)
|
||||
|
||||
|
||||
async def async_test_pressure(hass, cluster, entity_id):
|
||||
async def async_test_pressure(hass: HomeAssistant, cluster, entity_id):
|
||||
"""Test pressure sensor."""
|
||||
await send_attributes_report(hass, cluster, {1: 1, 0: 1000, 2: 10000})
|
||||
assert_state(hass, entity_id, "1000", UnitOfPressure.HPA)
|
||||
|
@ -131,7 +128,7 @@ async def async_test_pressure(hass, cluster, entity_id):
|
|||
assert_state(hass, entity_id, "1000", UnitOfPressure.HPA)
|
||||
|
||||
|
||||
async def async_test_illuminance(hass, cluster, entity_id):
|
||||
async def async_test_illuminance(hass: HomeAssistant, cluster, entity_id):
|
||||
"""Test illuminance sensor."""
|
||||
await send_attributes_report(hass, cluster, {1: 1, 0: 10, 2: 20})
|
||||
assert_state(hass, entity_id, "1", LIGHT_LUX)
|
||||
|
@ -143,7 +140,7 @@ async def async_test_illuminance(hass, cluster, entity_id):
|
|||
assert_state(hass, entity_id, "unknown", LIGHT_LUX)
|
||||
|
||||
|
||||
async def async_test_metering(hass, cluster, entity_id):
|
||||
async def async_test_metering(hass: HomeAssistant, cluster, entity_id):
|
||||
"""Test Smart Energy metering sensor."""
|
||||
await send_attributes_report(hass, cluster, {1025: 1, 1024: 12345, 1026: 100})
|
||||
assert_state(hass, entity_id, "12345.0", None)
|
||||
|
@ -164,8 +161,10 @@ async def async_test_metering(hass, cluster, entity_id):
|
|||
assert hass.states.get(entity_id).attributes["status"] in ("<bitmap8.32: 32>", "32")
|
||||
|
||||
|
||||
async def async_test_smart_energy_summation(hass, cluster, entity_id):
|
||||
"""Test SmartEnergy Summation delivered sensro."""
|
||||
async def async_test_smart_energy_summation_delivered(
|
||||
hass: HomeAssistant, cluster, entity_id
|
||||
):
|
||||
"""Test SmartEnergy Summation delivered sensor."""
|
||||
|
||||
await send_attributes_report(
|
||||
hass, cluster, {1025: 1, "current_summ_delivered": 12321, 1026: 100}
|
||||
|
@ -179,7 +178,24 @@ async def async_test_smart_energy_summation(hass, cluster, entity_id):
|
|||
)
|
||||
|
||||
|
||||
async def async_test_electrical_measurement(hass, cluster, entity_id):
|
||||
async def async_test_smart_energy_summation_received(
|
||||
hass: HomeAssistant, cluster, entity_id
|
||||
):
|
||||
"""Test SmartEnergy Summation received sensor."""
|
||||
|
||||
await send_attributes_report(
|
||||
hass, cluster, {1025: 1, "current_summ_received": 12321, 1026: 100}
|
||||
)
|
||||
assert_state(hass, entity_id, "12.321", UnitOfEnergy.KILO_WATT_HOUR)
|
||||
assert hass.states.get(entity_id).attributes["status"] == "NO_ALARMS"
|
||||
assert hass.states.get(entity_id).attributes["device_type"] == "Electric Metering"
|
||||
assert (
|
||||
hass.states.get(entity_id).attributes[ATTR_DEVICE_CLASS]
|
||||
== SensorDeviceClass.ENERGY
|
||||
)
|
||||
|
||||
|
||||
async def async_test_electrical_measurement(hass: HomeAssistant, cluster, entity_id):
|
||||
"""Test electrical measurement sensor."""
|
||||
# update divisor cached value
|
||||
await send_attributes_report(hass, cluster, {"ac_power_divisor": 1})
|
||||
|
@ -201,7 +217,7 @@ async def async_test_electrical_measurement(hass, cluster, entity_id):
|
|||
assert hass.states.get(entity_id).attributes["active_power_max"] == "8.8"
|
||||
|
||||
|
||||
async def async_test_em_apparent_power(hass, cluster, entity_id):
|
||||
async def async_test_em_apparent_power(hass: HomeAssistant, cluster, entity_id):
|
||||
"""Test electrical measurement Apparent Power sensor."""
|
||||
# update divisor cached value
|
||||
await send_attributes_report(hass, cluster, {"ac_power_divisor": 1})
|
||||
|
@ -219,7 +235,7 @@ async def async_test_em_apparent_power(hass, cluster, entity_id):
|
|||
assert_state(hass, entity_id, "9.9", UnitOfApparentPower.VOLT_AMPERE)
|
||||
|
||||
|
||||
async def async_test_em_rms_current(hass, cluster, entity_id):
|
||||
async def async_test_em_rms_current(hass: HomeAssistant, cluster, entity_id):
|
||||
"""Test electrical measurement RMS Current sensor."""
|
||||
|
||||
await send_attributes_report(hass, cluster, {0: 1, 0x0508: 1234, 10: 1000})
|
||||
|
@ -237,7 +253,7 @@ async def async_test_em_rms_current(hass, cluster, entity_id):
|
|||
assert hass.states.get(entity_id).attributes["rms_current_max"] == "8.8"
|
||||
|
||||
|
||||
async def async_test_em_rms_voltage(hass, cluster, entity_id):
|
||||
async def async_test_em_rms_voltage(hass: HomeAssistant, cluster, entity_id):
|
||||
"""Test electrical measurement RMS Voltage sensor."""
|
||||
|
||||
await send_attributes_report(hass, cluster, {0: 1, 0x0505: 1234, 10: 1000})
|
||||
|
@ -255,7 +271,7 @@ async def async_test_em_rms_voltage(hass, cluster, entity_id):
|
|||
assert hass.states.get(entity_id).attributes["rms_voltage_max"] == "8.9"
|
||||
|
||||
|
||||
async def async_test_powerconfiguration(hass, cluster, entity_id):
|
||||
async def async_test_powerconfiguration(hass: HomeAssistant, cluster, entity_id):
|
||||
"""Test powerconfiguration/battery sensor."""
|
||||
await send_attributes_report(hass, cluster, {33: 98})
|
||||
assert_state(hass, entity_id, "49", "%")
|
||||
|
@ -266,7 +282,7 @@ async def async_test_powerconfiguration(hass, cluster, entity_id):
|
|||
assert hass.states.get(entity_id).attributes["battery_voltage"] == 2.0
|
||||
|
||||
|
||||
async def async_test_powerconfiguration2(hass, cluster, entity_id):
|
||||
async def async_test_powerconfiguration2(hass: HomeAssistant, cluster, entity_id):
|
||||
"""Test powerconfiguration/battery sensor."""
|
||||
await send_attributes_report(hass, cluster, {33: -1})
|
||||
assert_state(hass, entity_id, STATE_UNKNOWN, "%")
|
||||
|
@ -278,7 +294,7 @@ async def async_test_powerconfiguration2(hass, cluster, entity_id):
|
|||
assert_state(hass, entity_id, "49", "%")
|
||||
|
||||
|
||||
async def async_test_device_temperature(hass, cluster, entity_id):
|
||||
async def async_test_device_temperature(hass: HomeAssistant, cluster, entity_id):
|
||||
"""Test temperature sensor."""
|
||||
await send_attributes_report(hass, cluster, {0: 2900})
|
||||
assert_state(hass, entity_id, "29.0", UnitOfTemperature.CELSIUS)
|
||||
|
@ -330,7 +346,7 @@ async def async_test_device_temperature(hass, cluster, entity_id):
|
|||
smartenergy.Metering.cluster_id,
|
||||
"instantaneous_demand",
|
||||
async_test_metering,
|
||||
9,
|
||||
10,
|
||||
{
|
||||
"demand_formatting": 0xF9,
|
||||
"divisor": 1,
|
||||
|
@ -338,13 +354,13 @@ async def async_test_device_temperature(hass, cluster, entity_id):
|
|||
"multiplier": 1,
|
||||
"status": 0x00,
|
||||
},
|
||||
{"current_summ_delivered"},
|
||||
{"current_summ_delivered", "current_summ_received"},
|
||||
),
|
||||
(
|
||||
smartenergy.Metering.cluster_id,
|
||||
"summation_delivered",
|
||||
async_test_smart_energy_summation,
|
||||
9,
|
||||
async_test_smart_energy_summation_delivered,
|
||||
10,
|
||||
{
|
||||
"demand_formatting": 0xF9,
|
||||
"divisor": 1000,
|
||||
|
@ -354,7 +370,23 @@ async def async_test_device_temperature(hass, cluster, entity_id):
|
|||
"summation_formatting": 0b1_0111_010,
|
||||
"unit_of_measure": 0x00,
|
||||
},
|
||||
{"instaneneous_demand"},
|
||||
{"instaneneous_demand", "current_summ_received"},
|
||||
),
|
||||
(
|
||||
smartenergy.Metering.cluster_id,
|
||||
"summation_received",
|
||||
async_test_smart_energy_summation_received,
|
||||
10,
|
||||
{
|
||||
"demand_formatting": 0xF9,
|
||||
"divisor": 1000,
|
||||
"metering_device_type": 0x00,
|
||||
"multiplier": 1,
|
||||
"status": 0x00,
|
||||
"summation_formatting": 0b1_0111_010,
|
||||
"unit_of_measure": 0x00,
|
||||
},
|
||||
{"instaneneous_demand", "current_summ_delivered"},
|
||||
),
|
||||
(
|
||||
homeautomation.ElectricalMeasurement.cluster_id,
|
||||
|
@ -476,7 +508,7 @@ async def test_sensor(
|
|||
await async_test_rejoin(hass, zigpy_device, [cluster], (report_count,))
|
||||
|
||||
|
||||
def assert_state(hass, entity_id, state, unit_of_measurement):
|
||||
def assert_state(hass: HomeAssistant, entity_id, state, unit_of_measurement):
|
||||
"""Check that the state is what is expected.
|
||||
|
||||
This is used to ensure that the logic in each sensor class handled the
|
||||
|
@ -488,7 +520,7 @@ def assert_state(hass, entity_id, state, unit_of_measurement):
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def hass_ms(hass):
|
||||
def hass_ms(hass: HomeAssistant):
|
||||
"""Hass instance with measurement system."""
|
||||
|
||||
async def _hass_ms(meas_sys):
|
||||
|
@ -710,6 +742,7 @@ async def test_electrical_measurement_init(
|
|||
},
|
||||
{
|
||||
"summation_delivered",
|
||||
"summation_received",
|
||||
},
|
||||
{
|
||||
"instantaneous_demand",
|
||||
|
@ -717,19 +750,21 @@ async def test_electrical_measurement_init(
|
|||
),
|
||||
(
|
||||
smartenergy.Metering.cluster_id,
|
||||
{"instantaneous_demand", "current_summ_delivered"},
|
||||
{"instantaneous_demand", "current_summ_delivered", "current_summ_received"},
|
||||
{},
|
||||
{
|
||||
"summation_delivered",
|
||||
"instantaneous_demand",
|
||||
"summation_delivered",
|
||||
"summation_received",
|
||||
},
|
||||
),
|
||||
(
|
||||
smartenergy.Metering.cluster_id,
|
||||
{},
|
||||
{
|
||||
"summation_delivered",
|
||||
"instantaneous_demand",
|
||||
"summation_delivered",
|
||||
"summation_received",
|
||||
},
|
||||
{},
|
||||
),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue