In the meanwhile, I learned what “quirks” are !
However, my TS0601 is from a newer type: tze200_bkkmqmyo
I think I need to change some things in the following Python code, but I’m lost in the woods …
Anyone got any idea on what needs to be changed in the following code ?
It seems there is no code available anywhere, that can read-out this new type of TS0601
(or my google-fu is not anymore what is used to be …)
I can “see” power measurement with this code, but it returns always “unknown”.
Also the switch is doing nothing, when pulled in HA …
"""Tuya Din Power Meter."""
from zigpy.profiles import zha
import zigpy.types as t
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 Bus, LocalDataCluster
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
)
from zhaquirks.tuya import TuyaManufClusterAttributes, TuyaOnOff, TuyaSwitch
TUYA_TOTAL_ENERGY_ATTR = 0x0201
TUYA_CURRENT_ATTR = 0x0266
TUYA_FREQ_ATTR = 0x0269
TUYA_POWER_ATTR = 0x0267
TUYA_VOLTAGE_ATTR = 0x0006
TUYA_DIN_SWITCH_ATTR = 0x0210
TUYA_PFACT_ATTR = 0x026F
SWITCH_EVENT = "switch_event"
class TuyaManufClusterDinPower(TuyaManufClusterAttributes):
"""Manufacturer Specific Cluster of the Tuya Power Meter device."""
attributes = {
TUYA_TOTAL_ENERGY_ATTR: ("energy", t.uint16_t),
TUYA_CURRENT_ATTR: ("current", t.int16s),
TUYA_FREQ_ATTR: ("freq", t.uint16_t),
TUYA_PFACT_ATTR: ("pfact", t.int16s),
TUYA_POWER_ATTR: ("power", t.uint16_t),
TUYA_VOLTAGE_ATTR: ("voltage", t.uint16_t),
TUYA_DIN_SWITCH_ATTR: ("switch", t.uint8_t),
}
def _update_attribute(self, attrid, value):
super()._update_attribute(attrid, value)
if attrid == TUYA_TOTAL_ENERGY_ATTR:
self.endpoint.smartenergy_metering.energy_reported(value / 100)
elif attrid == TUYA_CURRENT_ATTR:
self.endpoint.electrical_measurement.current_reported(value)
elif attrid == TUYA_FREQ_ATTR:
self.endpoint.electrical_measurement.freq_reported(value / 100)
elif attrid == TUYA_POWER_ATTR:
self.endpoint.electrical_measurement.power_reported(value)
elif attrid == TUYA_PFACT_ATTR:
self.endpoint.electrical_measurement.pfact_reported(value / 10)
elif attrid == TUYA_VOLTAGE_ATTR:
self.endpoint.electrical_measurement.voltage_reported(value / 10)
elif attrid == TUYA_DIN_SWITCH_ATTR:
self.endpoint.device.switch_bus.listener_event(
SWITCH_EVENT, self.endpoint.endpoint_id, value
)
class TuyaPowerMeasurement(LocalDataCluster, ElectricalMeasurement):
"""Custom class for power, voltage and current measurement."""
cluster_id = ElectricalMeasurement.cluster_id
POWER_ID = 0x050B
VOLTAGE_ID = 0x0505
CURRENT_ID = 0x0508
FREQ_ID = 0x0300
PFACT_ID = 0x0510
AC_CURRENT_MULTIPLIER = 0x0602
AC_CURRENT_DIVISOR = 0x0603
AC_FREQ_MULTIPLIER = 0x0400
AC_FREQ_DIVISOR = 0x0401
_CONSTANT_ATTRIBUTES = {AC_CURRENT_MULTIPLIER: 1, AC_CURRENT_DIVISOR: 1000}
def voltage_reported(self, value):
"""Voltage reported."""
self._update_attribute(self.VOLTAGE_ID, value)
def power_reported(self, value):
"""Power reported."""
self._update_attribute(self.POWER_ID, value)
def current_reported(self, value):
"""Ampers reported."""
self._update_attribute(self.CURRENT_ID, value)
def freq_reported(self, value):
"""Freq reported."""
self._update_attribute(self.FREQ_ID, value)
def pfact_reported(self, value):
"""Power factor reported."""
self._update_attribute(self.PFACT_ID, value)
class TuyaElectricalMeasurement(LocalDataCluster, Metering):
"""Custom class for total energy measurement."""
cluster_id = Metering.cluster_id
CURRENT_ID = 0x0000
POWER_WATT = 0x0000
"""Setting unit of measurement."""
_CONSTANT_ATTRIBUTES = {0x0300: POWER_WATT}
def energy_reported(self, value):
"""Summation Energy reported."""
self._update_attribute(self.CURRENT_ID, value)
class TuyaPowerMeter(TuyaSwitch):
"""Tuya power meter device."""
def __init__(self, *args, **kwargs):
"""Init device."""
self.switch_bus = Bus()
super().__init__(*args, **kwargs)
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"),
],
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,
TuyaManufClusterAttributes.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,
TuyaOnOff,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
}
}
}