Zigbee2mqtt źle rozpoznany przełącznik

Kupiłem moduł switcha:
Model RR620ZB LoraTap Zigbee ID: TS0002 | _TZ3000_7ed9cqgi, podłączyłem przez Zigbee2mqtt.
Został rozpoznany jako TS0002 _TZ3000_4xfqlgqo, przełącznik ścienny TuYa TS0002 control via MQTT | Zigbee2MQTT
Pytanie czy da się w jakiś sposób zmienić w zigbee2mqtt sposób rozpoznania tego urządzenia, tak żeby był rozpoznawany jako TuYa TS0002_switch_module control via MQTT | Zigbee2MQTT.
Znalazłem w necie coś takiego ale jestem zupełnie zielony i tego nie łapię [New device support]: 2 Gang ZigBee Switch RR620ZB (Tuya TS0002 alike) · Issue #13951 · Koenkk/zigbee2mqtt (github.com).
Może ktoś z Forumowiczów spotkał się z podobną sytuacją i może pomóc?

Pozdrawiam

WS

Posiadasz najnowszą wersje Z2M?

Jeżeli kod podany na stronie jest prawidłowy to tworzysz sobie plik np. _TZ3000_7ed9cqgi.js
Wklejasz podany kod

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 tuya = require("zigbee-herdsman-converters/lib/tuya");

const definition ={
        fingerprint: [{modelID: 'TS0002', manufacturerName: '_TZ3000_7ed9cqgi'}],
        model: 'TS0002_switch_module',
        vendor: 'TuYa',
        description: '2 gang switch module',
        whiteLabel: [{vendor: 'unknown/pcblab.io', model: 'RR620ZB'}],
        toZigbee: extend.switch().toZigbee.concat([tz.moes_power_on_behavior, tz.tuya_switch_type]),
        fromZigbee: extend.switch().fromZigbee.concat([fz.moes_power_on_behavior, fz.tuya_switch_type]),
        exposes: [
            e.switch().withEndpoint('l1'),
            e.switch().withEndpoint('l2'),
            exposes.presets.power_on_behavior(),
            exposes.presets.switch_type_2(),
        ],
        endpoint: (device) => {
            return {'l1': 1, 'l2': 2};
        },
        meta: {multiEndpoint: true},
        configure: async (device, coordinatorEndpoint, logger) => {
            await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
            await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
        },
    };
	
module.exports = definition;

Plik _TZ3000_7ed9cqgi.js kopiujesz do katalogu Z2M

Screenshot - 07.04.2023 , 07_33_47

w panelu Z2M klikasz extrenal converter i dodajesz w linijce nazwę _TZ3000_7ed9cqgi.js
restart Z2M

1 polubienie

OK rozumiem ale gdzie w panelu Z2M znajdę external converter ? Nie mogę znaleźć.

Znalazłem, zrobiłem zgodnie z Twoim tutorialem. Niestety Z2M nie startuje, pewnie kod jest do d.

Log:

/app/data/extension/externally-loaded.js:22
exposes.presets.switch_type_2(),
^
TypeError: exposes.presets.switch_type_2 is not a function
at /app/data/extension/externally-loaded.js:22:29
at Script.runInContext (node:vm:141:12)
at Script.runInNewContext (node:vm:146:17)
at Object.runInNewContext (node:vm:306:38)
at loadModuleFromText (/app/lib/util/utils.ts:150:8)
at loadModuleFromFile (/app/lib/util/utils.ts:157:12)
at Object.getExternalConvertersDefinitions (/app/lib/util/utils.ts:167:25)
at getExternalConvertersDefinitions.next ()
at new ExternalConverters (/app/lib/extension/externalConverters.ts:12:20)
at new Controller (/app/lib/controller.ts:84:58)

1 polubienie

Znalazłem, zrobiłem zgodnie z Twoim tutorialem. Niestety Z2M nie startuje, pewnie kod jest do d.

Log:

/app/data/extension/externally-loaded.js:22
exposes.presets.switch_type_2(),
^
TypeError: exposes.presets.switch_type_2 is not a function
at /app/data/extension/externally-loaded.js:22:29
at Script.runInContext (node:vm:141:12)
at Script.runInNewContext (node:vm:146:17)
at Object.runInNewContext (node:vm:306:38)
at loadModuleFromText (/app/lib/util/utils.ts:150:8)
at loadModuleFromFile (/app/lib/util/utils.ts:157:12)
at Object.getExternalConvertersDefinitions (/app/lib/util/utils.ts:167:25)
at getExternalConvertersDefinitions.next ()
at new ExternalConverters (/app/lib/extension/externalConverters.ts:12:20)
at new Controller (/app/lib/controller.ts:84:58)

