Koenkk/zigbee-herdsman-converters

New device template for `_TZE204_dvosyycn`

clumsy-stefan opened this issue · 7 comments

Even though this device alreday exists, it seems that there are multiple versions of this.

The version I have from AliExpress has 8 Analog Inputs and 8 Digital outputs. The inputs can be directly connected to the outputs or individually used.

Attached the template to use the device incl. the analog ports and change the input settings / couplings.

Probably this is of use for someone...

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

const fzLocal = {
    value: {
        cluster: 'manuSpecificTuya',
        type: ['commandDataResponse', 'commandDataReport'],
        convert: (model, msg, publish, options, meta) => {
                value_192 = meta.state.value_v1;
                value_193 = meta.state.value_v2;
                changed = false;
                payload = {};
                for (const dpValue of msg.data.dpValues) {
                        const dp = dpValue.dp;
                        switch (dp) {
                            case 192:
                                {
                                        value_192 = legacy.getDataValue(dpValue);
                                        changed = true;
                                };
                            case 193:
                                {
                                        value_193 = legacy.getDataValue(dpValue);
                                        changed = true;
//                                      meta.logger.info(`RECEIVED DP #${dp} -- VALUE = ${value_192} -- VALUE_2 = ${value_193}`);
                                };
//                          default: {
//                                      meta.logger.warn(`zigbee-herdsman-converters:: NOT RECOGNIZED DP ` + `#${dp} with data ${JSON.stringify(msg.data)} VALUE = ${value}`);
//                              };
                        };
                };
                if (changed) {
                        payload['mode_l' + value_192] = value_193;
                        payload['value_v1'] = value_192;
                        payload['value_v2'] = value_193;
                        return payload;
                };
        },
    },
};

const tzLocal = {
    value: {
        key: ['value'],
        convertSet: async (entity, key, value, meta) => {
            const convertedKey = meta.mapped.meta.multiEndpoint && meta.endpoint_name ? `value_${meta.endpoint_name}` : 'value';
            const datapoints = meta.mapped.meta?.tuyaDatapoints;
            const dpEntry = datapoints.find((d) => d[1] === convertedKey);
            const dpId = dpEntry[0];
            await tuya.sendDataPointValue(entity, dpId, value);
        },
    },
};


