Add tier summation delivered for Lixee Zlinky TIC (#82602)
* Add tier summation delivered for zlinky * Improve name case * Add other tiers and register tier * Fix smartenergy sensor update * Account for new reporting configuration in unit tests * Use cluster ID attributes instead of hardcoding the values * Use tier names instead of the numeric constants for formatter * Revert active register tier delivered * Fix tests Co-authored-by: puddly <32534428+puddly@users.noreply.github.com>
This commit is contained in:
parent
83591704b5
commit
c3e27f6812
4 changed files with 186 additions and 43 deletions
|
@ -68,6 +68,24 @@ class Metering(ZigbeeChannel):
|
|||
REPORT_CONFIG = (
|
||||
AttrReportConfig(attr="instantaneous_demand", config=REPORT_CONFIG_OP),
|
||||
AttrReportConfig(attr="current_summ_delivered", config=REPORT_CONFIG_DEFAULT),
|
||||
AttrReportConfig(
|
||||
attr="current_tier1_summ_delivered", config=REPORT_CONFIG_DEFAULT
|
||||
),
|
||||
AttrReportConfig(
|
||||
attr="current_tier2_summ_delivered", config=REPORT_CONFIG_DEFAULT
|
||||
),
|
||||
AttrReportConfig(
|
||||
attr="current_tier3_summ_delivered", config=REPORT_CONFIG_DEFAULT
|
||||
),
|
||||
AttrReportConfig(
|
||||
attr="current_tier4_summ_delivered", config=REPORT_CONFIG_DEFAULT
|
||||
),
|
||||
AttrReportConfig(
|
||||
attr="current_tier5_summ_delivered", config=REPORT_CONFIG_DEFAULT
|
||||
),
|
||||
AttrReportConfig(
|
||||
attr="current_tier6_summ_delivered", config=REPORT_CONFIG_DEFAULT
|
||||
),
|
||||
AttrReportConfig(attr="status", config=REPORT_CONFIG_ASAP),
|
||||
)
|
||||
ZCL_INIT_ATTRS = {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Sensors on Zigbee Home Automation networks."""
|
||||
from __future__ import annotations
|
||||
|
||||
import enum
|
||||
import functools
|
||||
import numbers
|
||||
from typing import TYPE_CHECKING, Any, TypeVar
|
||||
|
@ -174,7 +175,7 @@ class Sensor(ZhaEntity, SensorEntity):
|
|||
"""Handle state update from channel."""
|
||||
self.async_write_ha_state()
|
||||
|
||||
def formatter(self, value: int) -> int | float | None:
|
||||
def formatter(self, value: int | enum.IntEnum) -> int | float | str | None:
|
||||
"""Numeric pass-through formatter."""
|
||||
if self._decimals > 0:
|
||||
return round(
|
||||
|
@ -495,7 +496,7 @@ class SmartEnergySummation(SmartEnergyMetering, id_suffix="summation_delivered")
|
|||
|
||||
@MULTI_MATCH(
|
||||
channel_names=CHANNEL_SMARTENERGY_METERING,
|
||||
models={"TS011F"},
|
||||
models={"TS011F", "ZLinky_TIC"},
|
||||
stop_on_match_group=CHANNEL_SMARTENERGY_METERING,
|
||||
)
|
||||
class PolledSmartEnergySummation(SmartEnergySummation):
|
||||
|
@ -510,6 +511,84 @@ class PolledSmartEnergySummation(SmartEnergySummation):
|
|||
await self._channel.async_force_update()
|
||||
|
||||
|
||||
@MULTI_MATCH(
|
||||
channel_names=CHANNEL_SMARTENERGY_METERING,
|
||||
models={"ZLinky_TIC"},
|
||||
)
|
||||
class Tier1SmartEnergySummation(
|
||||
SmartEnergySummation, id_suffix="tier1_summation_delivered"
|
||||
):
|
||||
"""Tier 1 Smart Energy Metering summation sensor."""
|
||||
|
||||
SENSOR_ATTR: int | str = "current_tier1_summ_delivered"
|
||||
_attr_name: str = "Tier 1 summation delivered"
|
||||
|
||||
|
||||
@MULTI_MATCH(
|
||||
channel_names=CHANNEL_SMARTENERGY_METERING,
|
||||
models={"ZLinky_TIC"},
|
||||
)
|
||||
class Tier2SmartEnergySummation(
|
||||
SmartEnergySummation, id_suffix="tier2_summation_delivered"
|
||||
):
|
||||
"""Tier 2 Smart Energy Metering summation sensor."""
|
||||
|
||||
SENSOR_ATTR: int | str = "current_tier2_summ_delivered"
|
||||
_attr_name: str = "Tier 2 summation delivered"
|
||||
|
||||
|
||||
@MULTI_MATCH(
|
||||
channel_names=CHANNEL_SMARTENERGY_METERING,
|
||||
models={"ZLinky_TIC"},
|
||||
)
|
||||
class Tier3SmartEnergySummation(
|
||||
SmartEnergySummation, id_suffix="tier3_summation_delivered"
|
||||
):
|
||||
"""Tier 3 Smart Energy Metering summation sensor."""
|
||||
|
||||
SENSOR_ATTR: int | str = "current_tier3_summ_delivered"
|
||||
_attr_name: str = "Tier 3 summation delivered"
|
||||
|
||||
|
||||
@MULTI_MATCH(
|
||||
channel_names=CHANNEL_SMARTENERGY_METERING,
|
||||
models={"ZLinky_TIC"},
|
||||
)
|
||||
class Tier4SmartEnergySummation(
|
||||
SmartEnergySummation, id_suffix="tier4_summation_delivered"
|
||||
):
|
||||
"""Tier 4 Smart Energy Metering summation sensor."""
|
||||
|
||||
SENSOR_ATTR: int | str = "current_tier4_summ_delivered"
|
||||
_attr_name: str = "Tier 4 summation delivered"
|
||||
|
||||
|
||||
@MULTI_MATCH(
|
||||
channel_names=CHANNEL_SMARTENERGY_METERING,
|
||||
models={"ZLinky_TIC"},
|
||||
)
|
||||
class Tier5SmartEnergySummation(
|
||||
SmartEnergySummation, id_suffix="tier5_summation_delivered"
|
||||
):
|
||||
"""Tier 5 Smart Energy Metering summation sensor."""
|
||||
|
||||
SENSOR_ATTR: int | str = "current_tier5_summ_delivered"
|
||||
_attr_name: str = "Tier 5 summation delivered"
|
||||
|
||||
|
||||
@MULTI_MATCH(
|
||||
channel_names=CHANNEL_SMARTENERGY_METERING,
|
||||
models={"ZLinky_TIC"},
|
||||
)
|
||||
class Tier6SmartEnergySummation(
|
||||
SmartEnergySummation, id_suffix="tier6_summation_delivered"
|
||||
):
|
||||
"""Tier 6 Smart Energy Metering summation sensor."""
|
||||
|
||||
SENSOR_ATTR: int | str = "current_tier6_summ_delivered"
|
||||
_attr_name: str = "Tier 6 summation delivered"
|
||||
|
||||
|
||||
@MULTI_MATCH(channel_names=CHANNEL_PRESSURE)
|
||||
class Pressure(Sensor):
|
||||
"""Pressure sensor."""
|
||||
|
|
|
@ -106,35 +106,43 @@ async def poll_control_device(zha_device_restored, zigpy_device_mock):
|
|||
@pytest.mark.parametrize(
|
||||
"cluster_id, bind_count, attrs",
|
||||
[
|
||||
(0x0000, 0, {}),
|
||||
(0x0001, 1, {"battery_voltage", "battery_percentage_remaining"}),
|
||||
(0x0002, 1, {"current_temperature"}),
|
||||
(0x0003, 0, {}),
|
||||
(0x0004, 0, {}),
|
||||
(0x0005, 1, {}),
|
||||
(0x0006, 1, {"on_off"}),
|
||||
(0x0007, 1, {}),
|
||||
(0x0008, 1, {"current_level"}),
|
||||
(0x0009, 1, {}),
|
||||
(0x000C, 1, {"present_value"}),
|
||||
(0x000D, 1, {"present_value"}),
|
||||
(0x000E, 1, {"present_value"}),
|
||||
(0x000D, 1, {"present_value"}),
|
||||
(0x0010, 1, {"present_value"}),
|
||||
(0x0011, 1, {"present_value"}),
|
||||
(0x0012, 1, {"present_value"}),
|
||||
(0x0013, 1, {"present_value"}),
|
||||
(0x0014, 1, {"present_value"}),
|
||||
(0x0015, 1, {}),
|
||||
(0x0016, 1, {}),
|
||||
(0x0019, 0, {}),
|
||||
(0x001A, 1, {}),
|
||||
(0x001B, 1, {}),
|
||||
(0x0020, 1, {}),
|
||||
(0x0021, 0, {}),
|
||||
(0x0101, 1, {"lock_state"}),
|
||||
(zigpy.zcl.clusters.general.Basic.cluster_id, 0, {}),
|
||||
(
|
||||
0x0201,
|
||||
zigpy.zcl.clusters.general.PowerConfiguration.cluster_id,
|
||||
1,
|
||||
{"battery_voltage", "battery_percentage_remaining"},
|
||||
),
|
||||
(
|
||||
zigpy.zcl.clusters.general.DeviceTemperature.cluster_id,
|
||||
1,
|
||||
{"current_temperature"},
|
||||
),
|
||||
(zigpy.zcl.clusters.general.Identify.cluster_id, 0, {}),
|
||||
(zigpy.zcl.clusters.general.Groups.cluster_id, 0, {}),
|
||||
(zigpy.zcl.clusters.general.Scenes.cluster_id, 1, {}),
|
||||
(zigpy.zcl.clusters.general.OnOff.cluster_id, 1, {"on_off"}),
|
||||
(zigpy.zcl.clusters.general.OnOffConfiguration.cluster_id, 1, {}),
|
||||
(zigpy.zcl.clusters.general.LevelControl.cluster_id, 1, {"current_level"}),
|
||||
(zigpy.zcl.clusters.general.Alarms.cluster_id, 1, {}),
|
||||
(zigpy.zcl.clusters.general.AnalogInput.cluster_id, 1, {"present_value"}),
|
||||
(zigpy.zcl.clusters.general.AnalogOutput.cluster_id, 1, {"present_value"}),
|
||||
(zigpy.zcl.clusters.general.AnalogValue.cluster_id, 1, {"present_value"}),
|
||||
(zigpy.zcl.clusters.general.AnalogOutput.cluster_id, 1, {"present_value"}),
|
||||
(zigpy.zcl.clusters.general.BinaryOutput.cluster_id, 1, {"present_value"}),
|
||||
(zigpy.zcl.clusters.general.BinaryValue.cluster_id, 1, {"present_value"}),
|
||||
(zigpy.zcl.clusters.general.MultistateInput.cluster_id, 1, {"present_value"}),
|
||||
(zigpy.zcl.clusters.general.MultistateOutput.cluster_id, 1, {"present_value"}),
|
||||
(zigpy.zcl.clusters.general.MultistateValue.cluster_id, 1, {"present_value"}),
|
||||
(zigpy.zcl.clusters.general.Commissioning.cluster_id, 1, {}),
|
||||
(zigpy.zcl.clusters.general.Partition.cluster_id, 1, {}),
|
||||
(zigpy.zcl.clusters.general.Ota.cluster_id, 0, {}),
|
||||
(zigpy.zcl.clusters.general.PowerProfile.cluster_id, 1, {}),
|
||||
(zigpy.zcl.clusters.general.ApplianceControl.cluster_id, 1, {}),
|
||||
(zigpy.zcl.clusters.general.PollControl.cluster_id, 1, {}),
|
||||
(zigpy.zcl.clusters.general.GreenPowerProxy.cluster_id, 0, {}),
|
||||
(zigpy.zcl.clusters.closures.DoorLock.cluster_id, 1, {"lock_state"}),
|
||||
(
|
||||
zigpy.zcl.clusters.hvac.Thermostat.cluster_id,
|
||||
1,
|
||||
{
|
||||
"local_temperature",
|
||||
|
@ -150,9 +158,9 @@ async def poll_control_device(zha_device_restored, zigpy_device_mock):
|
|||
"pi_heating_demand",
|
||||
},
|
||||
),
|
||||
(0x0202, 1, {"fan_mode"}),
|
||||
(zigpy.zcl.clusters.hvac.Fan.cluster_id, 1, {"fan_mode"}),
|
||||
(
|
||||
0x0300,
|
||||
zigpy.zcl.clusters.lighting.Color.cluster_id,
|
||||
1,
|
||||
{
|
||||
"current_x",
|
||||
|
@ -163,16 +171,54 @@ async def poll_control_device(zha_device_restored, zigpy_device_mock):
|
|||
"current_saturation",
|
||||
},
|
||||
),
|
||||
(0x0400, 1, {"measured_value"}),
|
||||
(0x0401, 1, {"level_status"}),
|
||||
(0x0402, 1, {"measured_value"}),
|
||||
(0x0403, 1, {"measured_value"}),
|
||||
(0x0404, 1, {"measured_value"}),
|
||||
(0x0405, 1, {"measured_value"}),
|
||||
(0x0406, 1, {"occupancy"}),
|
||||
(0x0702, 1, {"instantaneous_demand"}),
|
||||
(
|
||||
0x0B04,
|
||||
zigpy.zcl.clusters.measurement.IlluminanceMeasurement.cluster_id,
|
||||
1,
|
||||
{"measured_value"},
|
||||
),
|
||||
(
|
||||
zigpy.zcl.clusters.measurement.IlluminanceLevelSensing.cluster_id,
|
||||
1,
|
||||
{"level_status"},
|
||||
),
|
||||
(
|
||||
zigpy.zcl.clusters.measurement.TemperatureMeasurement.cluster_id,
|
||||
1,
|
||||
{"measured_value"},
|
||||
),
|
||||
(
|
||||
zigpy.zcl.clusters.measurement.PressureMeasurement.cluster_id,
|
||||
1,
|
||||
{"measured_value"},
|
||||
),
|
||||
(
|
||||
zigpy.zcl.clusters.measurement.FlowMeasurement.cluster_id,
|
||||
1,
|
||||
{"measured_value"},
|
||||
),
|
||||
(
|
||||
zigpy.zcl.clusters.measurement.RelativeHumidity.cluster_id,
|
||||
1,
|
||||
{"measured_value"},
|
||||
),
|
||||
(zigpy.zcl.clusters.measurement.OccupancySensing.cluster_id, 1, {"occupancy"}),
|
||||
(
|
||||
zigpy.zcl.clusters.smartenergy.Metering.cluster_id,
|
||||
1,
|
||||
{
|
||||
"instantaneous_demand",
|
||||
"current_summ_delivered",
|
||||
"current_tier1_summ_delivered",
|
||||
"current_tier2_summ_delivered",
|
||||
"current_tier3_summ_delivered",
|
||||
"current_tier4_summ_delivered",
|
||||
"current_tier5_summ_delivered",
|
||||
"current_tier6_summ_delivered",
|
||||
"status",
|
||||
},
|
||||
),
|
||||
(
|
||||
zigpy.zcl.clusters.homeautomation.ElectricalMeasurement.cluster_id,
|
||||
1,
|
||||
{
|
||||
"active_power",
|
||||
|
|
|
@ -309,7 +309,7 @@ async def async_test_device_temperature(hass, cluster, entity_id):
|
|||
smartenergy.Metering.cluster_id,
|
||||
"instantaneous_demand",
|
||||
async_test_metering,
|
||||
1,
|
||||
9,
|
||||
{
|
||||
"demand_formatting": 0xF9,
|
||||
"divisor": 1,
|
||||
|
@ -323,7 +323,7 @@ async def async_test_device_temperature(hass, cluster, entity_id):
|
|||
smartenergy.Metering.cluster_id,
|
||||
"summation_delivered",
|
||||
async_test_smart_energy_summation,
|
||||
1,
|
||||
9,
|
||||
{
|
||||
"demand_formatting": 0xF9,
|
||||
"divisor": 1000,
|
||||
|
|
Loading…
Add table
Reference in a new issue