Wrzuć tu kod który wkleiłeś

Skopiowałem to co Ty wkleiłeś powyżej.

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 tuya = require("zigbee-herdsman-converters/lib/tuya");

const definition ={
        fingerprint: [{modelID: 'TS0002', manufacturerName: '_TZ3000_7ed9cqgi'}],
        model: 'TS0002_switch_module',
        vendor: 'TuYa',
        description: '2 gang switch module',
        whiteLabel: [{vendor: 'unknown/pcblab.io', model: 'RR620ZB'}],
        toZigbee: extend.switch().toZigbee.concat([tz.moes_power_on_behavior, tz.tuya_switch_type]),
        fromZigbee: extend.switch().fromZigbee.concat([fz.moes_power_on_behavior, fz.tuya_switch_type]),
        exposes: [
            e.switch().withEndpoint('l1'),
            e.switch().withEndpoint('l2'),
            exposes.presets.power_on_behavior(),
            exposes.presets.switch_type_2(),
        ],
        endpoint: (device) => {
            return {'l1': 1, 'l2': 2};
        },
        meta: {multiEndpoint: true},
        configure: async (device, coordinatorEndpoint, logger) => {
            await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
            await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
        },
    };
	
module.exports = definition;

Spoko, czasami zmieniają się znaki w kodzie przy kopiowaniu. Pewnie błędy są w samym kodzie ze strony. Zaraz sprawdzę u siebie.

@plzws niestety plik jest z błędami

Dziękuję za pomoc. Szkoda z tym kodem ale przynajmniej nauczyłem się korzystać z konwertera.
:+1:

Nie ma problemu, nie wiem ile trwa dodanie takiego kodu, ale na pewno jest on w wersji dev branch w HA jest to Zigbee2MQTT Edge

Jak chcesz sprawdzać to wykonaj niezbędne kopie.

Stawiam na to, że nie tyle z błędami, co nie pasuje do sprzętu.

Z2M nie startuje po dodaniu (sypie błędami) tego do converter

Faktycznie, ale skoro chcemy wykorzystać gotowca, to trzeba “pożyczyć” jakiś działający konwerter.

No to już przerasta (przynajmniej na razie) moje umiejętności.

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

const definition = {
    fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_7hfcudw5'}, {modelID: 'TS0202', manufacturerName: '_TZ3000_kmh5qpmb'}],
    model: 'NAS-PD07',
    vendor: 'Neo',
    description: 'Motion, temperature & humidity sensor CUSTOM',
    fromZigbee: [fz.neo_nas_pd07, fz.ignore_tuya_set_time, fz.ias_occupancy_alarm_1],
    toZigbee: [tz.neo_nas_pd07],
    onEvent: tuya.onEventSetTime,
    exposes: [e.occupancy(), e.humidity(), e.temperature(), e.tamper(), e.battery_low(),
        exposes.enum('power_type', ea.STATE, ['battery_full', 'battery_high', 'battery_medium', 'battery_low', 'usb']),
        exposes.enum('alarm', ea.STATE, ['over_temperature', 'over_humidity', 'below_min_temperature', 'below_min_humdity', 'off'])
            .withDescription('Temperature/humidity alarm status'),
        exposes.numeric('temperature_min', ea.STATE_SET).withUnit('°C').withValueMin(-20).withValueMax(80),
        exposes.numeric('temperature_max', ea.STATE_SET).withUnit('°C').withValueMin(-20).withValueMax(80),
        exposes.binary('temperature_scale', ea.STATE_SET, '°C', '°F').withDescription('Temperature scale (°F/°C)'),
        exposes.numeric('humidity_min', ea.STATE_SET).withUnit('%').withValueMin(1).withValueMax(100),
        exposes.numeric('humidity_max', ea.STATE_SET).withUnit('%').withValueMin(1).withValueMax(100),
        // exposes.binary('unknown_111', ea.STATE_SET, 'ON', 'OFF').withDescription('Unknown datapoint 111 (default: ON)'),
        // exposes.binary('unknown_112', ea.STATE_SET, 'ON', 'OFF').withDescription('Unknown datapoint 112 (default: ON)')
    ],
    configure: async (device, coordinatorEndpoint, logger) => {
        const endpoint = device.getEndpoint(1);
        await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
        await endpoint.command('manuSpecificTuya', 'mcuVersionRequest', {'seq': 0x0002});
    },
};