const definition = {

        fingerprint: tuya.fingerprint('TS0601', ['_TZE204_dvosyycn']),
        model: 'TS0601',
        vendor: 'TuYa',
        description: 'ZXYH 8IN/8OUT',
        extend: [],
        fromZigbee: [tuya.fz.datapoints, fzLocal.value],
        toZigbee: [tuya.tz.datapoints, tzLocal.value],
        configure: tuya.configureMagicPacket,
        exposes: [
                ...Array.from({ length: 8 }, (_, i) => tuya.exposes.switch().withEndpoint(`l${i + 1}`).withDescription(`Switch l${i + 1}`)),
                ...Array.from({ length: 8 }, (_, i) => e.numeric('mode', ea.STATE).withEndpoint(`l${i + 1}`).withDescription(`Mode l${i + 1}`)),
                ...Array.from({ length: 8 }, (_, i) => e.voltage().withEndpoint(`a${i + 1}`).withDescription(`Voltage ${i + 1}`)),
                e.text('serial', ea.STATE).withDescription('Serial number'),
                e.text('dp_string_171', ea.STATE).withDescription('DP 171'),
                e.text('data_9', ea.STATE).withDescription('DP 181'),
                e.enum('value', ea.STATE_SET, [1, 2, 3, 4, 5, 6, 7, 8]).withDescription('Channel Select').withEndpoint('v1'),
                e.enum('value', ea.STATE_SET, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).withDescription('Channel Mode').withEndpoint('v2'),
                e.numeric('value', ea.STATE_SET).withEndpoint(`v3`).withDescription(`Value 3`),
                e.numeric('mode', ea.STATE_SET).withDescription('Mode'),
                e.numeric('order', ea.STATE_SET).withDescription('Order'),
                e.numeric('state', ea.STATE_SET).withDescription('State'),
        ],
        endpoint: (device) => {
            return {
                    'l1': 1, 'l2': 1, 'l3': 1, 'l4': 1, 'l5': 1, 'l6': 1, 'l7': 1, 'l8': 1, 'l9': 1, 'l10': 1, 'l11': 1, 'l12': 1, 'l13': 1, 'l14': 1, 'l15': 1, 'l16': 1,
                    'v1': 1, 'v2': 1, 'v3': 1,
                    'a1': 1, 'a2': 1, 'a3': 1, 'a4': 1, 'a5': 1, 'a6': 1, 'a7': 1, 'a8': 1,
                     };
        },
        meta: {
            multiEndpoint: true,
            tuyaDatapoints: [
                [1, 'state_l1', tuya.valueConverter.onOff],
                [2, 'state_l2', tuya.valueConverter.onOff],
                [3, 'state_l3', tuya.valueConverter.onOff],
                [4, 'state_l4', tuya.valueConverter.onOff],
                [5, 'state_l5', tuya.valueConverter.onOff],
                [6, 'state_l6', tuya.valueConverter.onOff],
                [101, 'state_l7', tuya.valueConverter.onOff],
                [102, 'state_l8', tuya.valueConverter.onOff],
                [103, 'state_l9', tuya.valueConverter.onOff],
                [104, 'state_l10', tuya.valueConverter.onOff],
                [105, 'state_l11', tuya.valueConverter.onOff],
                [106, 'state_l12', tuya.valueConverter.onOff],
                [107, 'state_l13', tuya.valueConverter.onOff],
                [108, 'state_l14', tuya.valueConverter.onOff],
                [109, 'state_l15', tuya.valueConverter.onOff],
                [110, 'state_l16', tuya.valueConverter.onOff],
                [171, 'dp_string_171', tuya.valueConverter.raw],
                [181, 'data_9', tuya.valueConverter.raw],
                [182, 'voltage_a8', tuya.valueConverter.divideBy10],
                [183, 'voltage_a7', tuya.valueConverter.divideBy10],
                [184, 'voltage_a6', tuya.valueConverter.divideBy10],
                [185, 'voltage_a5', tuya.valueConverter.divideBy10],
                [186, 'voltage_a4', tuya.valueConverter.divideBy10],
                [187, 'voltage_a3', tuya.valueConverter.divideBy10],
                [188, 'voltage_a2', tuya.valueConverter.divideBy10],
                [189, 'voltage_a1', tuya.valueConverter.divideBy10],
                [190, 'mode', tuya.valueConverter.raw],
                [191, 'order', tuya.valueConverter.raw],
                [192, 'value_v1', tuya.valueConverter.raw],
                [193, 'value_v2', tuya.valueConverter.raw],
                [194, 'value_v3', tuya.valueConverter.raw],
                [198, 'state', tuya.valueConverter.raw],
                [199, 'serial', tuya.valueConverter.raw],
            ],
        },
};

module.exports = definition;
/*
 * Report from Tuya Cloud Debug
{"1":"Switch 1",
"2":"Switch 2",
"3":"Switch 3",
"4":"Switch 4",
"5":"Switch 5",
"6":"Switch 6",
"101":"switch 7",
"102":"Switch 8",
"103":"switch 9",
"104":"Switch 10",
"105":"switch 11",
"106":"switch 12",
"107":"switch 13",
"108":"switch 14",
"109":"switch 15",
"110":"switch 16",
"111":"switch 17",
"112":"switch 18",
"113":"switch 19",
"114":"switch 20",
"115":"switch 21",
"116":"switch 22",
"117":"switch 23",
"118":"switch 24",
"171":"dp_string171",
"181":"data9",
"182":"num8",
"183":"num7",
"184":"num6",
"185":"num5",
"186":"num4",
"187":"num3",
"188":"num2",
"189":"num1",
"190":"mode",
"191":"order",
"192":"value1",
"193":"value2",
"194":"value3",
"198":"State",
"199":"sn"}
*/

Could you make a pull request for this?

I can try. I need to find out how and where I need to include it in the existing files. The other issue is, that there exists already a device definition with this odentification, and I'm not sure if there is another device (with 8 or 16 relais), that uses the same ID and I would damage that one. (sorry for my english)..

I'm struggling to understand the structure of the converters. eg. what needs to go in lib/* , converters/* and devices/* (especially the fzLocal and tzLocal functions). Also if I should extend the */tuya.js definitions oder make a complete new one (all in device/xyz.js or split in lib/xyz.js and device/xyz.js)...
Really sorry, but I'm not an actual developper, but I'm happy to support whereever I can..

Sure, all of it in one file then?

And I would need to remove the existing definition of that device, hopefully not breaking anyones devices...

I assume I can/should do the same #7181, that one also runs smoothly in my environment?!

yes in one file, you can remove the already existing one

Tried to do a PR, but it seems something is wrong as one oof the tests failed. Unfortunately I have no clue about .ts files, so I can't really see what's wrong with my code.. When I use it like this in my js, it works..