Open joviado opened 7 months ago
Hi,
I have this device and I am interesed in have the converter. I am new in this and my knowledge is nearly nothing, I am doing my best to learn but I am like a baby trying to walk. As well I need a lot of help.
I share what I learnt until now.
For the moment apart of the Data Points that you show in your previous message I have seen messages to this data points:
"1":"Total forward energy" -- {"data":{"data":[0,0,0,8],"type":"Buffer"},"datatype":2,"dp":1}],"seq":22784} --> num divided by 100 --> 0,08 kwh "6":"Phase A": -- {"data":{"data":[8,198,0,0,0,0,0,0],"type":"Buffer"},"datatype":0,"dp":6} --> raw --> {"current":0,"power":0,"voltage":224.6} Byte 0 y 1 Voltage, 4 y 5 corriente, 6 y 7 power (phasevariant2) "16":"Switch" -- {"data":{"data":[0],"type":"Buffer"},"datatype":1,"dp":16}],"seq":18944} --> boolean --> 0:off 1: on
Settings (over-voltage, unde-voltage, over-current, over-power and temperature):
data settings: (enum) 0: closed 1: alarm 2: trip
"102":"Over-voltage setting" -- {"data":{"data":[2],"type":"Buffer"},"datatype":4,"dp":102}],"seq":19200} --> enum --> 0: Closed 1: Alarm 2: trip "103":"Under-voltage setting" -- {"data":{"data":[0],"type":"Buffer"},"datatype":4,"dp":103}],"seq":19456} --> enum --> 0: Closed 1: Alarm 2: trip "104":"Over-current setting" -- {"data":{"data":[2],"type":"Buffer"},"datatype":4,"dp":104}],"seq":19712} --> enum --> 0: Closed 1: Alarm 2: trip "105":"Over-power setting" -- {"data":{"data":[0],"type":"Buffer"},"datatype":4,"dp":105}],"seq":19968} --> enum --> 0: Closed 1: Alarm 2: trip "107":"Temperature setting" -- {"data":{"data":[2],"type":"Buffer"},"datatype":4,"dp":107}],"seq":20224} --> enum --> 0: Closed 1: Alarm 2: trip
"109":"Online state", I have not seen any mesage, I do not know what it is for and how it works.
"110":"Event" --> {"data":{"data":[11],"type":"Buffer"},"datatype":4,"dp":110}],"seq":57600} --> enum 11 I don't know the meaning but it is the value when switch is ON enum 12 I don't know the meaning but it is the value when switch is OFF enum 0 shows during power on
"112":"Automatic closing switch" -- {"data":{"data":[0],"type":"Buffer"},"datatype":1,"dp":112}],"seq":20736} --> Boolean --> 0:off 1: on
Threshold:
"114":"Current threshold" -- {"data":{"data":[0,0,0,10],"type":"Buffer"},"datatype":2,"dp":114}],"seq":20992} --> num --> 10A "115":"Over-voltage threshold" -- {"data":{"data":[0,0,1,24],"type":"Buffer"},"datatype":2,"dp":115}],"seq":21248} --> num --> 280 V "116":"Under-voltage threshold" -- {"data":{"data":[0,0,0,165],"type":"Buffer"},"datatype":2,"dp":116}],"seq":21504} --> num --> 165 V "118":"Temperature threshold" -- {"data":{"data":[0,0,3,32],"type":"Buffer"},"datatype":2,"dp":118}],"seq":21760} --> num --> 80 ºC --> div 10 "119":"Over-power threshold" -- {"data":{"data":[0,0,7,208],"type":"Buffer"},"datatype":2,"dp":119}],"seq":22016} --> num --> 2000 W
"125":"Forward electricity" -- {"data":{"data":[0,0,0,8],"type":"Buffer"},"datatype":2,"dp":125}],"seq":23040} --> num --> 0.08 Kw - h "131":"Real-time Temp" -- {"data":{"data":[0,0,0,210],"type":"Buffer"},"datatype":2,"dp":131}],"seq":22272} --> num --> 21 ºC --> div 10
Another thing I've seen is that the device only updates current, voltage, power, energy, etc. information every 10 minutes and sends no changes in current draw when it happens, only every 10 minutes.
I can only see the following cluster under Endpoint 1: Output: genOta, genTime and Input: genBasic, genGroups, genScenes, manuSpecifcTuya.
I do not know how to pin the device to request updates of electrical measures, in other devices I can do it through cluster haElectricalMeasurements.
The only thing I was able to make work with a local converter is switch on or off the device and show current, voltage, power, energy and temperatura as you @joviado. I am trying to add at least the setting (how the device does when the defined threshold is crossed) of the temperature threshold without success.
I add my external definition. Please take in account that I am new and sure this code is useless. I was trying to adapt code from other similar devices, but I am missing something because is not working. I imagine is because the msg are of type buffer and I do not know how to manipulate it.
`const fz = require('zigbee-herdsman-converters/converters/fromZigbee'); const tz = require('zigbee-herdsman-converters/converters/toZigbee'); const exposes = require('zigbee-herdsman-converters/lib/exposes'); const reporting = require('zigbee-herdsman-converters/lib/reporting'); const extend = require('zigbee-herdsman-converters/lib/extend'); const moderExtend = require('zigbee-herdsman-converters/lib/modernExtend'); const ota = require('zigbee-herdsman-converters/lib/ota'); const tuya = require('zigbee-herdsman-converters/lib/tuya'); const utils = require('zigbee-herdsman-converters/lib/utils'); const globalStore = require('zigbee-herdsman-converters/lib/store'); const e = exposes.presets; const ea = exposes.access;
const tz_settings = { key: ['Temperature setting'], convertSet: async (entity, key, value, meta) => { if(value == "closed") { await tuya.sendDataPointEnum(entity, 131, 0); } else if(value == "alarm") { await tuya.sendDataPointEnum(entity, 131, 1); } else if(value == "trip") { await tuya.sendDataPointEnum(entity, 131, 2); } }, }
const definition = { // Since a lot of TuYa devices use the same modelID, but use different datapoints // it's necessary to provide a fingerprint instead of a zigbeeModel fingerprint: [ { // The model ID from: Device with modelID 'TS0601' is not supported // You may need to add \u0000 at the end of the name in some cases modelID: 'TS0601', // The manufacturer name from: Device with modelID 'TS0601' is not supported. manufacturerName: '_TZE204_mrffaamu', }, ], model: 'TOQCB2-80', vendor: 'TuYa', description: 'Smart Circuit breaker', fromZigbee: [tuya.fz.datapoints], toZigbee: [tuya.tz.datapoints,tz_settings], configure: tuya.configureMagicPacket, exposes: [tuya.exposes.switch(), e.energy(), e.power(), e.voltage(), e.current(),e.temperature(), // Here you should put all functionality that your device exposes e.enum('Temperature setting', ea.ALL, ['closed', 'alarm', 'trip']) .withDescription('Action if threshold value is reached'), ], meta: { // All datapoints go in here tuyaDatapoints: [ [1, 'energy', tuya.valueConverter.divideBy100], [6, null, tuya.valueConverter.phaseVariant2], [16, 'state', tuya.valueConverter.onOff], [107, 'Temperature setting', tuya.valueConverterBasic.lookup({'trip': tuya.enum(2), 'alarm': tuya.enum(1), 'closed': tuya.enum(0)})] [131, "temperature", tuya.valueConverter.divideBy10], ], }, };
module.exports = definition;`
Finally I attach the messages sent by the device if it helps to develop the converter.
Debug 2024-03-28 11:33:41Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,9],"type":"Buffer"},"datatype":2,"dp":1}],"seq":23552}' from endpoint 1 with groupID 0 Info 2024-03-28 11:33:41MQTT publish: topic 'zigbee2mqtt/pia_sa', payload '{"current":0,"energy":0.09,"linkquality":65,"power":0,"state":"OFF","temperature":21.8,"voltage":229.1}' Debug 2024-03-28 11:33:42Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,9],"type":"Buffer"},"datatype":2,"dp":125}],"seq":23808}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:42Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[8,249,0,0,0,0,0,0],"type":"Buffer"},"datatype":0,"dp":6}],"seq":24064}' from endpoint 1 with groupID 0 Info 2024-03-28 11:33:42MQTT publish: topic 'zigbee2mqtt/pia_sa', payload '{"current":0,"energy":0.09,"linkquality":65,"power":0,"state":"OFF","temperature":21.8,"voltage":229.7}' Debug 2024-03-28 11:33:42Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[1],"type":"Buffer"},"datatype":1,"dp":16}],"seq":24320}' from endpoint 1 with groupID 0 Info 2024-03-28 11:33:42MQTT publish: topic 'zigbee2mqtt/pia_sa', payload '{"current":0,"energy":0.09,"linkquality":69,"power":0,"state":"ON","temperature":21.8,"voltage":229.7}' Debug 2024-03-28 11:33:42Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[2],"type":"Buffer"},"datatype":4,"dp":102}],"seq":24576}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:42Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":4,"dp":103}],"seq":24832}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:42Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[2],"type":"Buffer"},"datatype":4,"dp":104}],"seq":25088}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:42Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":4,"dp":105}],"seq":25344}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:42Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[2],"type":"Buffer"},"datatype":4,"dp":107}],"seq":25600}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:42Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[13],"type":"Buffer"},"datatype":4,"dp":110}],"seq":25856}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:43Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":1,"dp":112}],"seq":26112}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:43Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,10],"type":"Buffer"},"datatype":2,"dp":114}],"seq":26368}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:43Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,1,24],"type":"Buffer"},"datatype":2,"dp":115}],"seq":26624}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:43Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,165],"type":"Buffer"},"datatype":2,"dp":116}],"seq":26880}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:43Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,3,32],"type":"Buffer"},"datatype":2,"dp":118}],"seq":27136}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:43Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,7,208],"type":"Buffer"},"datatype":2,"dp":119}],"seq":27392}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:43Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,218],"type":"Buffer"},"datatype":2,"dp":131}],"seq":27648}' from endpoint 1 with groupID 0 Info 2024-03-28 11:33:43MQTT publish: topic 'zigbee2mqtt/pia_sa', payload '{"current":0,"energy":0.09,"linkquality":69,"power":0,"state":"ON","temperature":21.8,"voltage":229.7}' Debug 2024-03-28 11:33:43Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[1],"type":"Buffer"},"datatype":1,"dp":16}],"seq":28160}' from endpoint 1 with groupID 0 Info 2024-03-28 11:33:43MQTT publish: topic 'zigbee2mqtt/pia_sa', payload '{"current":0,"energy":0.09,"linkquality":69,"power":0,"state":"ON","temperature":21.8,"voltage":229.7}' Debug 2024-03-28 11:33:43Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,9],"type":"Buffer"},"datatype":2,"dp":1}],"seq":28416}' from endpoint 1 with groupID 0 Info 2024-03-28 11:33:43MQTT publish: topic 'zigbee2mqtt/pia_sa', payload '{"current":0,"energy":0.09,"linkquality":69,"power":0,"state":"ON","temperature":21.8,"voltage":229.7}' Debug 2024-03-28 11:33:44Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,9],"type":"Buffer"},"datatype":2,"dp":125}],"seq":28672}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:44Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[8,248,0,0,0,0,0,0],"type":"Buffer"},"datatype":0,"dp":6}],"seq":28928}' from endpoint 1 with groupID 0 Info 2024-03-28 11:33:44MQTT publish: topic 'zigbee2mqtt/pia_sa', payload '{"current":0,"energy":0.09,"linkquality":65,"power":0,"state":"ON","temperature":21.8,"voltage":229.6}' Debug 2024-03-28 11:33:44Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[1],"type":"Buffer"},"datatype":1,"dp":16}],"seq":29184}' from endpoint 1 with groupID 0 Info 2024-03-28 11:33:44MQTT publish: topic 'zigbee2mqtt/pia_sa', payload '{"current":0,"energy":0.09,"linkquality":69,"power":0,"state":"ON","temperature":21.8,"voltage":229.6}' Debug 2024-03-28 11:33:44Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[2],"type":"Buffer"},"datatype":4,"dp":102}],"seq":29440}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:44Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":4,"dp":103}],"seq":29696}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:44Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[2],"type":"Buffer"},"datatype":4,"dp":104}],"seq":29952}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:44Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":4,"dp":105}],"seq":30208}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:44Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[2],"type":"Buffer"},"datatype":4,"dp":107}],"seq":30464}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:44Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[13],"type":"Buffer"},"datatype":4,"dp":110}],"seq":30720}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:45Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":1,"dp":112}],"seq":30976}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:45Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,10],"type":"Buffer"},"datatype":2,"dp":114}],"seq":31232}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:45Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,1,24],"type":"Buffer"},"datatype":2,"dp":115}],"seq":31488}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:45Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,165],"type":"Buffer"},"datatype":2,"dp":116}],"seq":31744}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:45Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,3,32],"type":"Buffer"},"datatype":2,"dp":118}],"seq":32000}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:45Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,7,208],"type":"Buffer"},"datatype":2,"dp":119}],"seq":32256}' from endpoint 1 with groupID 0 Debug 2024-03-28 11:33:45Received Zigbee message from 'pia_sa', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,219],"type":"Buffer"},"datatype":2,"dp":131}],"seq":32512}' from endpoint 1 with groupID 0 Info 2024-03-28 11:33:45MQTT publish: topic 'zigbee2mqtt/pia_sa', payload '{"current":0,"energy":0.09,"linkquality":72,"power":0,"state":"ON","temperature":21.9,"voltage":229.6}'
Hi,
Now it is working the settings, as an example temperarture and under-voltage settings. Now I am working with the threshold I got an error of data type.
const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const moderExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;
const { Buffer } = require('node:buffer');
const tz_settings = {
key: ['temperature_setting','temperature_threshold','under-voltage_setting'],
convertSet: async (entity, key, value, meta) => {
const settingType = {'trip': 2, 'alarm': 1, 'closed': 0};
switch (key) {
case 'temperature_setting': {
await tuya.sendDataPointEnum(entity, 107, utils.getFromLookup(value, settingType));
break;
}
case 'temperature_threshold': {
const buf = Buffer.from([0x00,0x00,0x00,value]);
await tuya.sendDataPointStringBuffer(entity, 118, buf);
break;
}
case 'under-voltage_setting': {
await tuya.sendDataPointEnum(entity, 103, utils.getFromLookup(value, settingType));
break;
}
default: // Unknown key
meta.logger.warn(`Unhandled key ${key}`);
}
},
}
const definition = {
// Since a lot of TuYa devices use the same modelID, but use different datapoints
// it's necessary to provide a fingerprint instead of a zigbeeModel
fingerprint: [
{
// The model ID from: Device with modelID 'TS0601' is not supported
// You may need to add \u0000 at the end of the name in some cases
modelID: 'TS0601',
// The manufacturer name from: Device with modelID 'TS0601' is not supported.
manufacturerName: '_TZE204_mrffaamu',
},
],
model: 'TOQCB2-80',
vendor: 'TuYa',
description: 'Smart Circuit breaker',
fromZigbee: [tuya.fz.datapoints],
toZigbee: [tuya.tz.datapoints,tz_settings],
configure: tuya.configureMagicPacket,
exposes: [tuya.exposes.switch(), e.energy(), e.power(), e.voltage(), e.current(),e.temperature(),
// Here you should put all functionality that your device exposes
e.enum('temperature_setting', ea.ALL, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('temperature_threshold', ea.STATE_SET).withValueMin(-40).withValueMax(100).withValueStep(1)
.withDescription('Temperature threshold setting'),
e.enum('under-voltage_setting', ea.ALL, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('under-voltage_threshold', ea.STATE_SET).withValueMin(145).withValueMax(220).withValueStep(1)
.withDescription('Under-voltage threshold setting'),
],
meta: {
// All datapoints go in here
tuyaDatapoints: [
[1, 'energy', tuya.valueConverter.divideBy100],
[6, null, tuya.valueConverter.phaseVariant2],
[16, 'state', tuya.valueConverter.onOff],
[103, 'under-voltage_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[107, 'temperature_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[116, 'under-voltage_threshold', tuya.valueConverter.raw],
[118, 'temperature_threshold', tuya.valueConverter.divideBy10],
[131, "temperature", tuya.valueConverter.divideBy10],
],
},
};
module.exports = definition;`
I attach the last version. Now it is possible to configure thresholds and settings. Almost everything. There is still a problem that I am not able to solve and frankly speaking I am lost, it is that the device only update electrical measures every 10 minutes even if there are changes in the device power or current consumption. I have checked that in Tuya it updates current, power and voltages changes after few seconds when happens. I do not know if it is something to be configrued in the device or it is done by polling the device, in both cases I do not know how to do it, I neee help in this issue.
const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const moderExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;
const tz_settings = {
key: ['temperature_setting','temperature_threshold','under-voltage_setting','under-voltage_threshold',
'over-current_setting','current_threshold','over-voltage_setting','over-voltage_threshold',
'over-power_setting','over-power_threshold'],
convertSet: async (entity, key, value, meta) => {
const settingType = {'trip': 2, 'alarm': 1, 'closed': 0};
let dp_key = -1; // value if not found
// search feature's dp.
const tuyadatapoints_list = meta.mapped.meta.tuyaDatapoints
for (let i = 0; i < tuyadatapoints_list.length; i++) {
if (tuyadatapoints_list[i][1] === key) {
dp_key = tuyadatapoints_list[i][0];
break;
}
}
switch (key) {
case 'temperature_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'temperature_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value*10);
break;
}
case 'under-voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'under-voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over-voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over-voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over-power_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over-power_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over-current_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'current_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
default: // Unknown key
meta.logger.warn(`Unhandled key ${key}`);
}
},
}
const definition = {
// Since a lot of TuYa devices use the same modelID, but use different datapoints
// it's necessary to provide a fingerprint instead of a zigbeeModel
fingerprint: [
{
// The model ID from: Device with modelID 'TS0601' is not supported
// You may need to add \u0000 at the end of the name in some cases
modelID: 'TS0601',
// The manufacturer name from: Device with modelID 'TS0601' is not supported.
manufacturerName: '_TZE204_mrffaamu',
},
],
model: 'TOQCB2-80',
vendor: 'TuYa',
description: 'Smart Circuit breaker',
fromZigbee: [tuya.fz.datapoints],
toZigbee: [tuya.tz.datapoints,tz_settings],
configure: tuya.configureMagicPacket,
exposes: [tuya.exposes.switch(), e.energy(), e.power(), e.voltage(), e.current(),e.temperature(),
// Here you should put all functionality that your device exposes
e.numeric('forward_electricity', ea.STATE).withUnit('kwh'),
e.enum('over-current_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('current_threshold', ea.STATE_SET).withValueMin(1).withValueMax(63).withValueStep(1).withUnit('A')
.withDescription('Current threshold setting'),
e.enum('under-voltage_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('under-voltage_threshold', ea.STATE_SET).withValueMin(145).withValueMax(220).withValueStep(1).withUnit('V')
.withDescription('Under-voltage threshold setting'),
e.enum('over-voltage_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('over-voltage_threshold', ea.STATE_SET).withValueMin(245).withValueMax(295).withValueStep(1).withUnit('V')
.withDescription('Over-voltage threshold setting'),
e.enum('over-power_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('over-power_threshold', ea.STATE_SET).withValueMin(5).withValueMax(25000).withValueStep(1).withUnit('W')
.withDescription('Over-power threshold setting'),
e.enum('temperature_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('temperature_threshold', ea.STATE_SET).withValueMin(-40).withValueMax(100).withValueStep(1).withUnit('*C')
.withDescription('Temperature threshold setting'),
],
meta: {
// All datapoints go in here
tuyaDatapoints: [
[1, 'energy', tuya.valueConverter.divideBy100],
[6, null, tuya.valueConverter.phaseVariant2],
[16, 'state', tuya.valueConverter.onOff],
[102, 'over-voltage_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[103, 'under-voltage_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[104, 'over-current_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[105, 'over-power_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[107, 'temperature_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
// [109, 'online_state, unknown, I have not seen any message from this DP],
// [110, 'event', enum type, values 11 turn ON 12 turn Off 0 normal ]
// [112, 'automatic_closing, tuya.valueConverter.onOff],
// [113, 'restore_default', pending to define],
[114, 'current_threshold', tuya.valueConverter.raw],
[115, 'over-voltage_threshold', tuya.valueConverter.raw],
[116, 'under-voltage_threshold', tuya.valueConverter.raw],
[118, 'temperature_threshold', tuya.valueConverter.divideBy10],
[119, 'over-power_threshold', tuya.valueConverter.raw],
[125, 'forward_electricity', tuya.valueConverter.divideBy100],
[131, "temperature", tuya.valueConverter.divideBy10],
],
},
};
module.exports = definition;
@true9741 , great job. I add, if there is a trip it indicates the shot, and manual reset. The problem continues, electrical measures update every 10 minutes
const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const moderExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;
const tz_settings = {
key: ['temperature_setting','temperature_threshold','under-voltage_setting','under-voltage_threshold',
'over-current_setting','current_threshold','over-voltage_setting','over-voltage_threshold',
'over-power_setting','over-power_threshold'],
convertSet: async (entity, key, value, meta) => {
const settingType = {'trip': 2, 'alarm': 1, 'closed': 0};
let dp_key = -1; // value if not found
// search feature's dp.
const tuyadatapoints_list = meta.mapped.meta.tuyaDatapoints
for (let i = 0; i < tuyadatapoints_list.length; i++) {
if (tuyadatapoints_list[i][1] === key) {
dp_key = tuyadatapoints_list[i][0];
break;
}
}
switch (key) {
case 'temperature_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'temperature_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value*10);
break;
}
case 'under-voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'under-voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over-voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over-voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over-power_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over-power_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over-current_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'current_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
default: // Unknown key
meta.logger.warn(`Unhandled key ${key}`);
}
},
}
const definition = {
// Since a lot of TuYa devices use the same modelID, but use different datapoints
// it's necessary to provide a fingerprint instead of a zigbeeModel
fingerprint: [
{
// The model ID from: Device with modelID 'TS0601' is not supported
// You may need to add \u0000 at the end of the name in some cases
modelID: 'TS0601',
// The manufacturer name from: Device with modelID 'TS0601' is not supported.
manufacturerName: '_TZE204_mrffaamu',
},
],
model: 'TOQCB2-80',
vendor: 'TuYa',
description: 'Smart Circuit breaker',
configure: async (device, coordinatorEndpoint, logger) => {
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
// set reporting interval of genOnOff to max to "disable" it
// background: genOnOff reporting does not respect timer or button, that makes the on/off reporting pretty useless
// the device is reporting it's state change anyway via tuya DPs
await reporting.onOff(device.getEndpoint(1), {max: 0xffff});
},
fromZigbee: [tuya.fz.datapoints],
toZigbee: [tuya.tz.datapoints,tz_settings],
configure: tuya.configureMagicPacket,
exposes: [tuya.exposes.switch(), e.energy(), e.power(), e.voltage(), e.current(),e.temperature(),
// Here you should put all functionality that your device exposes
e.numeric('forward_electricity', ea.STATE).withUnit('kwh'),
e.enum('over-current_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('current_threshold', ea.STATE_SET).withValueMin(1).withValueMax(63).withValueStep(1).withUnit('A')
.withDescription('Current threshold setting'),
e.enum('under-voltage_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('under-voltage_threshold', ea.STATE_SET).withValueMin(145).withValueMax(220).withValueStep(1).withUnit('V')
.withDescription('Under-voltage threshold setting'),
e.enum('over-voltage_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('over-voltage_threshold', ea.STATE_SET).withValueMin(245).withValueMax(295).withValueStep(1).withUnit('V')
.withDescription('Over-voltage threshold setting'),
e.enum('over-power_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('over-power_threshold', ea.STATE_SET).withValueMin(5).withValueMax(25000).withValueStep(1).withUnit('W')
.withDescription('Over-power threshold setting'),
e.enum('temperature_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('temperature_threshold', ea.STATE_SET).withValueMin(-40).withValueMax(100).withValueStep(1).withUnit('*C')
.withDescription('Temperature threshold setting'),
],
meta: {
// All datapoints go in here
tuyaDatapoints: [
[1, 'energy', tuya.valueConverter.divideBy100],
[6, null, tuya.valueConverter.phaseVariant2],
[16, 'state', tuya.valueConverter.onOff],
[102, 'over-voltage_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[103, 'under-voltage_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[104, 'over-current_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[105, 'over-power_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[107, 'temperature_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
// [109, 'online_state, unknown, I have not seen any message from this DP],
// [110, 'event', enum type, values 11 turn ON 12 turn Off 0 normal ]
// [112, 'automatic_closing, tuya.valueConverter.onOff],
// [113, 'restore_default', pending to define],
[114, 'current_threshold', tuya.valueConverter.raw],
[115, 'over-voltage_threshold', tuya.valueConverter.raw],
[116, 'under-voltage_threshold', tuya.valueConverter.raw],
[118, 'temperature_threshold', tuya.valueConverter.divideBy10],
[119, 'over-power_threshold', tuya.valueConverter.raw],
[125, 'forward_electricity', tuya.valueConverter.divideBy100],
[131, "temperature", tuya.valueConverter.divideBy10],
],
},
};
module.exports = definition;
Hi @joviado,
latest version of the converter. I identify how to update the data by doing a poll, I have maintained it every 3 minutes, I think that with this device it is enough because if there is a shot or an alarm the device sends the message immediately and this poll is only needed to update. voltage, current, power and energy. The device sent about 10 messages to do this and if it has more than one, in my case, it is congesting the zigbee network. I have added the last status/action of the device, it it has an alarm, trip, manual operation or remote operation. Also I have added the switch to Factory settings (it should be use with care), and the switch to clear the last status/action, for example if there was an alarm to reset the event to normal. I have checked that works fine with Homeassistant, for solving some issues with hass, I've changed the names of the dp, removing - with _ in some of them.
Please test it an give me your comments.
const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
// const extend = require('zigbee-herdsman-converters/lib/extend');
const moderExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;
const tz_settings = {
key: ['temperature_setting','temperature_threshold','under_voltage_setting','under_voltage_threshold',
'over_current_setting','current_threshold','over_voltage_setting','over_voltage_threshold',
'over_power_setting','over_power_threshold','restore_default'],
convertSet: async (entity, key, value, meta) => {
const settingType = {'trip': 2, 'alarm': 1, 'closed': 0};
// const typeswitch = {'ON':true, 'OFF':false}
let dp_key = -1; // value if not found
// identify dp.
const tuyadatapoints_list = meta.mapped.meta.tuyaDatapoints
for (let i = 0; i < tuyadatapoints_list.length; i++) {
if (tuyadatapoints_list[i][1] === key) {
dp_key = tuyadatapoints_list[i][0];
break;
}
}
switch (key) {
case 'temperature_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'temperature_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value*10);
break;
}
case 'under_voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'under_voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over_voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_power_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over_power_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_current_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'current_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
default: // Unknown key
meta.logger.warn(`Unhandled key ${key}`);
}
},
}
const definition = {
// Since a lot of TuYa devices use the same modelID, but use different datapoints
// it's necessary to provide a fingerprint instead of a zigbeeModel
fingerprint: [
{
// The model ID from: Device with modelID 'TS0601' is not supported
// You may need to add \u0000 at the end of the name in some cases
modelID: 'TS0601',
// The manufacturer name from: Device with modelID 'TS0601' is not supported.
manufacturerName: '_TZE204_mrffaamu',
},
],
model: 'TOQCB2-80',
vendor: 'TuYa',
description: 'Smart Circuit breaker',
fromZigbee: [tuya.fz.datapoints],
toZigbee: [tuya.tz.datapoints,tz_settings],
// Important: respondToMcuVersionResponse should be false otherweise there are an avalanche of commandMcuVersionResponse messages every second.
// queryIntervalSeconds: is doing a pooling to update device's parameters, now define to update data every 3 minutes.
onEvent: tuya.onEvent({respondToMcuVersionResponse:false, queryIntervalSeconds: 3 * 60}),
configure: tuya.configureMagicPacket,
exposes: [tuya.exposes.switch(), e.energy(), e.power(), e.voltage(), e.current(),e.temperature(),
// Here you should put all functionality that your device exposes
e.numeric('forward_electricity', ea.STATE).withUnit('kwh'),
e.enum('last_event1', ea.STATE, ['Normal', 'Trip_Over-current', 'Trip_Over-power', 'Trip_Over-temperature', 'Trip_voltage_1',
'Trip_voltage_2', 'Alarm_Over-current', 'Alarm_Over-power', 'Alarm_Over-temperature','Alarm_voltage_1', 'Alarm_voltage_2',
'Remote-ON','Remote-OFF','Manual-ON','Manual-OFF', 'Value_15', 'Value_16', 'Factory_reset'])
.withDescription('Last event'),
e.enum('over_current_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('current_threshold', ea.STATE_SET).withValueMin(1).withValueMax(63).withValueStep(1).withUnit('A')
.withDescription('Current threshold setting'),
e.enum('under_voltage_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('under_voltage_threshold', ea.STATE_SET).withValueMin(145).withValueMax(220).withValueStep(1).withUnit('V')
.withDescription('Under_voltage threshold setting'),
e.enum('over_voltage_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('over_voltage_threshold', ea.STATE_SET).withValueMin(245).withValueMax(295).withValueStep(1).withUnit('V')
.withDescription('Over-voltage threshold setting'),
e.enum('over_power_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('over_power_threshold', ea.STATE_SET).withValueMin(200).withValueMax(20000).withValueStep(100).withUnit('W')
.withDescription('Over-power threshold setting'),
e.enum('temperature_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('temperature_threshold', ea.STATE_SET).withValueMin(-40).withValueMax(100).withValueStep(1).withUnit('*C')
.withDescription('Temperature threshold setting'),
e.binary('clear_fault', ea.STATE_SET, 'ON', 'OFF')
.withDescription('Recover from an incident'),
e.binary('factory_reset', ea.STATE_SET, 'ON', 'OFF')
.withDescription('Back to factory settings, USE WITH CAUTION'),
],
meta: {
// All datapoints go in here
tuyaDatapoints: [
[1, 'energy', tuya.valueConverter.divideBy100],
[6, null, tuya.valueConverter.phaseVariant2],
[16, 'state', tuya.valueConverter.onOff],
[102, 'over_voltage_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[103, 'under_voltage_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[104, 'over_current_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[105, 'over_power_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[107, 'temperature_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
// [109, 'online_state, unknown, I have not seen any message from this DP],
[110, 'last_event1', tuya.valueConverterBasic.lookup(
{'Normal': tuya.enum(0), 'Trip_Over-current': tuya.enum(1), 'Trip_Over-power': tuya.enum(2),
'Trip_Over-temperature': tuya.enum(3), 'Trip_voltage_1': tuya.enum(4), 'Trip_voltage_2': tuya.enum(5),
'Alarm_Over-current': tuya.enum(6), 'Alarm_Over-power': tuya.enum(7), 'Alarm_Over-temperature': tuya.enum(8),
'Alarm_voltage_1': tuya.enum(9), 'Alarm_voltage_2': tuya.enum(10), 'Remote-ON': tuya.enum(11),
'Remote-OFF': tuya.enum(12), 'Manual-ON': tuya.enum(13), 'Manual-OFF': tuya.enum(14),
'Value_15': tuya.enum(15), 'Value_16': tuya.enum(16), 'Factory_reset': tuya.enum(17)})],
[112, 'clear_fault', tuya.valueConverter.onOff],
[113, 'factory_reset', tuya.valueConverter.onOff],
[114, 'current_threshold', tuya.valueConverter.raw],
[115, 'over_voltage_threshold', tuya.valueConverter.raw],
[116, 'under_voltage_threshold', tuya.valueConverter.raw],
[118, 'temperature_threshold', tuya.valueConverter.divideBy10],
[119, 'over_power_threshold', tuya.valueConverter.raw],
[125, 'forward_electricity', tuya.valueConverter.divideBy100],
[131, "temperature", tuya.valueConverter.divideBy10],
],
},
};
module.exports = definition;
Hi @Koenkk,
I am new on doing converters and I need your help with one thing that could be a potencial problem and another two things that I am sure could be improved in my converter but frankly speaking I do not know how to do it, I need some hints.
I started with the potencial problem.
debug 2024-04-02 16:00:44: Received Zigbee message from 'pia_sa', type 'commandMcuVersionResponse', cluster 'manuSpecificTuya', data '{"seq":1053,"version":79}' from endpoint 1 with groupID 0
debug 2024-04-02 16:00:44: No converter available for 'TOQCB2-80' with cluster 'manuSpecificTuya' and type 'commandMcuVersionResponse' and data '{"seq":1053,"version":79}'
debug 2024-04-02 16:00:44: Received Zigbee message from 'pia_sa', type 'commandMcuVersionResponse', cluster 'manuSpecificTuya', data '{"seq":1565,"version":79}' from endpoint 1 with groupID 0
debug 2024-04-02 16:00:44: No converter available for 'TOQCB2-80' with cluster 'manuSpecificTuya' and type 'commandMcuVersionResponse' and data '{"seq":1565,"version":79}'
debug 2024-04-02 16:00:44: Received Zigbee message from 'pia_sa', type 'commandMcuVersionResponse', cluster 'manuSpecificTuya', data '{"seq":2077,"version":79}' from endpoint 1 with groupID 0
debug 2024-04-02 16:00:44: No converter available for 'TOQCB2-80' with cluster 'manuSpecificTuya' and type 'commandMcuVersionResponse' and data '{"seq":2077,"version":79}'
debug 2024-04-02 16:00:44: Received Zigbee message from 'pia_sa', type 'commandMcuVersionResponse', cluster 'manuSpecificTuya', data '{"seq":2589,"version":79}' from endpoint 1 with groupID 0
debug 2024-04-02 16:00:44: No converter available for 'TOQCB2-80' with cluster 'manuSpecificTuya' and type 'commandMcuVersionResponse' and data '{"seq":2589,"version":79}'
debug 2024-04-02 16:00:44: Received Zigbee message from 'pia_sa', type 'commandMcuVersionResponse', cluster 'manuSpecificTuya', data '{"seq":3101,"version":79}' from endpoint 1 with groupID 0
debug 2024-04-02 16:00:44: No converter available for 'TOQCB2-80' with cluster 'manuSpecificTuya' and type 'commandMcuVersionResponse' and data '{"seq":3101,"version":79}'
debug 2024-04-02 16:00:44: Received Zigbee message from 'pia_sa', type 'commandMcuVersionResponse', cluster 'manuSpecificTuya', data '{"seq":3613,"version":79}' from endpoint 1 with groupID 0
debug 2024-04-02 16:00:44: No converter available for 'TOQCB2-80' with cluster 'manuSpecificTuya' and type 'commandMcuVersionResponse' and data '{"seq":3613,"version":79}'
debug 2024-04-02 16:00:45: Received Zigbee message from 'pia_sa', type 'commandMcuVersionResponse', cluster 'manuSpecificTuya', data '{"seq":4125,"version":79}' from endpoint 1 with groupID 0
debug 2024-04-02 16:00:45: No converter available for 'TOQCB2-80' with cluster 'manuSpecificTuya' and type 'commandMcuVersionResponse' and data '{"seq":4125,"version":79}'
debug 2024-04-02 16:00:45: Received Zigbee message from 'pia_sa', type 'commandMcuVersionResponse', cluster 'manuSpecificTuya', data '{"seq":4637,"version":79}' from endpoint 1 with groupID 0
debug 2024-04-02 16:00:45: No converter available for 'TOQCB2-80' with cluster 'manuSpecificTuya' and type 'commandMcuVersionResponse' and data '{"seq":4637,"version":79}'
I checked the onEvent function but couldn't understand why. My concern is that I forget something that could cause problems in the future. I'm sure you could tell if there's a potential problem here, just to be sure.
Possible improvements.
I attach the converter
const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
// const extend = require('zigbee-herdsman-converters/lib/extend');
const moderExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;
const tz_settings = {
key: ['temperature_setting','temperature_threshold','under_voltage_setting','under_voltage_threshold',
'over_current_setting','current_threshold','over_voltage_setting','over_voltage_threshold',
'over_power_setting','over_power_threshold','restore_default'],
convertSet: async (entity, key, value, meta) => {
const settingType = {'trip': 2, 'alarm': 1, 'closed': 0};
// const typeswitch = {'ON':true, 'OFF':false}
let dp_key = -1; // value if not found
// identify dp.
const tuyadatapoints_list = meta.mapped.meta.tuyaDatapoints
for (let i = 0; i < tuyadatapoints_list.length; i++) {
if (tuyadatapoints_list[i][1] === key) {
dp_key = tuyadatapoints_list[i][0];
break;
}
}
switch (key) {
case 'temperature_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'temperature_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value*10);
break;
}
case 'under_voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'under_voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over_voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_power_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over_power_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_current_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'current_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
default: // Unknown key
meta.logger.warn(`Unhandled key ${key}`);
}
},
}
const definition = {
// Since a lot of TuYa devices use the same modelID, but use different datapoints
// it's necessary to provide a fingerprint instead of a zigbeeModel
fingerprint: [
{
// The model ID from: Device with modelID 'TS0601' is not supported
// You may need to add \u0000 at the end of the name in some cases
modelID: 'TS0601',
// The manufacturer name from: Device with modelID 'TS0601' is not supported.
manufacturerName: '_TZE204_mrffaamu',
},
],
model: 'TOQCB2-80',
vendor: 'TuYa',
description: 'Smart Circuit breaker',
fromZigbee: [tuya.fz.datapoints],
toZigbee: [tuya.tz.datapoints,tz_settings],
// Important: respondToMcuVersionResponse should be false otherweise there are an avalanche of commandMcuVersionResponse messages every second.
// queryIntervalSeconds: is doing a pooling to update device's parameters, now define to update data every 3 minutes.
onEvent: tuya.onEvent({respondToMcuVersionResponse:false, queryIntervalSeconds: 3 * 60}),
configure: tuya.configureMagicPacket,
exposes: [tuya.exposes.switch(), e.energy(), e.power(), e.voltage(), e.current(),e.temperature(),
// Here you should put all functionality that your device exposes
e.numeric('forward_electricity', ea.STATE).withUnit('kwh'),
e.enum('last_event1', ea.STATE, ['Normal', 'Trip_Over-current', 'Trip_Over-power', 'Trip_Over-temperature', 'Trip_voltage_1',
'Trip_voltage_2', 'Alarm_Over-current', 'Alarm_Over-power', 'Alarm_Over-temperature','Alarm_voltage_1', 'Alarm_voltage_2',
'Remote-ON','Remote-OFF','Manual-ON','Manual-OFF', 'Value_15', 'Value_16', 'Factory_reset'])
.withDescription('Last event'),
e.enum('over_current_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('current_threshold', ea.STATE_SET).withValueMin(1).withValueMax(63).withValueStep(1).withUnit('A')
.withDescription('Current threshold setting'),
e.enum('under_voltage_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('under_voltage_threshold', ea.STATE_SET).withValueMin(145).withValueMax(220).withValueStep(1).withUnit('V')
.withDescription('Under_voltage threshold setting'),
e.enum('over_voltage_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('over_voltage_threshold', ea.STATE_SET).withValueMin(245).withValueMax(295).withValueStep(1).withUnit('V')
.withDescription('Over-voltage threshold setting'),
e.enum('over_power_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('over_power_threshold', ea.STATE_SET).withValueMin(200).withValueMax(20000).withValueStep(100).withUnit('W')
.withDescription('Over-power threshold setting'),
e.enum('temperature_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('temperature_threshold', ea.STATE_SET).withValueMin(-40).withValueMax(100).withValueStep(1).withUnit('*C')
.withDescription('Temperature threshold setting'),
e.binary('clear_fault', ea.STATE_SET, 'ON', 'OFF')
.withDescription('Recover from an incident'),
e.binary('factory_reset', ea.STATE_SET, 'ON', 'OFF')
.withDescription('Back to factory settings, USE WITH CAUTION'),
],
meta: {
// All datapoints go in here
tuyaDatapoints: [
[1, 'energy', tuya.valueConverter.divideBy100],
[6, null, tuya.valueConverter.phaseVariant2],
[16, 'state', tuya.valueConverter.onOff],
[102, 'over_voltage_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[103, 'under_voltage_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[104, 'over_current_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[105, 'over_power_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[107, 'temperature_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
// [109, 'online_state, unknown, I have not seen any message from this DP],
[110, 'last_event1', tuya.valueConverterBasic.lookup(
{'Normal': tuya.enum(0), 'Trip_Over-current': tuya.enum(1), 'Trip_Over-power': tuya.enum(2),
'Trip_Over-temperature': tuya.enum(3), 'Trip_voltage_1': tuya.enum(4), 'Trip_voltage_2': tuya.enum(5),
'Alarm_Over-current': tuya.enum(6), 'Alarm_Over-power': tuya.enum(7), 'Alarm_Over-temperature': tuya.enum(8),
'Alarm_voltage_1': tuya.enum(9), 'Alarm_voltage_2': tuya.enum(10), 'Remote-ON': tuya.enum(11),
'Remote-OFF': tuya.enum(12), 'Manual-ON': tuya.enum(13), 'Manual-OFF': tuya.enum(14),
'Value_15': tuya.enum(15), 'Value_16': tuya.enum(16), 'Factory_reset': tuya.enum(17)})],
[112, 'clear_fault', tuya.valueConverter.onOff],
[113, 'factory_reset', tuya.valueConverter.onOff],
[114, 'current_threshold', tuya.valueConverter.raw],
[115, 'over_voltage_threshold', tuya.valueConverter.raw],
[116, 'under_voltage_threshold', tuya.valueConverter.raw],
[118, 'temperature_threshold', tuya.valueConverter.divideBy10],
[119, 'over_power_threshold', tuya.valueConverter.raw],
[125, 'forward_electricity', tuya.valueConverter.divideBy100],
[131, "temperature", tuya.valueConverter.divideBy10],
],
},
};
module.exports = definition;
Thanks for your help in advance.
Do we have any update on this? Is it still open or completed?
Hello Guys,
from https://github.com/Koenkk/zigbee2mqtt/issues/21116
i have added the parts for voltage, current and power for every single phase to "exposes":
(...) tuya.exposes.voltageWithPhase('a'), tuya.exposes.voltageWithPhase('b'), tuya.exposes.voltageWithPhase('c'), tuya.exposes.powerWithPhase('a'), tuya.exposes.powerWithPhase('b'), tuya.exposes.powerWithPhase('c'), tuya.exposes.currentWithPhase('a'), tuya.exposes.currentWithPhase('b'), tuya.exposes.currentWithPhase('c'), (...)
and within the "meta"-section:
[6, null, tuya.valueConverter.phaseVariant2WithPhase('a')], [7, null, tuya.valueConverter.phaseVariant2WithPhase('b')], [8, null, tuya.valueConverter.phaseVariant2WithPhase('c')],
so the converter now looks like:
const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
// const extend = require('zigbee-herdsman-converters/lib/extend');
const moderExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;
const tz_settings = {
key: ['temperature_setting','temperature_threshold','under_voltage_setting','under_voltage_threshold',
'over_current_setting','current_threshold','over_voltage_setting','over_voltage_threshold',
'over_power_setting','over_power_threshold','restore_default'],
convertSet: async (entity, key, value, meta) => {
const settingType = {'trip': 2, 'alarm': 1, 'closed': 0};
// const typeswitch = {'ON':true, 'OFF':false}
let dp_key = -1; // value if not found
// identify dp.
const tuyadatapoints_list = meta.mapped.meta.tuyaDatapoints
for (let i = 0; i < tuyadatapoints_list.length; i++) {
if (tuyadatapoints_list[i][1] === key) {
dp_key = tuyadatapoints_list[i][0];
break;
}
}
switch (key) {
case 'temperature_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'temperature_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value*10);
break;
}
case 'under_voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'under_voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over_voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_power_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over_power_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_current_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'current_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
default: // Unknown key
meta.logger.warn(`Unhandled key ${key}`);
}
},
}
const definition = {
// Since a lot of TuYa devices use the same modelID, but use different datapoints
// it's necessary to provide a fingerprint instead of a zigbeeModel
fingerprint: [
{
// The model ID from: Device with modelID 'TS0601' is not supported
// You may need to add \u0000 at the end of the name in some cases
modelID: 'TS0601',
// The manufacturer name from: Device with modelID 'TS0601' is not supported.
manufacturerName: '_TZE204_q22avxbv',
},
],
model: 'TOQCB2-80',
vendor: 'TuYa',
description: 'Smart Circuit breaker',
fromZigbee: [tuya.fz.datapoints],
toZigbee: [tuya.tz.datapoints,tz_settings],
// Important: respondToMcuVersionResponse should be false otherweise there are an avalanche of commandMcuVersionResponse messages every second.
// queryIntervalSeconds: is doing a pooling to update device's parameters, now define to update data every 3 minutes.
onEvent: tuya.onEvent({respondToMcuVersionResponse:false, queryIntervalSeconds: 3 * 60}),
configure: tuya.configureMagicPacket,
exposes: [tuya.exposes.switch(), e.energy(), e.power(), e.voltage(), e.current(), e.temperature(),
//-----NEU-----//
//Ergänzung Messung einzelne Phasen
tuya.exposes.voltageWithPhase('a'), tuya.exposes.voltageWithPhase('b'), tuya.exposes.voltageWithPhase('c'),
tuya.exposes.powerWithPhase('a'), tuya.exposes.powerWithPhase('b'), tuya.exposes.powerWithPhase('c'),
tuya.exposes.currentWithPhase('a'), tuya.exposes.currentWithPhase('b'), tuya.exposes.currentWithPhase('c'),
//-------------//
// Here you should put all functionality that your device exposes
e.numeric('forward_electricity', ea.STATE).withUnit('kwh'),
e.enum('last_event1', ea.STATE, ['Normal', 'Trip_Over-current', 'Trip_Over-power', 'Trip_Over-temperature', 'Trip_voltage_1',
'Trip_voltage_2', 'Alarm_Over-current', 'Alarm_Over-power', 'Alarm_Over-temperature','Alarm_voltage_1', 'Alarm_voltage_2',
'Remote-ON','Remote-OFF','Manual-ON','Manual-OFF', 'Value_15', 'Value_16', 'Factory_reset'])
.withDescription('Last event'),
e.enum('over_current_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('current_threshold', ea.STATE_SET).withValueMin(1).withValueMax(63).withValueStep(1).withUnit('A')
.withDescription('Current threshold setting'),
e.enum('under_voltage_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('under_voltage_threshold', ea.STATE_SET).withValueMin(145).withValueMax(220).withValueStep(1).withUnit('V')
.withDescription('Under_voltage threshold setting'),
e.enum('over_voltage_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('over_voltage_threshold', ea.STATE_SET).withValueMin(245).withValueMax(295).withValueStep(1).withUnit('V')
.withDescription('Over-voltage threshold setting'),
e.enum('over_power_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('over_power_threshold', ea.STATE_SET).withValueMin(200).withValueMax(20000).withValueStep(100).withUnit('W')
.withDescription('Over-power threshold setting'),
e.enum('temperature_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('temperature_threshold', ea.STATE_SET).withValueMin(-40).withValueMax(100).withValueStep(1).withUnit('*C')
.withDescription('Temperature threshold setting'),
e.binary('clear_fault', ea.STATE_SET, 'ON', 'OFF')
.withDescription('Recover from an incident'),
e.binary('factory_reset', ea.STATE_SET, 'ON', 'OFF')
.withDescription('Back to factory settings, USE WITH CAUTION'),
],
meta: {
// All datapoints go in here
tuyaDatapoints: [
[1, 'energy', tuya.valueConverter.divideBy100],
//-----ALT-----//
//[6, null, tuya.valueConverter.phaseVariant2],
//-------------//
//-----NEU-----//
[3, null, null], // Monthly, but sends data only after request
[4, null, null], // Dayly, but sends data only after request
[6, null, tuya.valueConverter.phaseVariant2WithPhase('a')],
[7, null, tuya.valueConverter.phaseVariant2WithPhase('b')],
[8, null, tuya.valueConverter.phaseVariant2WithPhase('c')],
//-------------//
[16, 'state', tuya.valueConverter.onOff],
[102, 'over_voltage_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[103, 'under_voltage_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[104, 'over_current_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[105, 'over_power_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[107, 'temperature_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
// [109, 'online_state, unknown, I have not seen any message from this DP],
[110, 'last_event1', tuya.valueConverterBasic.lookup(
{'Normal': tuya.enum(0), 'Trip_Over-current': tuya.enum(1), 'Trip_Over-power': tuya.enum(2),
'Trip_Over-temperature': tuya.enum(3), 'Trip_voltage_1': tuya.enum(4), 'Trip_voltage_2': tuya.enum(5),
'Alarm_Over-current': tuya.enum(6), 'Alarm_Over-power': tuya.enum(7), 'Alarm_Over-temperature': tuya.enum(8),
'Alarm_voltage_1': tuya.enum(9), 'Alarm_voltage_2': tuya.enum(10), 'Remote-ON': tuya.enum(11),
'Remote-OFF': tuya.enum(12), 'Manual-ON': tuya.enum(13), 'Manual-OFF': tuya.enum(14),
'Value_15': tuya.enum(15), 'Value_16': tuya.enum(16), 'Factory_reset': tuya.enum(17)})],
[112, 'clear_fault', tuya.valueConverter.onOff],
[113, 'factory_reset', tuya.valueConverter.onOff],
[114, 'current_threshold', tuya.valueConverter.raw],
[115, 'over_voltage_threshold', tuya.valueConverter.raw],
[116, 'under_voltage_threshold', tuya.valueConverter.raw],
[118, 'temperature_threshold', tuya.valueConverter.divideBy10],
[119, 'over_power_threshold', tuya.valueConverter.raw],
[125, 'forward_electricity', tuya.valueConverter.divideBy100],
[131, "temperature", tuya.valueConverter.divideBy10],
],
},
};
module.exports = definition;
With this changes to voltage, current and power for each Phase is now shown correectly.
I Think, the exposes
e.power(), e.voltage(), e.current(),
are now unnecessary (they all report now "0").
The Datapoint
[125, 'forward_electricity', tuya.valueConverter.divideBy100],
reports the energy from only on Phase (L1), and is in my opinion also unecessary, because i couldn´t determine, how to replicate this for all three Phases (I don´t have a Thuya Gateway, so can´t find other datapoints, try and error gives no usable result).
The only Problem i´m experiencing now is, that sometimes there is an
Alarm_voltage_1
under events.
Maybe someone could classify this correctly or make a PR for this converter.
For the device-picture and documentation i had already made a PR (or tried it...):
here is the PR for this:
https://github.com/Koenkk/zigbee-herdsman-converters/pull/7752#issuecomment-2214289716
Reported Values are shown correct now with native support of this device.
Although i´m now having problems with setting thresholds (over-current-/-voltage-/-power-/-temperature- and under-voltage-setting) and their respective actions (closed, alarm, trip). Every time, i want to change a threshold or a specific action it gives me the error (for example for "over_power_setting"):
z2m: No converter available for 'over_power_setting' ("closed")
If I´m using the following external converter:
const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
// const extend = require('zigbee-herdsman-converters/lib/extend');
const moderExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;
const tz_settings = {
key: ['temperature_setting','temperature_threshold','under_voltage_setting','under_voltage_threshold',
'over_current_setting','current_threshold','over_voltage_setting','over_voltage_threshold',
'over_power_setting','over_power_threshold','restore_default'],
convertSet: async (entity, key, value, meta) => {
const settingType = {'trip': 2, 'alarm': 1, 'closed': 0};
// const typeswitch = {'ON':true, 'OFF':false}
let dp_key = -1; // value if not found
// identify dp.
const tuyadatapoints_list = meta.mapped.meta.tuyaDatapoints
for (let i = 0; i < tuyadatapoints_list.length; i++) {
if (tuyadatapoints_list[i][1] === key) {
dp_key = tuyadatapoints_list[i][0];
break;
}
}
switch (key) {
case 'temperature_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'temperature_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value*10);
break;
}
case 'under_voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'under_voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over_voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_power_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over_power_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_current_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'current_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
default: // Unknown key
meta.logger.warn(`Unhandled key ${key}`);
}
},
}
const definition = {
// Since a lot of TuYa devices use the same modelID, but use different datapoints
// it's necessary to provide a fingerprint instead of a zigbeeModel
fingerprint: [
{
// The model ID from: Device with modelID 'TS0601' is not supported
// You may need to add \u0000 at the end of the name in some cases
modelID: 'TS0601',
// The manufacturer name from: Device with modelID 'TS0601' is not supported.
manufacturerName: '_TZE204_q22avxbv',
},
],
model: 'TOQCB2-80',
vendor: 'TuYa',
description: 'Smart Circuit breaker',
fromZigbee: [tuya.fz.datapoints],
toZigbee: [tuya.tz.datapoints,tz_settings],
// Important: respondToMcuVersionResponse should be false otherweise there are an avalanche of commandMcuVersionResponse messages every second.
// queryIntervalSeconds: is doing a pooling to update device's parameters, now define to update data every 3 minutes.
onEvent: tuya.onEvent({respondToMcuVersionResponse:false, queryIntervalSeconds: 3 * 60}),
configure: tuya.configureMagicPacket,
exposes: [tuya.exposes.switch(), e.energy(), e.power(), e.voltage(), e.current(), e.temperature(),
//-----NEU-----//
//Ergänzung Messung einzelne Phasen, 04.07.2024
tuya.exposes.voltageWithPhase('a'), tuya.exposes.voltageWithPhase('b'), tuya.exposes.voltageWithPhase('c'),
tuya.exposes.powerWithPhase('a'), tuya.exposes.powerWithPhase('b'), tuya.exposes.powerWithPhase('c'),
tuya.exposes.currentWithPhase('a'), tuya.exposes.currentWithPhase('b'), tuya.exposes.currentWithPhase('c'),
//-------------//
// Here you should put all functionality that your device exposes
//e.numeric('forward_electricity', ea.STATE).withUnit('kwh'),
e.enum('last_event', ea.STATE, ['Normal', 'Trip_Over-current', 'Trip_Over-power', 'Trip_Over-temperature', 'Trip_voltage_1',
'Trip_voltage_2', 'Alarm_Over-current', 'Alarm_Over-power', 'Alarm_Over-temperature','Alarm_voltage_1', 'Alarm_voltage_2',
'Remote-ON','Remote-OFF','Manual-ON','Manual-OFF', 'Value_15', 'Value_16', 'Factory_reset'])
.withDescription('Last event'),
e.enum('over_current_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('current_threshold', ea.STATE_SET).withValueMin(1).withValueMax(63).withValueStep(1).withUnit('A')
.withDescription('Current threshold setting'),
e.enum('under_voltage_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('under_voltage_threshold', ea.STATE_SET).withValueMin(145).withValueMax(220).withValueStep(1).withUnit('V')
.withDescription('Under_voltage threshold setting'),
e.enum('over_voltage_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('over_voltage_threshold', ea.STATE_SET).withValueMin(245).withValueMax(295).withValueStep(1).withUnit('V')
.withDescription('Over-voltage threshold setting'),
e.enum('over_power_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('over_power_threshold', ea.STATE_SET).withValueMin(200).withValueMax(20000).withValueStep(100).withUnit('W')
.withDescription('Over-power threshold setting'),
e.enum('temperature_setting', ea.STATE_SET, ['closed', 'alarm', 'trip'])
.withDescription('Action if threshold value is reached'),
e.numeric('temperature_threshold', ea.STATE_SET).withValueMin(-40).withValueMax(100).withValueStep(1).withUnit('*C')
.withDescription('Temperature threshold setting'),
e.binary('clear_fault', ea.STATE_SET, 'ON', 'OFF')
.withDescription('Recover from an incident'),
e.binary('factory_reset', ea.STATE_SET, 'ON', 'OFF')
.withDescription('Back to factory settings, USE WITH CAUTION'),
],
meta: {
// All datapoints go in here
tuyaDatapoints: [
[1, 'energy', tuya.valueConverter.divideBy100],
//-----ALT-----//
//[6, null, tuya.valueConverter.phaseVariant2],
//-------------//
//-----NEU-----//
[3, null, null], // Monthly, but sends data only after request
[4, null, null], // Dayly, but sends data only after request
[6, null, tuya.valueConverter.phaseVariant2WithPhase('a')],
[7, null, tuya.valueConverter.phaseVariant2WithPhase('b')],
[8, null, tuya.valueConverter.phaseVariant2WithPhase('c')],
//-------------//
[16, 'state', tuya.valueConverter.onOff],
[102, 'over_voltage_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[103, 'under_voltage_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[104, 'over_current_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[105, 'over_power_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
[107, 'temperature_setting', tuya.valueConverterBasic.lookup(
{'closed': tuya.enum(0), 'alarm': tuya.enum(1), 'trip': tuya.enum(2)})],
// [109, 'online_state, unknown, I have not seen any message from this DP],
[110, 'last_event', tuya.valueConverterBasic.lookup(
{'Normal': tuya.enum(0), 'Trip_Over-current': tuya.enum(1), 'Trip_Over-power': tuya.enum(2),
'Trip_Over-temperature': tuya.enum(3), 'Trip_voltage_1': tuya.enum(4), 'Trip_voltage_2': tuya.enum(5),
'Alarm_Over-current': tuya.enum(6), 'Alarm_Over-power': tuya.enum(7), 'Alarm_Over-temperature': tuya.enum(8),
'Alarm_voltage_1': tuya.enum(9), 'Alarm_voltage_2': tuya.enum(10), 'Remote-ON': tuya.enum(11),
'Remote-OFF': tuya.enum(12), 'Manual-ON': tuya.enum(13), 'Manual-OFF': tuya.enum(14),
'Value_15': tuya.enum(15), 'Value_16': tuya.enum(16), 'Factory_reset': tuya.enum(17)})],
[112, 'clear_fault', tuya.valueConverter.onOff],
[113, 'factory_reset', tuya.valueConverter.onOff],
[114, 'current_threshold', tuya.valueConverter.raw],
[115, 'over_voltage_threshold', tuya.valueConverter.raw],
[116, 'under_voltage_threshold', tuya.valueConverter.raw],
[118, 'temperature_threshold', tuya.valueConverter.divideBy10],
[119, 'over_power_threshold', tuya.valueConverter.raw],
//[125, 'forward_electricity', tuya.valueConverter.divideBy100],
[131, "temperature", tuya.valueConverter.divideBy10],
],
},
};
module.exports = definition;
All is working as expected. The only Difference from this external converter to the original file "tuya.ts" is the missing part
const tz_settings = {...}
Do we need to add this:
const tz_settings = {
key: ['temperature_setting','temperature_threshold','under_voltage_setting','under_voltage_threshold',
'over_current_setting','current_threshold','over_voltage_setting','over_voltage_threshold',
'over_power_setting','over_power_threshold','restore_default'],
convertSet: async (entity, key, value, meta) => {
const settingType = {'trip': 2, 'alarm': 1, 'closed': 0};
// const typeswitch = {'ON':true, 'OFF':false}
let dp_key = -1; // value if not found
// identify dp.
const tuyadatapoints_list = meta.mapped.meta.tuyaDatapoints
for (let i = 0; i < tuyadatapoints_list.length; i++) {
if (tuyadatapoints_list[i][1] === key) {
dp_key = tuyadatapoints_list[i][0];
break;
}
}
switch (key) {
case 'temperature_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'temperature_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value*10);
break;
}
case 'under_voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'under_voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_voltage_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over_voltage_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_power_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'over_power_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
case 'over_current_setting': {
await tuya.sendDataPointEnum(entity, dp_key, utils.getFromLookup(value, settingType));
break;
}
case 'current_threshold': {
await tuya.sendDataPointValue(entity, dp_key, value);
break;
}
default: // Unknown key
meta.logger.warn(`Unhandled key ${key}`);
}
},
}
somewhere behind line 262
const tzLocal = {
and quote it at actuall line 10502
toZigbee: [tuya.tz.datapoints,tz_settings],
So that this is working for this Device ? Maybe we could then rename "tz_settings" to something like "TOQCB2-80_settings".
Best regards
Hi sorry if this is not the place to mention this:
I just received this circuit breaker (TOQCB2-80) bought in Aliexpress https://www.aliexpress.com/item/1005006987624792.html
I installed Z2M edge to have the support included here, but it seems that it is named here as _TZE204_mrffaamu and in my Z2M is appearing as _TZE284_mrffaamu:
Thank you!!
Hi sorry if this is not the place to mention this:
I just received this circuit breaker (TOQCB2-80) bought in Aliexpress https://www.aliexpress.com/item/1005006987624792.html
I installed Z2M edge to have the support included here, but it seems that it is named here as _TZE204_mrffaamu and in my Z2M is appearing as _TZE284_mrffaamu:
Thank you!!
Do you have the 4p Circuit Breaker or 2/3-pole version? if it is the 4-pole -version, we can add the fingerprint "_TZE284_mrffaamu" to the model, so that it can be detected correctly.
However, we currently still have a problem with the native support when it comes to make settings like "over-voltage-threshold" and so on (see https://github.com/Koenkk/zigbee2mqtt/issues/21943#issuecomment-2228302694 above).
Thank you. It is the 2 pole version. I'm aware of the problem per your comment above.
Link
https://es.aliexpress.com/item/1005006420715418.html?spm=a2g0o.order_list.order_list_main.88.284f194daJGf7d&gatewayAdapt=glo2esp
Database entry
{"id":24,"type":"Router","ieeeAddr":"0x943469fffedbdbb6","nwkAddr":20494,"manufId":4098,"manufName":"_TZE204_mrffaamu","powerSource":"Mains (single phase)","modelId":"TS0601","epList":[1],"endpoints":{"1":{"profId":260,"epId":1,"devId":81,"inClusterList":[0,4,5,61184],"outClusterList":[25,10],"clusters":{"genBasic":{"attributes":{"65503":"P��-iP��-iP��-iP��-iP��-iP��-iP��-iP��-i","65506":31,"65508":0,"65534":0,"modelId":"TS0601","manufacturerName":"_TZE204_mrffaamu","stackVersion":0,"dateCode":"","appVersion":70,"zclVersion":3,"powerSource":1}}},"binds":[{"cluster":6,"type":"endpoint","deviceIeeeAddress":"0x00124b002a2ec85d","endpointID":1}],"configuredReportings":[],"meta":{}}},"appVersion":70,"stackVersion":0,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"meta":{"configured":-708457359},"lastSeen":1711389817517}
Comments
Hello! Please add or help me to make a full converter for this equipment . It is not currently supported in z2m. https://github.com/Koenkk/zigbee2mqtt/issues/21116 It looks similar, but it is incomplete. I'm hooked and I don't know how to complete it all.
Data Points: "1":"Total forward energy", "6":"Phase A", "16":"Switch", "102":"Over-voltage setting", "103":"Under-voltage setting", "104":"Over-current setting", "105":"Over-power setting", "107":"Temperature setting", "109":"Online state", "110":"Event", "112":"Automatic closing switch", "113":"Restore default switch", "114":"Current threshold", "115":"Over-voltage threshold", "116":"Under-voltage threshold", "118":"Temperature threshold", "119":"Over-power threshold", "125":"Forward electricity", "131":"Real-time Temp"
External definition