Tuya Zigbee dwukierunkowy licznik energii model: TS0601 producent: _TZE204_81yrt3lo

Witam wszystkich,
kupiłem u MatSee Plus

i niestety okazało się post factum że na tą chwilę urządzenie nie jest wspierane przez Zigbee2mqtt aczkolwiek są już zgłoszenia aby zostało ono dodane do bazy urządzeń ale do tego potrzebne są DPid z tuya a tak się składa że udało mi się dostać ich listę do tego urządzenia od sprzedawcy ale nie wiem jak to ubrać w te external converter

Czy ktoś mógłby mi pomóc z tym tematem?

Dodam tylko że owe dane dotycząca dpid są poufne i nie mogę ich tu wkleić ale na priv się da. :slight_smile:

1 polubienie

Musisz ktoś taką konfigurację dla external converter napisać

Przykładowy config external converter dla innego urządzenia.

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 e = exposes.presets;
const ea = exposes.access;

const definition = {
  fingerprint: [{modelID: 'TS0202', manufacturerName: '_TZ3000_wrgn6xrz'}],
  model: 'TS0202',
  vendor: 'TuYa',
  description: 'Motion sensor',
  configure: async (device, coordinatorEndpoint, logger) => {
        const endpoint = device.getEndpoint(1);
        await reporting.bind(endpoint, coordinatorEndpoint, ['ssIasZone']);
    },
  fromZigbee: [fz.ias_occupancy_alarm_1, fz.ias_occupancy_alarm_1_report, fz.ignore_basic_report,
    {
        cluster: 'ssIasZone',
        type: ['attributeReport', 'readResponse'],
        convert: (model, msg, publish, options, meta) => {
            const result = {};
            if (msg.data.hasOwnProperty('currentZoneSensitivityLevel')) {
                const sensitivityLookup = {'low': 0, 'medium': 1, 'high': 2};
                result.sensitivity = sensitivityLookup[msg.data['currentZoneSensitivityLevel']];
            }
            if (msg.data.hasOwnProperty('61441')) {
                const keepTimeLookup = {'30': 0, '60': 1, '120': 2};
                result.keep_time = keepTimeLookup[msg.data['61441']];
            }
            return result;
        },
    }],
  toZigbee: [{
      key: ['sensitivity', 'keep_time'],
      convertSet: async (entity, key, value, meta) => {
            switch (key) {
            case 'sensitivity':
                const sensitivityLookup = {'low': 0, 'medium': 1, 'high': 2};
                await entity.write('ssIasZone', {currentZoneSensitivityLevel: sensitivityLookup[value]}, {disableResponse: true});
                return {readAfterWriteTime: 1000, state: {sensitivity: value}};
            case 'keep_time':
                const keepTimeLookup = {'30': 0, '60': 1, '120': 2};
                await entity.write('ssIasZone', {61441: {value: keepTimeLookup[value], type: 0x20}}, {disableResponse: true});
                return {readAfterWriteTime: 1000, state: {keep_time: value}};
            default: // Unknown key
                throw new Error(`Unhandled key ${key}`);
            }
        },
  }],
  exposes: [e.occupancy(), e.battery_low(), e.tamper(),
    exposes
      .enum('sensitivity', ea.STATE_SET, ['low', 'medium', 'high'])
      .withDescription('PIR sensor sensitivity'),
    exposes
      .enum("keep_time", ea.STATE_SET, ["30", "60", "120"])
      .withDescription("PIR keep time in seconds"),
  ],
};

module.exports = definition;

Wejdź tam gdzie zostało zgłoszone urządzenie może już ktoś dodał konfigurację, lub poszukaj w necie


po Zigbee Manufacturer

No niestety juz szukalem po _TZE204_81yrt3lo i tylko requesty o dodanie urzdzenia do zigbee2mqtt sa.
nikt jeszcze config external converter nie zrobil.

Dotarłem do wiadomości ze powinien działać external od
TuYa TS0601_bidirectional_energy meter
wiec poszukaem jego definicji w tuya.ts w zigbee2mqtt na githubie