module.exports = definition;

Spróbuj ten kod:

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

const definition = {
    fingerprint: [{modelID: 'TS0002', manufacturerName: '_TZ3000_7ed9cqgi'}],
    model: 'TS0002_switch_module',
    vendor: 'TuYa',
    description: '2 gang switch module',
    whiteLabel: [{vendor: 'unknown/pcblab.io', model: 'RR620ZB'}],
    extend: tuya.extend.switch({switchType: true, endpoints: ['l1', 'l2']}),
    endpoint: (device) => {
        return {'l1': 1, 'l2': 2};
    },
    meta: {multiEndpoint: true},
    configure: async (device, coordinatorEndpoint, logger) => {
        await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
        await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
        await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
    },
};

module.exports = definition;

Zrobiłem wszystko zgodnie z instrukcją Artura. Zrestartowałem Z2M, wszystko wstało ale nie mam żadnych zmian na tym urządzeniu.

Hmm… widzę ogólnie problem z tymi modułami… kiedyś (w zeszłym roku), kupowałem praktycznie identycznie wyglądające ale Zigbee znajdowało je jako Lonsonho QS-Zigbee-S05-LN control via MQTT | Zigbee2MQTT

A teraz kupiłem dwa z Allegro z łudząco podobnymi nadrukami (różni sprzedawcy, różne “marki”), 1punktowy przekaźnik, a identyfikuje się jako: Zemismart ZM-L03E-Z control via MQTT | Zigbee2MQTT i chąc niechąc nie mogę tego zmienić…

jest to upierdliwe, nie ukrywam, bo wg Zigbee mam 3 punkty, a fizycznie steruję tylko jednym:
obraz

W Twoim przypadku jeszcze mogłoby się udać poprzez zewnętrzny konwerter, ponieważ da się je znaleźć w bazie Koenkk’a na githubie.

Spróbuj jeszcze oryginalny kod z githuba. Wtedy co prawda będzie się urządzenie identyfikowało jako OXT SWTZ22.

const exposes = require('zigbee-herdsman-converters/lib/exposes');
const fz = {...require('zigbee-herdsman-converters/converters/fromZigbee'), legacy: require('zigbee-herdsman-converters/lib/legacy').fromZigbee};
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
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 libColor = require('zigbee-herdsman-converters/lib/color');
const utils = require('zigbee-herdsman-converters/lib/utils');
const zosung = require('zigbee-herdsman-converters/lib/zosung');
const fzZosung = zosung.fzZosung;
const tzZosung = zosung.tzZosung;
const ez = zosung.presetsZosung;
const globalStore = require('zigbee-herdsman-converters/lib/store');

const definition = {
    fingerprint: tuya.fingerprint('TS0002', ['_TZ3000_01gpyda5', '_TZ3000_bvrlqyj7', '_TZ3000_7ed9cqgi', '_TZ3000_zmy4lslw']),
    model: 'TS0002_switch_module',
    vendor: 'TuYa',
    description: '2 gang switch module',
    whiteLabel: [{vendor: 'OXT', model: 'SWTZ22'}],
    extend: tuya.extend.switch({switchType: true, endpoints: ['l1', 'l2']}),
    endpoint: (device) => {
        return {'l1': 1, 'l2': 2};
    },
    meta: {multiEndpoint: true},
    configure: async (device, coordinatorEndpoint, logger) => {
        await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
        await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
        await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
    },
};

module.exports = definition;

PS:
Przesyłam bazę wiedzy:

Urządzenie oczywiście usunąłeś z Z2M przed Restartem? Restart wykonaj z poziomu HA → Dodatki
Screenshot - 08.04.2023 , 13_28_11

Próbowałem. Jakoś nic to zasadniczo nie zmienia poza tym że z2m zaczyna działać niestabilnie albo gubię inne urządzenia.
Dzięki za pomoc. Muszę na spokojnie poczytać dokumentację.

Wszystkiego najlepszego Panowie. :egg: :egg: :egg: