From a99f27e1316e41fbed5967ec65f4da53d6c4d6bb Mon Sep 17 00:00:00 2001 From: abmantis Date: Mon, 2 Dec 2024 01:46:12 +0000 Subject: [PATCH 1/2] Add TS0601 3 phase meter --- zhaquirks/tuya/__init__.py | 9 ++ zhaquirks/tuya/ts0601_din_power.py | 202 ++++++++++++++++++++++++++++- 2 files changed, 210 insertions(+), 1 deletion(-) diff --git a/zhaquirks/tuya/__init__.py b/zhaquirks/tuya/__init__.py index ac4554faac..152a93accf 100644 --- a/zhaquirks/tuya/__init__.py +++ b/zhaquirks/tuya/__init__.py @@ -1594,6 +1594,15 @@ def handle_get_data(self, command: TuyaCommand) -> foundation.Status: dp_error = True # return foundation.Status.UNSUPPORTED_ATTRIBUTE + _LOGGER.debug( + "[0x%04x:%s:0x%04x] Received value %s " "for attribute 0x%04x", + self.endpoint.device.nwk, + self.endpoint.endpoint_id, + self.cluster_id, + record.data.payload, + record.dp, + ) + return ( foundation.Status.SUCCESS if not dp_error diff --git a/zhaquirks/tuya/ts0601_din_power.py b/zhaquirks/tuya/ts0601_din_power.py index d9c1b76a25..02fcb30b55 100644 --- a/zhaquirks/tuya/ts0601_din_power.py +++ b/zhaquirks/tuya/ts0601_din_power.py @@ -1,6 +1,8 @@ """Tuya Din Power Meter.""" from zigpy.profiles import zha +from zigpy.quirks.v2 import SensorDeviceClass, SensorStateClass +from zigpy.quirks.v2.homeassistant import UnitOfEnergy import zigpy.types as t from zigpy.zcl.clusters.general import Basic, Groups, Ota, Scenes, Time from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement @@ -15,7 +17,13 @@ OUTPUT_CLUSTERS, PROFILE_ID, ) -from zhaquirks.tuya import TuyaManufClusterAttributes, TuyaOnOff, TuyaSwitch +from zhaquirks.tuya import ( + TuyaLocalCluster, + TuyaManufClusterAttributes, + TuyaOnOff, + TuyaSwitch, +) +from zhaquirks.tuya.builder import TuyaQuirkBuilder TUYA_TOTAL_ENERGY_ATTR = 0x0211 TUYA_CURRENT_ATTR = 0x0212 @@ -233,6 +241,198 @@ def __init__(self, *args, **kwargs): } +class Tuya3PhaseElectricalMeasurement(ElectricalMeasurement, TuyaLocalCluster): + """Tuya Electrical Measurement cluster.""" + + _CONSTANT_ATTRIBUTES = { + ElectricalMeasurement.AttributeDefs.ac_current_divisor.id: 1000, + ElectricalMeasurement.AttributeDefs.ac_voltage_divisor.id: 10, + ElectricalMeasurement.AttributeDefs.ac_frequency_divisor.id: 100, + } + + +( + TuyaQuirkBuilder("_TZE204_ugekduaj", "TS0601") + .tuya_dp( + dp_id=0x65, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="ac_frequency", + ) + # Energy consumed + .tuya_sensor( + dp_id=0x01, + attribute_name="energy_consumed", + type=t.uint32_t, + divisor=100, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + unit=UnitOfEnergy.KILO_WATT_HOUR, + translation_key="total_energy", + fallback_name="Total energy", + ) + .tuya_sensor( + dp_id=0x70, + attribute_name="energy_consumed_ph_a", + type=t.uint32_t, + divisor=100, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + unit=UnitOfEnergy.KILO_WATT_HOUR, + translation_key="energy", + fallback_name="Energy", + ) + .tuya_sensor( + dp_id=0x72, + attribute_name="energy_consumed_ph_b", + type=t.uint32_t, + divisor=100, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + unit=UnitOfEnergy.KILO_WATT_HOUR, + translation_key="energy_2", + fallback_name="Energy 2", + ) + .tuya_sensor( + dp_id=0x74, + attribute_name="energy_consumed_ph_c", + divisor=100, + type=t.uint32_t, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + unit=UnitOfEnergy.KILO_WATT_HOUR, + translation_key="energy_3", + fallback_name="Energy 3", + ) + # Energy produced + .tuya_sensor( + dp_id=0x02, + attribute_name="energy_produced", + type=t.uint32_t, + divisor=100, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + unit=UnitOfEnergy.KILO_WATT_HOUR, + translation_key="total_energy_produced", + fallback_name="Total energy produced", + ) + .tuya_sensor( + dp_id=0x71, + attribute_name="energy_produced_ph_a", + type=t.uint32_t, + converter=lambda x: x / 100, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + unit=UnitOfEnergy.KILO_WATT_HOUR, + translation_key="energy_produced", + fallback_name="Energy produced", + ) + .tuya_sensor( + dp_id=0x73, + attribute_name="energy_produced_ph_b", + type=t.uint32_t, + divisor=100, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + unit=UnitOfEnergy.KILO_WATT_HOUR, + translation_key="energy_produced_2", + fallback_name="Energy produced 2", + ) + .tuya_sensor( + dp_id=0x75, + attribute_name="energy_produced_ph_c", + type=t.uint32_t, + divisor=100, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + unit=UnitOfEnergy.KILO_WATT_HOUR, + translation_key="energy_produced_3", + fallback_name="Energy produced 3", + ) + # Power + .tuya_dp( + dp_id=0x6F, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="total_active_power", + ) + .tuya_dp( + dp_id=0x68, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="active_power", + ) + .tuya_dp( + dp_id=0x6B, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="active_power_ph_b", + ) + .tuya_dp( + dp_id=0x6E, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="active_power_ph_c", + ) + # Voltage + .tuya_dp( + dp_id=0x66, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="rms_voltage", + ) + .tuya_dp( + dp_id=0x69, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="rms_voltage_ph_b", + ) + .tuya_dp( + dp_id=0x6C, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="rms_voltage_ph_c", + ) + # Current + .tuya_dp( + dp_id=0x67, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="rms_current", + ) + .tuya_dp( + dp_id=0x6A, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="rms_current_ph_b", + ) + .tuya_dp( + dp_id=0x6D, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="rms_current_ph_c", + ) + # Power factor + .tuya_sensor( + dp_id=0x0F, + attribute_name="power_factor", + type=t.uint8_t, + state_class=SensorStateClass.MEASUREMENT, + device_class=SensorDeviceClass.POWER_FACTOR, + # unit=PERCENTAGE, # ZHA fails to validate this one + translation_key="total_power_factor", + fallback_name="Total power factor", + ) + .tuya_dp( + dp_id=0x76, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="power_factor", + ) + .tuya_dp( + dp_id=0x77, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="power_factor_ph_b", + ) + .tuya_dp( + dp_id=0x78, + ep_attribute=Tuya3PhaseElectricalMeasurement.ep_attribute, + attribute_name="power_factor_ph_c", + ) + .adds(Tuya3PhaseElectricalMeasurement) + .skip_configuration() + .add_to_registry() +) + + class HikingPowerMeter(TuyaSwitch): """Hiking Power Meter Device - DDS238-2.""" From 1df10e5bb574475b4eed77a3f94db68c7deb9011 Mon Sep 17 00:00:00 2001 From: abmantis Date: Tue, 24 Dec 2024 18:07:34 +0000 Subject: [PATCH 2/2] Improve energy entity names --- zhaquirks/tuya/ts0601_din_power.py | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/zhaquirks/tuya/ts0601_din_power.py b/zhaquirks/tuya/ts0601_din_power.py index 02fcb30b55..22f80eaa49 100644 --- a/zhaquirks/tuya/ts0601_din_power.py +++ b/zhaquirks/tuya/ts0601_din_power.py @@ -267,7 +267,6 @@ class Tuya3PhaseElectricalMeasurement(ElectricalMeasurement, TuyaLocalCluster): state_class=SensorStateClass.TOTAL_INCREASING, device_class=SensorDeviceClass.ENERGY, unit=UnitOfEnergy.KILO_WATT_HOUR, - translation_key="total_energy", fallback_name="Total energy", ) .tuya_sensor( @@ -278,8 +277,8 @@ class Tuya3PhaseElectricalMeasurement(ElectricalMeasurement, TuyaLocalCluster): state_class=SensorStateClass.TOTAL_INCREASING, device_class=SensorDeviceClass.ENERGY, unit=UnitOfEnergy.KILO_WATT_HOUR, - translation_key="energy", - fallback_name="Energy", + translation_key="energy_ph_a", + fallback_name="Energy phase A", ) .tuya_sensor( dp_id=0x72, @@ -289,8 +288,8 @@ class Tuya3PhaseElectricalMeasurement(ElectricalMeasurement, TuyaLocalCluster): state_class=SensorStateClass.TOTAL_INCREASING, device_class=SensorDeviceClass.ENERGY, unit=UnitOfEnergy.KILO_WATT_HOUR, - translation_key="energy_2", - fallback_name="Energy 2", + translation_key="energy_ph_b", + fallback_name="Energy phase B", ) .tuya_sensor( dp_id=0x74, @@ -300,8 +299,8 @@ class Tuya3PhaseElectricalMeasurement(ElectricalMeasurement, TuyaLocalCluster): state_class=SensorStateClass.TOTAL_INCREASING, device_class=SensorDeviceClass.ENERGY, unit=UnitOfEnergy.KILO_WATT_HOUR, - translation_key="energy_3", - fallback_name="Energy 3", + translation_key="energy_ph_c", + fallback_name="Energy phase C", ) # Energy produced .tuya_sensor( @@ -312,8 +311,8 @@ class Tuya3PhaseElectricalMeasurement(ElectricalMeasurement, TuyaLocalCluster): state_class=SensorStateClass.TOTAL_INCREASING, device_class=SensorDeviceClass.ENERGY, unit=UnitOfEnergy.KILO_WATT_HOUR, - translation_key="total_energy_produced", - fallback_name="Total energy produced", + translation_key="energy_produced", + fallback_name="Energy produced", ) .tuya_sensor( dp_id=0x71, @@ -323,8 +322,8 @@ class Tuya3PhaseElectricalMeasurement(ElectricalMeasurement, TuyaLocalCluster): state_class=SensorStateClass.TOTAL_INCREASING, device_class=SensorDeviceClass.ENERGY, unit=UnitOfEnergy.KILO_WATT_HOUR, - translation_key="energy_produced", - fallback_name="Energy produced", + translation_key="energy_produced_ph_a", + fallback_name="Energy produced phase A", ) .tuya_sensor( dp_id=0x73, @@ -334,8 +333,8 @@ class Tuya3PhaseElectricalMeasurement(ElectricalMeasurement, TuyaLocalCluster): state_class=SensorStateClass.TOTAL_INCREASING, device_class=SensorDeviceClass.ENERGY, unit=UnitOfEnergy.KILO_WATT_HOUR, - translation_key="energy_produced_2", - fallback_name="Energy produced 2", + translation_key="energy_produced_ph_b", + fallback_name="Energy produced phase B", ) .tuya_sensor( dp_id=0x75, @@ -345,8 +344,8 @@ class Tuya3PhaseElectricalMeasurement(ElectricalMeasurement, TuyaLocalCluster): state_class=SensorStateClass.TOTAL_INCREASING, device_class=SensorDeviceClass.ENERGY, unit=UnitOfEnergy.KILO_WATT_HOUR, - translation_key="energy_produced_3", - fallback_name="Energy produced 3", + translation_key="energy_produced_ph_c", + fallback_name="Energy produced phase C", ) # Power .tuya_dp(