# from tuya.ts
    {
        fingerprint: tuya.fingerprint('TS0601', ['_TZE200_lsanae15', '_TZE204_lsanae15']),
        model: 'TS0601_din_2',
        vendor: 'TuYa',
        description: 'Zigbee DIN energy meter',
        fromZigbee: [tuya.fz.datapoints],
        toZigbee: [tuya.tz.datapoints],
        configure: tuya.configureMagicPacket,
        exposes: [tuya.exposes.switch(), e.energy(), e.power(), e.voltage(), e.current(),
            e.enum('fault', ea.STATE, ['clear', 'over_current_threshold', 'over_power_threshold',
                'over_voltage threshold', 'wrong_frequency_threshold']).withDescription('Fault status of the device (clear = nothing)'),
            e.enum('threshold_1', ea.STATE, ['not_set', 'over_current_threshold', 'over_voltage_threshold'])
                .withDescription('State of threshold_1'),
            e.binary('threshold_1_protection', ea.STATE, 'ON', 'OFF')
                .withDescription('OFF - alarm only, ON - relay will be off when threshold reached'),
            e.numeric('threshold_1_value', ea.STATE)
                .withDescription('Can be in Volt or Ampere depending on threshold setting. Setup the value on the device'),
            e.enum('threshold_2', ea.STATE, ['not_set', 'over_current_threshold', 'over_voltage_threshold'])
                .withDescription('State of threshold_2'),
            e.binary('threshold_2_protection', ea.STATE, 'ON', 'OFF')
                .withDescription('OFF - alarm only, ON - relay will be off when threshold reached'),
            e.numeric('threshold_2_value', ea.STATE)
                .withDescription('Setup value on the device'),
            e.binary('clear_fault', ea.STATE_SET, 'ON', 'OFF')
                .withDescription('Turn ON to clear last the fault'),
            e.text('meter_id', ea.STATE).withDescription('Meter ID (ID of device)'),
        ],
        meta: {
            tuyaDatapoints: [
                [1, 'energy', tuya.valueConverter.divideBy100],
                [3, null, null], // Monthly, but sends data only after request
                [4, null, null], // Dayly, but sends data only after request
                [6, null, tuya.valueConverter.phaseVariant2], // voltage and current
                [10, 'fault', tuya.valueConverterBasic.lookup({'clear': 0, 'over_current_threshold': 1,
                    'over_power_threshold': 2, 'over_voltage_threshold': 4, 'wrong_frequency_threshold': 8})],
                [11, null, null], // Frozen - strange function, in native app - nothing is clear
                [16, 'state', tuya.valueConverter.onOff],
                [17, null, tuya.valueConverter.threshold], // It's settable, but can't write converter
                [18, 'meter_id', tuya.valueConverter.raw],
                [20, 'clear_fault', tuya.valueConverter.onOff], // Clear fault
                [21, null, null], // Forward Energy T1 - don't know what this
                [22, null, null], // Forward Energy T2 - don't know what this
                [23, null, null], // Forward Energy T3 - don't know what this
                [24, null, null], // Forward Energy T4 - don't know what this
            ],
        },
        whiteLabel: [
            tuya.whitelabel('MatSee Plus', 'DAC2161C', 'Smart Zigbee energy meter 80A din rail', ['_TZE200_lsanae15', '_TZE204_lsanae15']),
        ],
    }


i spreparowaem ponizszy 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 ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const e = exposes.presets;
const ea = exposes.access;

const definition = {
//    fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE204_81yrt3lo'}],
    fingerprint: tuya.fingerprint('TS0601', ['_TZE204_81yrt3lo', '_TZE204_81yrt3lo']),
    model: 'TS0601 bidirectional clamp energy meter',
    vendor: 'TuYa',
    description: 'Tuya Smart ZigBee Energy Meter Bidirectional Dual Phases 80A ',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    configure: tuya.configureMagicPacket,
        exposes: [tuya.exposes.switch(), e.energy(), e.power(), e.voltage(), e.current(),
            e.enum('fault', ea.STATE, ['clear', 'over_current_threshold', 'over_power_threshold',
                'over_voltage threshold', 'wrong_frequency_threshold']).withDescription('Fault status of the device (clear = nothing)'),
            e.enum('threshold_1', ea.STATE, ['not_set', 'over_current_threshold', 'over_voltage_threshold'])
                .withDescription('State of threshold_1'),
            e.binary('threshold_1_protection', ea.STATE, 'ON', 'OFF')
                .withDescription('OFF - alarm only, ON - relay will be off when threshold reached'),
            e.numeric('threshold_1_value', ea.STATE)
                .withDescription('Can be in Volt or Ampere depending on threshold setting. Setup the value on the device'),
            e.enum('threshold_2', ea.STATE, ['not_set', 'over_current_threshold', 'over_voltage_threshold'])
                .withDescription('State of threshold_2'),
            e.binary('threshold_2_protection', ea.STATE, 'ON', 'OFF')
                .withDescription('OFF - alarm only, ON - relay will be off when threshold reached'),
            e.numeric('threshold_2_value', ea.STATE)
                .withDescription('Setup value on the device'),
            e.binary('clear_fault', ea.STATE_SET, 'ON', 'OFF')
                .withDescription('Turn ON to clear last the fault'),
            e.text('meter_id', ea.STATE).withDescription('Meter ID (ID of device)'),
        ],
        meta: {
            tuyaDatapoints: [
                [1, 'energy', tuya.valueConverter.divideBy100],
                [3, null, null], // Monthly, but sends data only after request
                [4, null, null], // Dayly, but sends data only after request
                [6, null, tuya.valueConverter.phaseVariant2], // voltage and current
                [10, 'fault', tuya.valueConverterBasic.lookup({'clear': 0, 'over_current_threshold': 1,
                    'over_power_threshold': 2, 'over_voltage_threshold': 4, 'wrong_frequency_threshold': 8})],
                [11, null, null], // Frozen - strange function, in native app - nothing is clear
                [16, 'state', tuya.valueConverter.onOff],
                [17, null, tuya.valueConverter.threshold], // It's settable, but can't write converter
                [18, 'meter_id', tuya.valueConverter.raw],
                [20, 'clear_fault', tuya.valueConverter.onOff], // Clear fault
                [21, null, null], // Forward Energy T1 - don't know what this
                [22, null, null], // Forward Energy T2 - don't know what this
                [23, null, null], // Forward Energy T3 - don't know what this
                [24, null, null], // Forward Energy T4 - don't know what this
            ],
        },
};

