Skip to content

[External Converter] TS0601 from _TZE200_4utwozi2 #10609

@johnnyk86

Description

@johnnyk86

This is my external converter for TS0601 from _TZE200_4utwozi2
software_build_id: undefined
date_code: ``
endpoints:

{"1":{"clusters":{"input":["genGroups","genScenes","manuSpecificTuya","genBasic"],"output":["genOta","genTime"]}}}

What works / what doesn't?

This converter fully supports the TuYa TRV (model ME167, fingerprint _TZE200_4utwozi2).

It correctly exposes and handles:

Climate controls (setpoint, local_temp)

Running state ('heat'/'idle' from DP 3)

Child lock (DP 7)

Battery low (DP 15)

Local Temperature Calibration (DP 105): This now works correctly using tuya.valueConverter.localTemperatureCalibration for negative/positive offsets.

Window Detection (DP 36): Can be toggled ON/OFF.

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');

// Importiamo l'oggetto 'tuya' COMPLETO. 
const tuya = require('zigbee-herdsman-converters/lib/tuya');

const e = exposes.presets;
const ea = exposes.access;

// Converter customizzato per DP 3 (running_state)
const fzLocal = {
    TZE200_4utwozi2_running_state: {
        cluster: 'manuSpecificTuya',
        type: ['commandDataReport', 'commandDataResponse'],
        convert: (model, msg, publish, options, meta) => {
            const dp = msg.data.dpValues[0].dp;
            // Chiamiamo la funzione dal modulo 'tuya' importato
            const value = tuya.helpers.getDataValue(msg.data.dpValues[0]); 
            if (dp === 3) {
                // 0 = HEATING, 1 = OFF (idle)
                return {running_state: value === 0 ? 'heat' : 'idle'};
            }
        },
    },
};

// Converter customizzato per l'INVIO (toZigbee) dei DP non standard
const tzLocal = {
    local_temperature_calibration: {
        key: 'local_temperature_calibration',
        convertSet: async (entity, key, value, meta) => {
            // Usiamo il converter corretto dall'oggetto 'tuya'
            const convertedValue = tuya.valueConverter.localTemperatureCalibration.to(value, meta);
            // Inviamo il valore al DP 105
            await tuya.sendDataPointValue(entity, 105, convertedValue);
        },
    },
    window_detection: {
        key: 'window_detection',
        convertSet: async (entity, key, value, meta) => {
            // Usiamo il converter corretto dall'oggetto 'tuya'
            const convertedValue = tuya.valueConverter.onOff.to(value, meta);
            // Inviamo il valore al DP 36
            await tuya.sendDataPointValue(entity, 36, convertedValue);
        },
    },
};


const definition = {
    fingerprint: [
        {modelID: 'TS0601', manufacturerName: '_TZE200_4utwoz2'},
        {modelID: 'TS0601', manufacturerName: '_TZE200_4utwozi2'},
    ],
    model: 'ME167_Definitivo_v10', // v10
    vendor: 'TuYa',
    description: 'Valvola termostatica (ME167 - Completa)',

    fromZigbee: [tuya.fz.datapoints, fzLocal.TZE200_4utwozi2_running_state],
    toZigbee: [
        tuya.tz.datapoints, 
        tzLocal.local_temperature_calibration, // Aggiungiamo il nostro converter di invio
        tzLocal.window_detection // Aggiungiamo il nostro converter di invio
    ],

    onEvent: tuya.onEventSetTime,
    configure: tuya.configureMagicPacket,

    exposes: [
        e.climate()
            .withSetpoint('current_heating_setpoint', 5, 30, 0.5, ea.STATE_SET) // DP 4
            .withLocalTemperature(ea.STATE) // DP 5
            .withRunningState(['idle', 'heat'], ea.STATE), // DP 3
        e.child_lock(), // DP 7
        e.battery_low(), // DP 15

        // Calibrazione (DP 105)
        exposes.numeric('local_temperature_calibration', ea.STATE_SET).withUnit('°C')
            .withDescription('Offset per correggere la temperatura locale (es. -2)')
            .withValueMin(-5).withValueMax(5).withValueStep(0.5),

        // Rilevamento Finestra (DP 36)
        exposes.binary('window_detection', ea.STATE_SET, 'ON', 'OFF')
            .withDescription('Rilevamento finestra aperta'),
    ],

    meta: {
        // Questa lista è usata SOLO da 'tuya.fz.datapoints' (fromZigbee)
        tuyaDatapoints: [
            [4, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
            [5, 'local_temperature', tuya.valueConverter.divideBy10],
            [7, 'child_lock', tuya.valueConverter.lockUnlock],
            [3, 'running_state', tuya.valueConverterBasic.lookup({'heat': 0, 'idle': 1})],
            [15, 'battery_low', tuya.valueConverter.onOff],
            [105, 'local_temperature_calibration', tuya.valueConverter.localTemperatureCalibration],
            [36, 'window_detection', tuya.valueConverter.onOff],
        ],
    },
};

module.exports = definition;```

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions