I’ve been struggling trying to get this Zigbee clamp meter working.
It identifies as _TZE204_cjbofhxw TS0601
So it appears the quirk: ts0601_din_power.TuyaPowerMeter should cover it as many people report this works.
However, it seems to support the device, it does add and the red led goes off and just occasionally flashes which I believe means its paired correctly.
However, the entities shown are only:
Diagnostic
LQI
RSSI
(And they are greyed out)
No power, current, voltage or anything being shown. I have the unit connected so it has a load to monitor when I add it.
Doing a reconfiguration it does appear to have data in there, just for some reason the entities aren’t created at all:
Device reconfiguration complete.
binding reporting
Cluster
Binding
Reporting
Basic
Groups
Scenes
TuyaManufClusterDinPower
TuyaPowerMeasurement
Attribute
min/max/change
active_power:
5/900/1
active_power_max:
30/900/1
apparent_power:
5/900/1
rms_current:
5/900/1
rms_current_max:
30/900/1
rms_voltage:
5/900/1
rms_voltage_max:
30/900/1
ac_frequency:
5/900/1
ac_frequency_max:
30/900/1
TuyaElectricalMeasurement
Attribute
min/max/change
instantaneous_demand:
5/900/1
current_summ_delivered:
30/900/1
current_tier1_summ_delivered:
30/900/1
current_tier2_summ_delivered:
30/900/1
current_tier3_summ_delivered:
30/900/1
current_tier4_summ_delivered:
30/900/1
current_tier5_summ_delivered:
30/900/1
current_tier6_summ_delivered:
30/900/1
status:
1/900/1
Time
Ota
And if I download debug, it appears to have the right info in there:
"data": {
"ieee": "**REDACTED**",
"nwk": 20307,
"manufacturer": "_TZE204_cjbofhxw",
"model": "TS0601",
"name": "_TZE204_cjbofhxw TS0601",
"quirk_applied": true,
"quirk_class": "ts0601_din_power.TuyaPowerMeter",
"quirk_id": null,
"manufacturer_code": 4098,
"power_source": "Mains",
"lqi": 142,
"rssi": null,
"last_seen": "2023-11-10T13:53:20",
"available": true,
"device_type": "Router",
"signature": {
"node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.FullFunctionDevice|MainsPowered|RxOnWhenIdle|AllocateAddress: 142>, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
"endpoints": {
"1": {
"profile_id": "0x0104",
"device_type": "0x0051",
"input_clusters": [
"0x0000",
"0x0004",
"0x0005",
"0x0702",
"0x0b04",
"0xef00"
],
"output_clusters": [
"0x000a",
"0x0019"
]
}
},
"manufacturer": "_TZE204_cjbofhxw",
"model": "TS0601"
},
"active_coordinator": false,
"entities": [],
"neighbors": [
{
"device_type": "Coordinator",
"rx_on_when_idle": "On",
"relationship": "Sibling",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0x0000",
"permit_joining": "Unknown",
"depth": "0",
"lqi": "192"
},
{
"device_type": "Router",
"rx_on_when_idle": "On",
"relationship": "Sibling",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0x342F",
"permit_joining": "Unknown",
"depth": "15",
"lqi": "236"
},
{
"device_type": "Router",
"rx_on_when_idle": "On",
"relationship": "Parent",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0x4877",
"permit_joining": "Unknown",
"depth": "15",
"lqi": "254"
},
{
"device_type": "Router",
"rx_on_when_idle": "On",
"relationship": "Sibling",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0x74B0",
"permit_joining": "Unknown",
"depth": "15",
"lqi": "136"
},
{
"device_type": "Router",
"rx_on_when_idle": "On",
"relationship": "Sibling",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0xE63E",
"permit_joining": "Unknown",
"depth": "15",
"lqi": "128"
},
{
"device_type": "Router",
"rx_on_when_idle": "On",
"relationship": "Sibling",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0xE85B",
"permit_joining": "Unknown",
"depth": "15",
"lqi": "158"
}
],
"routes": [
{
"dest_nwk": "0x0000",
"route_status": "Active",
"memory_constrained": false,
"many_to_one": true,
"route_record_required": false,
"next_hop": "0x0000"
},
{
"dest_nwk": "0x4877",
"route_status": "Active",
"memory_constrained": false,
"many_to_one": true,
"route_record_required": true,
"next_hop": "0x4877"
}
],
"endpoint_names": [
{
"name": "SMART_PLUG"
}
],
"user_given_name": "PowerMonitor",
"device_reg_id": "daf0521b649369c322e53964a68c59eb",
"area_id": null,
"cluster_details": {
"1": {
"device_type": {
"name": "SMART_PLUG",
"id": 81
},
"profile_id": 260,
"in_clusters": {
"0x0000": {
"endpoint_attribute": "basic",
"attributes": {
"0x0001": {
"attribute_name": "app_version",
"value": 70
}
},
"unsupported_attributes": {}
},
"0x0004": {
"endpoint_attribute": "groups",
"attributes": {},
"unsupported_attributes": {}
},
"0x0005": {
"endpoint_attribute": "scenes",
"attributes": {},
"unsupported_attributes": {}
},
"0xef00": {
"endpoint_attribute": "tuya_manufacturer",
"attributes": {
"0xef00": {
"attribute_name": "mcu_version",
"value": "1.0.0"
}
},
"unsupported_attributes": {}
},
"0x0b04": {
"endpoint_attribute": "electrical_measurement",
"attributes": {
"0x0603": {
"attribute_name": "ac_current_divisor",
"value": 1000
},
"0x0602": {
"attribute_name": "ac_current_multiplier",
"value": 1
},
"0x050b": {
"attribute_name": "active_power",
"value": 179
},
"0x0508": {
"attribute_name": "rms_current",
"value": 719
}
},
"unsupported_attributes": {
"0x0600": {
"attribute_name": "ac_voltage_multiplier"
},
"0x0601": {
"attribute_name": "ac_voltage_divisor"
},
"0x0401": {
"attribute_name": "ac_frequency_divisor"
},
"0x0400": {
"attribute_name": "ac_frequency_multiplier"
},
"0x0604": {
"attribute_name": "ac_power_multiplier"
},
"0x0605": {
"attribute_name": "ac_power_divisor"
},
"0x0000": {
"attribute_name": "measurement_type"
},
"0x0403": {
"attribute_name": "power_divisor"
},
"0x0402": {
"attribute_name": "power_multiplier"
},
"0x0508": {
"attribute_name": "rms_current"
},
"0x050b": {
"attribute_name": "active_power"
},
"0x050a": {
"attribute_name": "rms_current_max"
},
"0x050d": {
"attribute_name": "active_power_max"
},
"0x0505": {
"attribute_name": "rms_voltage"
},
"0x050f": {
"attribute_name": "apparent_power"
},
"0x0510": {
"attribute_name": "power_factor"
},
"0x0300": {
"attribute_name": "ac_frequency"
},
"0x0302": {
"attribute_name": "ac_frequency_max"
},
"0x0507": {
"attribute_name": "rms_voltage_max"
}
}
},
"0x0702": {
"endpoint_attribute": "smartenergy_metering",
"attributes": {
"0x0302": {
"attribute_name": "divisor",
"value": 1000
},
"0x0300": {
"attribute_name": "unit_of_measure",
"value": 0
}
},
"unsupported_attributes": {
"0x0400": {
"attribute_name": "instantaneous_demand"
},
"0x0301": {
"attribute_name": "multiplier"
},
"0x0303": {
"attribute_name": "summation_formatting"
},
"0x0304": {
"attribute_name": "demand_formatting"
},
"0x0000": {
"attribute_name": "current_summ_delivered"
},
"0x0306": {
"attribute_name": "metering_device_type"
},
"0x0100": {
"attribute_name": "current_tier1_summ_delivered"
},
"0x0102": {
"attribute_name": "current_tier2_summ_delivered"
},
"0x0104": {
"attribute_name": "current_tier3_summ_delivered"
},
"0x0106": {
"attribute_name": "current_tier4_summ_delivered"
},
"0x0108": {
"attribute_name": "current_tier5_summ_delivered"
},
"0x010a": {
"attribute_name": "current_tier6_summ_delivered"
},
"0x0200": {
"attribute_name": "status"
}
}
}
},
"out_clusters": {
"0x000a": {
"endpoint_attribute": "time",
"attributes": {},
"unsupported_attributes": {}
},
"0x0019": {
"endpoint_attribute": "ota",
"attributes": {},
"unsupported_attributes": {}
}
}
}
}
}
}
Can anyone point me to why the quirk isn’t working right, what can I edit/tweak in the quirk?
The one I’m using is:
"""Tuya Din Power Meter."""
from typing import Dict
from zigpy.profiles import zha
from zigpy.quirks import CustomDevice
import zigpy.types as t
from zigpy.zcl import foundation
from zigpy.zcl.clusters.general import Basic, Groups, Ota, Scenes, Time
from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement
from zigpy.zcl.clusters.smartenergy import Metering
from zhaquirks import LocalDataCluster
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
)
from zhaquirks.tuya import TuyaLocalCluster
from zhaquirks.tuya.mcu import (
DPToAttributeMapping,
EnchantedDevice,
TuyaMCUCluster,
TuyaOnOff,
)
class TuyaPowerMeasurement(TuyaLocalCluster, ElectricalMeasurement):
"""Custom class for power, voltage and current measurement."""
AC_CURRENT_MULTIPLIER = 0x0602
AC_CURRENT_DIVISOR = 0x0603
_CONSTANT_ATTRIBUTES = {AC_CURRENT_MULTIPLIER: 1, AC_CURRENT_DIVISOR: 1000}
class TuyaElectricalMeasurement(TuyaLocalCluster, Metering):
"""Custom class for total energy measurement."""
POWER_WATT = 0x0000
_CONSTANT_ATTRIBUTES = {
0x0300: POWER_WATT, # unit_of_measure
0x0302: 1000, # divisor
}
class DinPowerManufCluster(TuyaMCUCluster):
"""Tuya Manufacturer Cluster with din power datapoints."""
class TuyaConnectionStatus(t.Struct):
"""Tuya request data."""
tsn: t.uint8_t
status: t.LVBytes
client_commands = TuyaMCUCluster.client_commands.copy()
client_commands.update(
{
0x25: foundation.ZCLCommandDef(
"mcu_connection_status",
{"payload": TuyaConnectionStatus},
True,
is_manufacturer_specific=True,
),
}
)
server_commands = TuyaMCUCluster.server_commands.copy()
server_commands.update(
{
0x25: foundation.ZCLCommandDef(
"mcu_connection_status_rsp",
{"payload": TuyaConnectionStatus},
False,
is_manufacturer_specific=True,
),
}
)
def handle_mcu_connection_status(
self, payload: TuyaConnectionStatus
) -> foundation.Status:
"""Handle gateway connection status requests (0x25)."""
payload_rsp = DinPowerManufCluster.TuyaConnectionStatus()
payload_rsp.tsn = payload.tsn
payload_rsp.status = b"\x01" # 0x00 not connected to internet | 0x01 connected to internet | 0x02 time out
self.create_catching_task(
super().command(0x25, payload_rsp, expect_reply=False)
)
return foundation.Status.SUCCESS
dp_to_attribute: Dict[int, DPToAttributeMapping] = {
0x01: DPToAttributeMapping(
TuyaElectricalMeasurement.ep_attribute,
"current_summ_delivered",
),
0x06: DPToAttributeMapping(
TuyaPowerMeasurement.ep_attribute,
("rms_current", "rms_voltage"),
converter=lambda x: (x >> 16, (x & 0x0000FFFF) / 10),
),
0x10: DPToAttributeMapping(
TuyaOnOff.ep_attribute,
"on_off",
),
0x66: DPToAttributeMapping(
TuyaElectricalMeasurement.ep_attribute,
"current_summ_received",
),
0x67: DPToAttributeMapping(
TuyaPowerMeasurement.ep_attribute,
"active_power",
),
0x69: DPToAttributeMapping(
TuyaPowerMeasurement.ep_attribute,
"ac_frequency",
),
0x6D: DPToAttributeMapping(
TuyaPowerMeasurement.ep_attribute,
"total_reactive_power",
),
0x6E: DPToAttributeMapping(
TuyaPowerMeasurement.ep_attribute,
"reactive_power",
),
0x6F: DPToAttributeMapping(
TuyaPowerMeasurement.ep_attribute,
"power_factor",
),
}
data_point_handlers = {
0x01: "_dp_2_attr_update",
0x06: "_dp_2_attr_update",
0x10: "_dp_2_attr_update",
0x66: "_dp_2_attr_update",
0x67: "_dp_2_attr_update",
0x69: "_dp_2_attr_update",
0x6D: "_dp_2_attr_update",
0x6E: "_dp_2_attr_update",
0x6F: "_dp_2_attr_update",
}
class TuyaManufClusterDinPower(DinPowerManufCluster):
"""Manufacturer Specific Cluster of the Tuya Power Meter device."""
dp_to_attribute: Dict[int, DPToAttributeMapping] = {
17: DPToAttributeMapping(
TuyaElectricalMeasurement.ep_attribute,
"current_summ_delivered",
),
18: DPToAttributeMapping(
TuyaPowerMeasurement.ep_attribute,
"rms_current",
),
19: DPToAttributeMapping(
TuyaPowerMeasurement.ep_attribute,
"active_power",
converter=lambda x: x // 10,
),
20: DPToAttributeMapping(
TuyaPowerMeasurement.ep_attribute,
"rms_voltage",
converter=lambda x: x // 10,
),
}
data_point_handlers = {
17: "_dp_2_attr_update",
18: "_dp_2_attr_update",
19: "_dp_2_attr_update",
20: "_dp_2_attr_update",
}
class TuyaPowerMeter(EnchantedDevice):
"""Tuya power meter device."""
signature = {
# "node_descriptor": "<NodeDescriptor byte1=1 byte2=64 mac_capability_flags=142 manufacturer_code=4098
# maximum_buffer_size=82 maximum_incoming_transfer_size=82 server_mask=11264
# maximum_outgoing_transfer_size=82 descriptor_capability_field=0>",
# device_version=1
# input_clusters=[0x0000, 0x0004, 0x0005, 0xef00]
# output_clusters=[0x000a, 0x0019]
MODELS_INFO: [
("_TZE204_cjbofhxw", "TS0601"),
],
ENDPOINTS: {
# <SimpleDescriptor endpoint=1 profile=260 device_type=51
# device_version=1
# input_clusters=[0, 4, 5, 61184]
# output_clusters=[10, 25]>
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaManufClusterDinPower.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
}
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaManufClusterDinPower,
TuyaPowerMeasurement,
TuyaElectricalMeasurement,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
}
}
}
class HikingPowerMeter(CustomDevice):
"""Hiking Power Meter Device - DDS238-2."""
signature = {
# "node_descriptor": "<NodeDescriptor byte1=1 byte2=64 mac_capability_flags=142 manufacturer_code=4098
# maximum_buffer_size=82 maximum_incoming_transfer_size=82 server_mask=11264
# maximum_outgoing_transfer_size=82 descriptor_capability_field=0>",
# device_version=1
# input_clusters=[0x0000, 0x0004, 0x0005, 0xef00]
# output_clusters=[0x000a, 0x0019]
MODELS_INFO: [
("_TZE200_bkkmqmyo", "TS0601"),
("ffffffffffffffff", "TS0601"),
],
ENDPOINTS: {
# <SimpleDescriptor endpoint=1 profile=260 device_type=51
# device_version=1
# input_clusters=[0, 4, 5, 61184]
# output_clusters=[10, 25]>
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
DinPowerManufCluster.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
}
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
DinPowerManufCluster,
TuyaElectricalMeasurement,
TuyaPowerMeasurement,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
16: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
INPUT_CLUSTERS: [
TuyaOnOff,
],
OUTPUT_CLUSTERS: [],
},
}
}