module.exports = definition;

po restarcie zigbee2mqtt produkt sparowalem i zostal rozpoznany razem ze wszystkim co wedlug definicji mial exponowac ale zwraca same null’e. :frowning:

wiec szukajc dalej odnalazlem external od PC321-Z-TY autorstwa samego guru Koenkk
PC321-Z-TY

powycinalem w nim wpisy odnosnie 3-ciej fazy i podmienilem kilka pid’ow wedlug tabelki ktora mam
i powstal kolejny external

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 ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const e = exposes.presets;
const ea = exposes.access;
const {Buffer} = require('buffer');

const valueConverter = {
    divideBy1000: tuya.valueConverterBasic.divideBy(1000),
    phaseVariant3: (phase) => { return {
        from: (v) => {
            const buf = Buffer.from(v, 'base64');
            return {
                [`voltage_${phase}`]: (buf[1] | buf[0] << 8) / 10,
                [`current_${phase}`]: (buf[4] | buf[3] << 8) / 1000,
                [`power_${phase}`]: (buf[7] | buf[6] << 8)};
        },
    }},
};

const exposesLocal = {
    energy_phase: (phase) => exposes.numeric(`energy_${phase}`, ea.STATE).withUnit('kWh').withDescription(`Sum of consumed energy (phase ${phase.toUpperCase()})`),
    voltage_phase: (phase) => exposes.numeric(`voltage_${phase}`, ea.STATE).withUnit('V').withDescription(`Measured electrical potential value (phase ${phase.toUpperCase()})`),
    power_phase: (phase) => exposes.numeric(`power_${phase}`, ea.STATE).withUnit('W').withDescription(`Instantaneous measured power (phase ${phase.toUpperCase()})`),
    current_phase: (phase) => exposes.numeric(`current_${phase}`, ea.STATE).withUnit('A').withDescription(`Instantaneous measured electrical current (phase ${phase.toUpperCase()})`),
    power_factor_phase: (phase) => exposes.numeric(`power_factor_${phase}`, ea.STATE).withUnit('%').withDescription(`Instantaneous measured power factor (phase ${phase.toUpperCase()})`),
};

const definition = {
    fingerprint: tuya.fingerprint('TS0601', ['_TZE204_81yrt3lo']),
    model: 'TS0601_2_phase_clamp_meter',
    vendor: 'TuYa',
    description: '2-phase clamp power meter',
    fromZigbee: [tuya.fzDataPoints],
    toZigbee: [tuya.tzDataPoints],
    configure: tuya.configureMagicPacket,
    whiteLabel: [{vendor: 'MatSeePlus', model: 'PJ-1203A'}],
    exposes: [
        e.ac_frequency(), e.current(), e.power(), e.energy(),
        exposesLocal.energy_phase('a'),
		exposesLocal.energy_phase('b'),
        exposesLocal.voltage_phase('a'),
		exposesLocal.voltage_phase('b'),
        exposesLocal.power_phase('a'),
		exposesLocal.power_phase('b'),
        exposesLocal.current_phase('a'),
		exposesLocal.current_phase('b'),
        exposesLocal.power_factor_phase('a'),
		exposesLocal.power_factor_phase('b'),
    ],
    meta: {
        tuyaDatapoints: [
            [111, 'ac_frequency', tuya.valueConverter.raw],
            [106, 'energy', tuya.valueConverter.divideBy100],
            [101, 'energy_a', valueConverter.divideBy1000],
            [111, 'energy_b', valueConverter.divideBy1000],
            [131, 'current', valueConverter.divideBy1000],
            [115, 'power', tuya.valueConverter.raw],
            [110, 'power_factor_a', tuya.valueConverter.raw],
            [121, 'power_factor_b', tuya.valueConverter.raw],
            [6, null, valueConverter.phaseVariant3('a')],
            [7, null, valueConverter.phaseVariant3('b')],
            [134, 'device_status', tuya.valueConverter.raw],
        ],
    },
};

module.exports = definition;

No i na tym poleglem bo zigbee2mqtt z nim nie chce nawet wstac
Oba externale sa tak rozne ze nie wiem nawet co jest dobre w nich a co zle.

Moze ktos ma jakies doswiadczenia z external converters + urzadzenia do pomiaru energii?

p.s.
Wykaz pidow od urzadzenia mam wraz z ich opisem i typami danych jakie zwracaja.

Witam,
tak działa już w home assistant poprawnie od końca zeszłego roku, stworzyłem własny external converter który został później dodany do repozytorium www.zigbee2mqtt.io i jest już oficialnie support’owane.

TuYa PJ-1203A control via MQTT | Zigbee2MQTT

1 polubienie