diff --git a/tests/test_cluster_handlers.py b/tests/test_cluster_handlers.py index 7827be9a..cab79f51 100644 --- a/tests/test_cluster_handlers.py +++ b/tests/test_cluster_handlers.py @@ -288,8 +288,13 @@ async def poll_control_device_mock(zha_gateway: Gateway) -> Device: "ac_frequency", "ac_frequency_max", "active_power", + "active_power_ph_b", + "active_power_ph_c", "active_power_max", "apparent_power", + "power_factor", + "power_factor_ph_b", + "power_factor_ph_c", "rms_current", "rms_current_ph_b", "rms_current_ph_c", @@ -297,7 +302,11 @@ async def poll_control_device_mock(zha_gateway: Gateway) -> Device: "rms_current_max_b", "rms_current_max_c", "rms_voltage", + "rms_voltage_ph_b", + "rms_voltage_ph_c", "rms_voltage_max", + "rms_voltage_max_ph_b", + "rms_voltage_max_ph_c", }, ), ], diff --git a/tests/test_sensor.py b/tests/test_sensor.py index 65c2a5c1..e53d7f65 100644 --- a/tests/test_sensor.py +++ b/tests/test_sensor.py @@ -1147,7 +1147,11 @@ async def test_elec_measurement_skip_unsupported_attribute( all_attrs = { "active_power", + "active_power_ph_b", + "active_power_ph_c", "active_power_max", + "active_power_max_ph_b", + "active_power_max_ph_c", "apparent_power", "rms_current", "rms_current_ph_b", @@ -1156,8 +1160,14 @@ async def test_elec_measurement_skip_unsupported_attribute( "rms_current_max_ph_b", "rms_current_max_ph_c", "rms_voltage", + "rms_voltage_ph_b", + "rms_voltage_ph_c", "rms_voltage_max", + "rms_voltage_max_ph_b", + "rms_voltage_max_ph_c", "power_factor", + "power_factor_ph_b", + "power_factor_ph_c", "ac_frequency", "ac_frequency_max", } diff --git a/zha/application/platforms/sensor/__init__.py b/zha/application/platforms/sensor/__init__.py index 11e9c876..7fe2c478 100644 --- a/zha/application/platforms/sensor/__init__.py +++ b/zha/application/platforms/sensor/__init__.py @@ -694,6 +694,30 @@ class PolledElectricalMeasurement(ElectricalMeasurement): _use_custom_polling: bool = True +@MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT) +class ElectricalMeasurementRMSActivePowerPhB(PolledElectricalMeasurement): + """RMS active power phase B measurement.""" + + _attribute_name = "active_power_ph_b" + _unique_id_suffix = "active_power_ph_b" + _attr_translation_key: str = "active_power_ph_b" + _use_custom_polling = False # Poll indirectly by ElectricalMeasurementSensor + _skip_creation_if_no_attr_cache = True + _attr_max_attribute_name = "active_power_max_ph_b" + + +@MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT) +class ElectricalMeasurementRMSActivePowerPhC(PolledElectricalMeasurement): + """RMS active power phase C measurement.""" + + _attribute_name = "active_power_ph_c" + _unique_id_suffix = "active_power_ph_c" + _attr_translation_key: str = "active_power_ph_c" + _use_custom_polling = False # Poll indirectly by ElectricalMeasurementSensor + _skip_creation_if_no_attr_cache = True + _attr_max_attribute_name = "active_power_max_ph_c" + + @MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT) class ElectricalMeasurementApparentPower(PolledElectricalMeasurement): """Apparent power measurement.""" @@ -720,7 +744,7 @@ class ElectricalMeasurementRMSCurrent(PolledElectricalMeasurement): @MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT) class ElectricalMeasurementRMSCurrentPhB(ElectricalMeasurementRMSCurrent): - """RMS current measurement.""" + """RMS current phase B measurement.""" _attribute_name = "rms_current_ph_b" _unique_id_suffix = "rms_current_ph_b" @@ -731,7 +755,7 @@ class ElectricalMeasurementRMSCurrentPhB(ElectricalMeasurementRMSCurrent): @MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT) class ElectricalMeasurementRMSCurrentPhC(ElectricalMeasurementRMSCurrent): - """RMS current measurement.""" + """RMS current phase C measurement.""" _attribute_name: str = "rms_current_ph_c" _unique_id_suffix: str = "rms_current_ph_c" @@ -752,6 +776,28 @@ class ElectricalMeasurementRMSVoltage(PolledElectricalMeasurement): _div_mul_prefix = "ac_voltage" +@MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT) +class ElectricalMeasurementRMSVoltagePhB(ElectricalMeasurementRMSVoltage): + """RMS voltage phase B measurement.""" + + _attribute_name = "rms_voltage_ph_b" + _unique_id_suffix = "rms_voltage_ph_b" + _attr_translation_key: str = "rms_voltage_ph_b" + _skip_creation_if_no_attr_cache = True + _attr_max_attribute_name = "rms_voltage_max_ph_b" + + +@MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT) +class ElectricalMeasurementRMSVoltagePhC(ElectricalMeasurementRMSVoltage): + """RMS voltage phase C measurement.""" + + _attribute_name = "rms_voltage_ph_c" + _unique_id_suffix = "rms_voltage_ph_c" + _attr_translation_key: str = "rms_voltage_ph_c" + _skip_creation_if_no_attr_cache = True + _attr_max_attribute_name = "rms_voltage_max_ph_c" + + @MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT) class ElectricalMeasurementFrequency(PolledElectricalMeasurement): """Frequency measurement.""" @@ -777,6 +823,28 @@ class ElectricalMeasurementPowerFactor(PolledElectricalMeasurement): _div_mul_prefix = None +@MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT) +class ElectricalMeasurementPowerFactorPhB(ElectricalMeasurementPowerFactor): + """Power factor phase B measurement.""" + + _attribute_name = "power_factor_ph_b" + _unique_id_suffix = "power_factor_ph_b" + _attr_translation_key: str = "power_factor_ph_b" + _skip_creation_if_no_attr_cache = True + _attr_max_attribute_name = "power_factor_max_ph_b" + + +@MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_ELECTRICAL_MEASUREMENT) +class ElectricalMeasurementPowerFactorPhC(ElectricalMeasurementPowerFactor): + """Power factor phase C measurement.""" + + _attribute_name = "power_factor_ph_c" + _unique_id_suffix = "power_factor_ph_c" + _attr_translation_key: str = "power_factor_ph_c" + _skip_creation_if_no_attr_cache = True + _attr_max_attribute_name = "power_factor_max_ph_c" + + @MULTI_MATCH( generic_ids=CLUSTER_HANDLER_ST_HUMIDITY_CLUSTER, stop_on_match_group=CLUSTER_HANDLER_HUMIDITY, diff --git a/zha/zigbee/cluster_handlers/homeautomation.py b/zha/zigbee/cluster_handlers/homeautomation.py index 180ab286..a504c8f3 100644 --- a/zha/zigbee/cluster_handlers/homeautomation.py +++ b/zha/zigbee/cluster_handlers/homeautomation.py @@ -65,10 +65,26 @@ class MeasurementType(enum.IntFlag): attr=ElectricalMeasurement.AttributeDefs.active_power.name, config=REPORT_CONFIG_OP, ), + AttrReportConfig( + attr=ElectricalMeasurement.AttributeDefs.active_power_ph_b.name, + config=REPORT_CONFIG_OP, + ), + AttrReportConfig( + attr=ElectricalMeasurement.AttributeDefs.active_power_ph_c.name, + config=REPORT_CONFIG_OP, + ), AttrReportConfig( attr=ElectricalMeasurement.AttributeDefs.active_power_max.name, config=REPORT_CONFIG_DEFAULT, ), + AttrReportConfig( + attr=ElectricalMeasurement.AttributeDefs.active_power_max_ph_b.name, + config=REPORT_CONFIG_DEFAULT, + ), + AttrReportConfig( + attr=ElectricalMeasurement.AttributeDefs.active_power_max_ph_c.name, + config=REPORT_CONFIG_DEFAULT, + ), AttrReportConfig( attr=ElectricalMeasurement.AttributeDefs.apparent_power.name, config=REPORT_CONFIG_OP, @@ -101,10 +117,26 @@ class MeasurementType(enum.IntFlag): attr=ElectricalMeasurement.AttributeDefs.rms_voltage.name, config=REPORT_CONFIG_OP, ), + AttrReportConfig( + attr=ElectricalMeasurement.AttributeDefs.rms_voltage_ph_b.name, + config=REPORT_CONFIG_OP, + ), + AttrReportConfig( + attr=ElectricalMeasurement.AttributeDefs.rms_voltage_ph_c.name, + config=REPORT_CONFIG_OP, + ), AttrReportConfig( attr=ElectricalMeasurement.AttributeDefs.rms_voltage_max.name, config=REPORT_CONFIG_DEFAULT, ), + AttrReportConfig( + attr=ElectricalMeasurement.AttributeDefs.rms_voltage_max_ph_b.name, + config=REPORT_CONFIG_DEFAULT, + ), + AttrReportConfig( + attr=ElectricalMeasurement.AttributeDefs.rms_voltage_max_ph_c.name, + config=REPORT_CONFIG_DEFAULT, + ), AttrReportConfig( attr=ElectricalMeasurement.AttributeDefs.ac_frequency.name, config=REPORT_CONFIG_OP, @@ -113,6 +145,18 @@ class MeasurementType(enum.IntFlag): attr=ElectricalMeasurement.AttributeDefs.ac_frequency_max.name, config=REPORT_CONFIG_DEFAULT, ), + AttrReportConfig( + attr=ElectricalMeasurement.AttributeDefs.power_factor.name, + config=REPORT_CONFIG_OP, + ), + AttrReportConfig( + attr=ElectricalMeasurement.AttributeDefs.power_factor_ph_b.name, + config=REPORT_CONFIG_OP, + ), + AttrReportConfig( + attr=ElectricalMeasurement.AttributeDefs.power_factor_ph_c.name, + config=REPORT_CONFIG_OP, + ), ) ZCL_INIT_ATTRS = { ElectricalMeasurement.AttributeDefs.ac_current_divisor.name: True, @@ -126,7 +170,6 @@ class MeasurementType(enum.IntFlag): ElectricalMeasurement.AttributeDefs.measurement_type.name: True, ElectricalMeasurement.AttributeDefs.power_divisor.name: True, ElectricalMeasurement.AttributeDefs.power_multiplier.name: True, - ElectricalMeasurement.AttributeDefs.power_factor.name: True, } async def async_update(self):