Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add remaining 3 phase electrical attributes #339

Merged
merged 13 commits into from
Jan 23, 2025
5 changes: 4 additions & 1 deletion tests/test_cluster_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,12 +287,15 @@ async def poll_control_device_mock(zha_gateway: Gateway) -> Device:
{
"ac_frequency",
"active_power",
"active_power_ph_b",
"active_power_ph_c",
"apparent_power",
"rms_current",
"rms_current_ph_b",
"rms_current_ph_c",
"rms_current_max",
"rms_voltage",
"rms_voltage_ph_b",
"rms_voltage_ph_c",
},
),
],
Expand Down
10 changes: 10 additions & 0 deletions tests/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
}
Expand Down
72 changes: 70 additions & 2 deletions zha/application/platforms/sensor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,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."""
Expand All @@ -717,7 +741,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"
Expand All @@ -728,7 +752,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"
Expand All @@ -749,6 +773,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."""
Expand All @@ -774,6 +820,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,
Expand Down
49 changes: 44 additions & 5 deletions zha/zigbee/cluster_handlers/homeautomation.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ 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.apparent_power.name,
config=REPORT_CONFIG_OP,
Expand All @@ -84,6 +92,14 @@ 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.ac_frequency.name,
config=REPORT_CONFIG_OP,
Expand All @@ -93,30 +109,53 @@ class MeasurementType(enum.IntFlag):
ElectricalMeasurement.AttributeDefs.ac_frequency.name,
ElectricalMeasurement.AttributeDefs.ac_frequency_max.name,
ElectricalMeasurement.AttributeDefs.active_power.name,
ElectricalMeasurement.AttributeDefs.active_power_ph_b.name,
ElectricalMeasurement.AttributeDefs.active_power_ph_c.name,
ElectricalMeasurement.AttributeDefs.active_power_max.name,
ElectricalMeasurement.AttributeDefs.active_power_max_ph_b.name,
ElectricalMeasurement.AttributeDefs.active_power_max_ph_c.name,
ElectricalMeasurement.AttributeDefs.apparent_power.name,
ElectricalMeasurement.AttributeDefs.power_factor.name,
ElectricalMeasurement.AttributeDefs.power_factor_ph_b.name,
ElectricalMeasurement.AttributeDefs.power_factor_ph_c.name,
ElectricalMeasurement.AttributeDefs.rms_current.name,
ElectricalMeasurement.AttributeDefs.rms_current_ph_b.name,
ElectricalMeasurement.AttributeDefs.rms_current_ph_c.name,
ElectricalMeasurement.AttributeDefs.rms_current_max.name,
ElectricalMeasurement.AttributeDefs.rms_current_max_ph_b.name,
ElectricalMeasurement.AttributeDefs.rms_current_max_ph_c.name,
ElectricalMeasurement.AttributeDefs.rms_current_ph_b.name,
ElectricalMeasurement.AttributeDefs.rms_current_ph_c.name,
ElectricalMeasurement.AttributeDefs.rms_voltage.name,
ElectricalMeasurement.AttributeDefs.rms_voltage_ph_b.name,
ElectricalMeasurement.AttributeDefs.rms_voltage_ph_c.name,
ElectricalMeasurement.AttributeDefs.rms_voltage_max.name,
ElectricalMeasurement.AttributeDefs.rms_voltage_max_ph_b.name,
ElectricalMeasurement.AttributeDefs.rms_voltage_max_ph_c.name,
]
ZCL_INIT_ATTRS = {
ElectricalMeasurement.AttributeDefs.ac_current_divisor.name: True,
ElectricalMeasurement.AttributeDefs.ac_current_multiplier.name: True,
ElectricalMeasurement.AttributeDefs.ac_frequency_divisor.name: True,
abmantis marked this conversation as resolved.
Show resolved Hide resolved
ElectricalMeasurement.AttributeDefs.ac_frequency_max.name: True,
ElectricalMeasurement.AttributeDefs.ac_frequency_multiplier.name: True,
ElectricalMeasurement.AttributeDefs.ac_power_divisor.name: True,
ElectricalMeasurement.AttributeDefs.ac_power_multiplier.name: True,
ElectricalMeasurement.AttributeDefs.ac_voltage_divisor.name: True,
ElectricalMeasurement.AttributeDefs.ac_voltage_multiplier.name: True,
ElectricalMeasurement.AttributeDefs.ac_frequency_divisor.name: True,
ElectricalMeasurement.AttributeDefs.ac_frequency_multiplier.name: True,
ElectricalMeasurement.AttributeDefs.active_power_max.name: True,
ElectricalMeasurement.AttributeDefs.active_power_max_ph_b.name: True,
ElectricalMeasurement.AttributeDefs.active_power_max_ph_c.name: True,
ElectricalMeasurement.AttributeDefs.measurement_type.name: True,
ElectricalMeasurement.AttributeDefs.power_divisor.name: True,
ElectricalMeasurement.AttributeDefs.power_multiplier.name: True,
ElectricalMeasurement.AttributeDefs.power_factor.name: True,
abmantis marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I think this is almost good to go now, except for one thing:
All attributes that are exclusively in ZCL_POLLING_ATTRS like power_factor (and I guess also the _max attributes) need to be added to ZCL_INIT_ATTRS too, with cache=True, so they're initialized during pairing. Otherwise, the entities will not be created until ZHA is restarted.

(Attributes that are in ATTR_REPORTING should not be duplicated into ZCL_INIT_ATTRS though.)

There are some other PRs I want to get in first, so I'll look into slightly changing this behavior in the future, but to have less conflicts with the (IKEA) divisor/multiplier reporting PR, let's just add the three power_factor and I guess also the ten _max attributes to ZCL_INIT_ATTRS.

ElectricalMeasurement.AttributeDefs.power_factor_ph_b.name: True,
ElectricalMeasurement.AttributeDefs.power_factor_ph_c.name: True,
ElectricalMeasurement.AttributeDefs.power_multiplier.name: True,
ElectricalMeasurement.AttributeDefs.rms_current_max.name: True,
ElectricalMeasurement.AttributeDefs.rms_current_max_ph_b.name: True,
ElectricalMeasurement.AttributeDefs.rms_current_max_ph_c.name: True,
ElectricalMeasurement.AttributeDefs.rms_voltage_max.name: True,
ElectricalMeasurement.AttributeDefs.rms_voltage_max_ph_b.name: True,
ElectricalMeasurement.AttributeDefs.rms_voltage_max_ph_c.name: True,
}

async def async_update(self):
Expand Down
Loading