Koenkk / zigbee2mqtt

Zigbee 🐝 to MQTT bridge 🌉, get rid of your proprietary Zigbee bridges 🔨
https://www.zigbee2mqtt.io
GNU General Public License v3.0
11.5k stars 1.63k forks source link

[New device support]: OXT (tuya) T363s 3 Phase power meter #21886

Open BartRuSec opened 3 months ago

BartRuSec commented 3 months ago

Link

https://houseiq.pl/pl/p/OXT-licznik-3-fazy-2-kierunkowy-ZigBee-TUYA/1859 https://pl.aliexpress.com/item/1005003481560370.html

Database entry

{"id":10,"type":"Router","ieeeAddr":"0x943469fffec65a4a","nwkAddr":43048,"manufId":4098,"manufName":"_TZE200_bkkmqmyo","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":"���-i���-i","65506":31,"65508":0,"65534":0,"modelId":"TS0601","manufacturerName":"_TZE200_bkkmqmyo","stackVersion":0,"dateCode":"","zclVersion":3,"appVersion":65,"powerSource":1}}},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":65,"stackVersion":0,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"meta":{"configured":-708457359},"lastSeen":1710942569728}

Comments

Now It is wrongly recognized as Hiking DDS238-2 . Following external definition works fine. It would be nice to extend homeassistant.ts with proper device classes:

      power_a:
        device_class: power
      power_b:
        device_class: power
      power_c:
        device_class: power
      current_a:
        device_class: current
      current_b:
        device_class: current
      current_c:
        device_class: current
      voltage_a:
        device_class: voltage
      voltage_b:
        device_class: voltage
      voltage_c:
        device_class: voltage
      power_reactive:
        device_class: reactive_power
      power_reactive_a:
        device_class: reactive_power
      power_reactive_b:
        device_class: reactive_power
      power_reactive_c:
        device_class: reactive_power
      power_factor:
        device_class: power_factor
      power_factor_a:
        device_class: power_factor
      power_factor_b:
        device_class: power_factor
      power_factor_c:
        device_class: power_factor

External definition

const exposes = require('zigbee-herdsman-converters/lib/exposes');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const { Buffer } = require('node:buffer');

const powerReactiveWithPhase = (phase) => e.numeric(`power_reactive_${phase}`, ea.STATE).withUnit('VAR').withDescription(`Instantaneous measured reactive power (phase ${phase.toUpperCase()})`);

const phaseVariant3WithPhase = (phase) => {
    return {
        from: (v) => {
            const buf = Buffer.from(v, 'base64');
            return {
                [`power_${phase}`]: (buf[3] | buf[2] << 8),
                [`power_reactive_${phase}`]: (buf[7] | buf[6] << 8),
                [`power_factor_${phase}`]: (buf[9] | buf[8] << 8) / 10,
                [`current_${phase}`]: (buf[12] | buf[11] << 8) / 1000,
                [`voltage_${phase}`]: (buf[14] | buf[13] << 8) / 10
            };
        },
    };
}

const definition =   {
    fingerprint: tuya.fingerprint('TS0601',['_TZE200_bkkmqmyo']),
    model: 'T363S',
    vendor: 'OXT',
    description: 'Smart energy monitor for 3P+N system',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    configure: tuya.configureMagicPacket,
    exposes: [tuya.exposes.switch(),tuya.exposes.voltageWithPhase('a'), tuya.exposes.voltageWithPhase('b'), tuya.exposes.voltageWithPhase('c'),
        powerReactiveWithPhase("a"),powerReactiveWithPhase("b"),powerReactiveWithPhase("c"),
        tuya.exposes.powerFactorWithPhase("a"),tuya.exposes.powerFactorWithPhase("b"),tuya.exposes.powerFactorWithPhase("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'),
        e.energy().withDescription('Total forward active energy'),
        e.produced_energy().withDescription('Total reverse active energy'), e.power_reactive(),
        e.power_factor().withUnit('%'), e.power(),
        e.ac_frequency(),
    ],
    meta: {
        tuyaDatapoints: [
            [1, 'energy', tuya.valueConverter.divideBy100],
            [6, null, phaseVariant3WithPhase('a')],
            [7, null, phaseVariant3WithPhase('b')],
            [8, null, phaseVariant3WithPhase('c')], // voltage and current and power
            [16, 'state', tuya.valueConverter.onOff],
            [101, 'total_energy', tuya.valueConverter.divideBy100], // total energy produced + consumed
            [102, 'produced_energy', tuya.valueConverter.divideBy100],
            [103, 'power', tuya.valueConverter.raw],
            [105, 'ac_frequency', tuya.valueConverter.divideBy100],
            [109, 'energy_reactive', tuya.valueConverter.divideBy100], // reactive energy in VArh
            [110, 'power_reactive', tuya.valueConverter.raw], // reactive power
            [111, 'power_factor', tuya.valueConverter.divideBy10],
            // Ignored for now; I don't know what the values mean
            [9, null, null],  // Ignored
            [17, null, null], // Ignored
            [18, null, null],  // Ignored
            [107,null,null],   // Ignored
            [106,null,null]    // Ignored
        ],
    }
}

module.exports = definition;
mrmaximas commented 3 months ago

@BartRuSec it may help to find the unknown values https://www.zigbee2mqtt.io/advanced/support-new-devices/03_find_tuya_data_points.html

BartRuSec commented 3 months ago

Thank @mrmaximas for the tip. Before I created my own external converter, I browsed through this and other documentation and looked through the source code for inspiration. I don't have a Tuya gateway and I don't use Tuya Cloud, so I mainly checked what was displayed on the device vs the values ​​from EP and I managed to achieve what was needed and valuable for me (I don't need more information).

mrmaximas commented 3 months ago

@BartRuSec I bought a wired Tuya Gateway for $20 for experiments, including firmware interception, I think it's a small price to pay for the development of this project :)