Koenkk / zigbee2mqtt

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

ZigBee Smart Thermostat Module Part Touch Screen #23755

Closed tobatya closed 1 day ago

tobatya commented 2 weeks ago

Link

https://aliexpress.ru/item/1005005288243919.html?spm=a2g2w.orderdetail.0.0.3e1d4aa6qJsxyC&sku_id=12000032501024262

Database entry

{"id":23,"type":"Router","ieeeAddr":"0xa4c1383466b207eb","nwkAddr":22908,"manufId":4417,"manufName":"_TZE200_7rghpoxo","powerSource":"Mains (single phase)","modelId":"TS0601","epList":[1,242],"endpoints":{"1":{"profId":260,"epId":1,"devId":81,"inClusterList":[4,5,61184,0],"outClusterList":[25,10],"clusters":{"genBasic":{"attributes":{"65503":",�.i.�.i2�.i5�.f6�`.\u0012","65506":54,"65508":0,"stackVersion":0,"dateCode":"","appVersion":70}}},"binds":[],"configuredReportings":[],"meta":{}},"242":{"profId":41440,"epId":242,"devId":97,"inClusterList":[],"outClusterList":[33],"clusters":{},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":70,"stackVersion":0,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"meta":{},"lastSeen":1724768850936}

Comments

I think the device is similar to MOES Zigbee Thermostat Room Temperature Controller of Water/Electric Floor Heating Thermostat

External definition

const definition = {
    zigbeeModel: ['TS0601'],
    model: 'TS0601',
    vendor: '_TZE200_7rghpoxo',
    description: 'Automatically generated definition',
    extend: [],
    meta: {},
};

module.exports = definition;
dweng0 commented 2 weeks ago

Link

https://www.aliexpress.com/item/1005006070061141.html?spm=a2g0o.order_list.order_list_main.85.21ef1802obGrnJ

Database entry

{"id":17,"type":"EndDevice","ieeeAddr":"0xa4c138a93ec7382b","nwkAddr":30083,"manufId":4417,"manufName":"_TZE200_yqgbrdyo","powerSource":"Battery","modelId":"TS0601","epList":[1],"endpoints":{"1":{"profId":260,"epId":1,"devId":81,"inClusterList":[4,5,61184,0],"outClusterList":[25,10],"clusters":{"genBasic":{"attributes":{"modelId":"TS0601","manufacturerName":"_TZE200_yqgbrdyo","powerSource":3,"zclVersion":3,"appVersion":67,"stackVersion":0,"hwVersion":1,"dateCode":""}}},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":67,"stackVersion":0,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"meta":{},"lastSeen":1724770412186}

External definition

const definition = {
    zigbeeModel: ['TS0601'],
    model: 'TS0601',
    vendor: '_TZE200_yqgbrdyo',
    description: 'Automatically generated definition',
    extend: [],
    meta: {},
};

module.exports = definition;

Comments

I have a similar device. that uses T0601 here

TL;DR a quick vid of the process of adding tuya devices would be amazing. I've been unable to add a (infamous) TS0601 device using the process outlined in the documentation.

I've tried multiple approaches to this.

I followed the documentation on adding a device. So:

  1. generate a definition

  2. Create a .js file in the same dir as the configuration.yml file

  3. reference the js file in the configuration file, AND update log level to debug

    log_level: debug
    external_converters:
    - tuya_trv.js
  4. Then the tuya_trv.js file, I basically did a lot of searching in the converters and find an example converter that i referenced here

so that the final tuya_trv.js file looks like this gist:

But i also have tried using "non" tuyaDatapoints:

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

const definition =    {    
    zigbeeModel: ['trv06'],
    fingerprint: [
        {modelID: 'TS0601', manufacturerName: '_TZE200_yqgbrdyo'},
    ],
    model: 'TRV06',
    vendor: 'EARU-electric',
    description: 'Radiator valve with thermostat',
    fromZigbee: [legacy.fz.tuya_thermostat, fz.ignore_basic_report],
    meta: {
        tuyaThermostatSystemMode: legacy.thermostatSystemModes4,
        tuyaThermostatPreset: legacy.thermostatPresets,
        tuyaThermostatPresetToSystemMode: legacy.thermostatSystemModes4,
    },
    toZigbee: [
        legacy.tz.tuya_thermostat_child_lock,
        legacy.tz.siterwell_thermostat_window_detection,
        legacy.tz.tuya_thermostat_valve_detection,
        legacy.tz.tuya_thermostat_current_heating_setpoint,
        legacy.tz.tuya_thermostat_system_mode,
        legacy.tz.tuya_thermostat_auto_lock,
        legacy.tz.tuya_thermostat_calibration,
        legacy.tz.tuya_thermostat_min_temp,
        legacy.tz.tuya_thermostat_max_temp,
        legacy.tz.tuya_thermostat_comfort_temp,
        legacy.tz.tuya_thermostat_eco_temp,
        legacy.tz.tuya_thermostat_force,
        legacy.tz.tuya_thermostat_preset,
        legacy.tz.tuya_thermostat_boost_time,
    ],
    exposes: [
        e.child_lock(),
        e.window_detection(),
        e.battery(),
        e.valve_detection(),
        e.position().withDescription('TRV valve position in %.'),
        e
            .climate()
            .withSetpoint('current_heating_setpoint', 5, 30, 0.5, ea.STATE_SET)
            .withLocalTemperature(ea.STATE)
            .withSystemMode(['off', 'auto', 'heat'], ea.STATE_SET)
            .withRunningState(['idle', 'heat'], ea.STATE),
    ],
};

module.exports = definition;
  1. Saved the files.
  2. deleted the device from z2m
  3. restarted z2m. I did not get a debug log from Z2m.

I get some stuff in the logs (by searching for the device id: 0xa4c138a93ec7382b But it's not really telling me much

[2024-08-27 15:44:31] debug:    zh:controller: Received payload: clusterID=61184, address=30083, groupID=0, endpoint=1, destinationEndpoint=1, wasBroadcast=false, linkQuality=26, frame={"header":{"frameControl":{"frameType":1,"manufacturerSpecific":false,"direction":1,"disableDefaultResponse":false,"reservedBits":0},"transactionSequenceNumber":221,"commandIdentifier":2},"payload":{"seq":49920,"dpValues":[{"dp":34,"datatype":0,"data":{"type":"Buffer","data":[7,6,0,0,210,8,0,0,160,12,0,0,210,14,0,0,160,18,0,0,210,22,0,0,160]}}]},"command":{"ID":2,"parameters":[{"name":"seq","type":33},{"name":"dpValues","type":1011}],"name":"dataReport"}}
[2024-08-27 15:44:31] debug:    zh:controller:endpoint: ZCL command 0xa4c138a93ec7382b/1 manuSpecificTuya.defaultRsp({"cmdId":2,"statusCode":0}, {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":0,"reservedBits":0,"transactionSequenceNumber":221,"writeUndiv":false})
[2024-08-27 15:44:31] debug:    zh:zstack: sendZclFrameToEndpointInternal 0xa4c138a93ec7382b:30083/1 (0,0,1)
[2024-08-27 15:44:31] debug:    zh:zstack:znp: SREQ: --> AF - dataRequest - {"dstaddr":30083,"destendpoint":1,"srcendpoint":1,"clusterid":61184,"transid":22,"options":0,"radius":30,"len":5,"data":{"type":"Buffer","data":[16,221,11,2,0]}}
[2024-08-27 15:44:31] debug:    zh:zstack:unpi:writer: --> frame [254,15,36,1,131,117,1,1,0,239,22,0,30,5,16,221,11,2,0,250]
[2024-08-27 15:44:31] debug:    zh:zstack:unpi:parser: --- parseNext []
[2024-08-27 15:44:31] debug:    z2m: Received Zigbee message from '0xa4c138a93ec7382b', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[7,6,0,0,210,8,0,0,160,12,0,0,210,14,0,0,160,18,0,0,210,22,0,0,160],"type":"Buffer"},"datatype":0,"dp":34}],"seq":49920}' from endpoint 1 with groupID 0

Note I was originally using Z2M stable, but have switched to edge to try and see if that helped.

References:

Installing a Tuya device

Installing a device (standard way)

Checking the exposure variables (tuya specific)

Checking the exposure variables (generic)

tobatya commented 2 weeks ago

I tried to add an external converter file but it doesn't help. The device is not detected onst 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 utils = require('zigbee-herdsman-converters/lib/utils'); 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 globalStore = require('zigbee-herdsman-converters/lib/store');

const definition = { fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_7rghpoxo'}], model: 'TS0601_Smart Thermostat', vendor: 'TuYa', description: 'Smart thermostat', fromZigbee: [fz.legacy.tuya_thermostat_weekly_schedule, fz.etop_thermostat, fz.ignore_basic_report, fz.ignore_tuya_set_time], toZigbee: [tz.etop_thermostat_system_mode, tz.etop_thermostat_away_mode, tz.tuya_thermostat_child_lock, tz.tuya_thermostat_current_heating_setpoint, tz.tuya_thermostat_weekly_schedule], onEvent: tuya.onEventSetTime, meta: { thermostat: { weeklyScheduleMaxTransitions: 4, weeklyScheduleSupportedModes: [1], // bits: 0-heat present, 1-cool present (dec: 1-heat,2-cool,3-heat+cool) weeklyScheduleFirstDayDpId: tuya.dataPoints.schedule, }, }, exposes: [e.child_lock(), exposes.climate().withSetpoint('current_heating_setpoint', 5, 35, 0.5, ea.STATE_SET) .withLocalTemperature(ea.STATE) .withSystemMode(['off', 'heat', 'auto'], ea.STATE_SET).withRunningState(['idle', 'heat'], ea.STATE) .withAwayMode()], };

module.exports = definition;

alehelley commented 4 days ago

Hello,

I have exactlly the same problem with a Samart Radiator valve. I have 20 of them. Is spent hours and hours trying to configure it. I'm desperated. I managed to make it supported by Z2M in HA by creating an external converter, but noting he exposed.

This is what i got in database.db :

{"id":23,"type":"EndDevice","ieeeAddr":"0xa4c138e87c289ab1","nwkAddr":8057,"manufId":4417,"manufName":"_TZE200_yqgbrdyo","powerSource":"Battery","modelId":"TS0601","epList":[1],"endpoints":{"1":{"profId":260,"epId":1,"devId":81,"inClusterList":[4,5,61184,0],"outClusterList":[25,10],"clusters":{},"binds":[],"configuredReportings":[],"meta":{}}},"zclVersion":3,"interviewCompleted":true,"meta":{},"lastSeen":1725995036406}

Heres is my external converter : const fz = require('zigbee-herdsman-converters/converters/fromZigbee'); const tz = require('zigbee-herdsman-converters/converters/toZigbee'); const e = require('zigbee-herdsman-converters/lib/exposes').presets; const ea = require('zigbee-herdsman-converters/lib/exposes').access; const reporting = require('zigbee-herdsman-converters/lib/reporting'); const ota = require('zigbee-herdsman-converters/lib/ota');

const definition = { zigbeeModel: ['TS0601'], model: 'TS0601_thermostat_3', vendor: 'Tuya', description: 'Thermostatic radiator valve', fromZigbee: [fz.thermostat, fz.ignore_basic_report], toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_system_mode, tz.on_off], exposes: [ e.climate().withSetpoint('occupied_heating_setpoint', 5, 30, 0.5).withLocalTemperature(), e.binary('state', ea.ALL, 'ON', 'OFF').withDescription('Thermostat state'), e.enum('system_mode', ea.ALL, ['off', 'auto', 'heat']).withDescription('System mode') ], meta: {multiEndpoint: true}, };

module.exports = definition;

Please Help

dweng0 commented 3 days ago

Hello,

I have exactlly the same problem with a Samart Radiator valve. I have 20 of them. Is spent hours and hours trying to configure it. I'm desperated. I managed to make it supported by Z2M in HA by creating an external converter, but noting he exposed.

This is what i got in database.db :

{"id":23,"type":"EndDevice","ieeeAddr":"0xa4c138e87c289ab1","nwkAddr":8057,"manufId":4417,"manufName":"_TZE200_yqgbrdyo","powerSource":"Battery","modelId":"TS0601","epList":[1],"endpoints":{"1":{"profId":260,"epId":1,"devId":81,"inClusterList":[4,5,61184,0],"outClusterList":[25,10],"clusters":{},"binds":[],"configuredReportings":[],"meta":{}}},"zclVersion":3,"interviewCompleted":true,"meta":{},"lastSeen":1725995036406}

Heres is my external converter : const fz = require('zigbee-herdsman-converters/converters/fromZigbee'); const tz = require('zigbee-herdsman-converters/converters/toZigbee'); const e = require('zigbee-herdsman-converters/lib/exposes').presets; const ea = require('zigbee-herdsman-converters/lib/exposes').access; const reporting = require('zigbee-herdsman-converters/lib/reporting'); const ota = require('zigbee-herdsman-converters/lib/ota');

const definition = { zigbeeModel: ['TS0601'], model: 'TS0601_thermostat_3', vendor: 'Tuya', description: 'Thermostatic radiator valve', fromZigbee: [fz.thermostat, fz.ignore_basic_report], toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_system_mode, tz.on_off], exposes: [ e.climate().withSetpoint('occupied_heating_setpoint', 5, 30, 0.5).withLocalTemperature(), e.binary('state', ea.ALL, 'ON', 'OFF').withDescription('Thermostat state'), e.enum('system_mode', ea.ALL, ['off', 'auto', 'heat']).withDescription('System mode') ], meta: {multiEndpoint: true}, };

module.exports = definition;

Please Help

You are missing the fingerprint property.

image The manufacturer should match the vendor in your auto generated definition: image

See how manufacturer and model match in the fingerprint object? image

When you restart z2m, what do the logs say about your converter file? (does it say its loaded or does it say if there's an error).

If your converter file loaded correctly

It will say the name of the file has been loaded in the logs: image

Or if it failed it will say something different, just to a CTRL-F and search for the name of your external converter file. in the example of the image it would be trv.js .

Once you've confirmed that your external converter is working. Take a look at the exposes tab and try to change some values. image

then go to the state tab and check if any of the published data is null: image

none of the state data should be null, if it is, the TRV doesn't support it and you need to modify your converter.js file accordingly. There will also be logs of errors when you tried changing values on the exposes tab.

Reasons for it to not work

If the value is coming back null. for a particular value, it could be one of:

If unsure, you can see how other devices are using the tuya value converter. If you are comfortable with visual code you can view the source code in github.dev here and do a CTRL-SHIFT-F search for specific values like tuya.vaueConverter. to see if they marry up correctly image

Hope this helps.

alehelley commented 3 days ago

Thank you for your answer. Unforunatly when I updated the external_converter.js with the fingerpint, the devices went to supported to unsuported ;( I'm lost...

Here is the .js I updated with the fingerprint :

image

const fz = require('zigbee-herdsman-converters/converters/fromZigbee'); const tz = require('zigbee-herdsman-converters/converters/toZigbee'); const e = require('zigbee-herdsman-converters/lib/exposes').presets; const ea = require('zigbee-herdsman-converters/lib/exposes').access; const reporting = require('zigbee-herdsman-converters/lib/reporting'); const ota = require('zigbee-herdsman-converters/lib/ota');

const definition = { fingerprint: [ { modelID: 'TS0601', manufacturerName: '_TZE200_yqgbrdyo', } ] zigbeeModel: ['TS0601'], model: 'TS0601_thermostat_3', vendor: 'Tuya', description: 'Thermostatic radiator valve', fromZigbee: [fz.thermostat, fz.ignore_basic_report], toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_system_mode, tz.on_off], exposes: [ e.climate().withSetpoint('occupied_heating_setpoint', 5, 30, 0.5).withLocalTemperature(), e.binary('state', ea.ALL, 'ON', 'OFF').withDescription('Thermostat state'), e.enum('system_mode', ea.ALL, ['off', 'auto', 'heat']).withDescription('System mode') ], meta: {multiEndpoint: true}, };

module.exports = definition;

alehelley commented 3 days ago

Here is my external definition :

image

dweng0 commented 1 day ago

Your vendor id is exactly the same as mine. try using my converter file:

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 definition = {
    fingerprint: [
        {
            modelID: 'TS0601',
            manufacturerName: '_TZE200_yqgbrdyo',
        },
    ],
    model: 'TRV06',
    vendor: 'EARU-electric',
        description: 'Thermostatic radiator valve',
        fromZigbee: [tuya.fz.datapoints],
        toZigbee: [tuya.tz.datapoints],
        onEvent: tuya.onEventSetTime,
        configure: tuya.configureMagicPacket,
        exposes: [
            e.child_lock(),
            e.battery_low(),
            e
                .climate()
                .withSetpoint('current_heating_setpoint', 5, 35, 1, ea.STATE_SET)
                .withLocalTemperature(ea.STATE)
                .withSystemMode(['auto', 'heat', 'off'], ea.STATE_SET)
                .withRunningState(['idle', 'heat'], ea.STATE)
                .withLocalTemperatureCalibration(-9, 9, 1, ea.STATE_SET),
            ...tuya.exposes.scheduleAllDays(ea.STATE_SET, 'HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C'),
            e
                .binary('scale_protection', ea.STATE_SET, 'ON', 'OFF')
                .withDescription(
                    'If the heat sink is not fully opened within ' +
                        'two weeks or is not used for a long time, the valve will be blocked due to silting up and the heat sink will not be ' +
                        'able to be used. To ensure normal use of the heat sink, the controller will automatically open the valve fully every ' +
                        'two weeks. It will run for 30 seconds per time with the screen displaying "Ad", then return to its normal working state ' +
                        'again.',
                ),
            e
                .binary('frost_protection', ea.STATE_SET, 'ON', 'OFF')
                .withDescription(
                    'When the room temperature is lower than 5 °C, the valve opens; when the temperature rises to 8 °C, the valve closes.',
                ),
            e.numeric('error', ea.STATE).withDescription('If NTC is damaged, "Er" will be on the TRV display.'),
        ],
        meta: {
            tuyaDatapoints: [
                [2, 'system_mode', tuya.valueConverterBasic.lookup({auto: tuya.enum(0), heat: tuya.enum(1), off: tuya.enum(2)})],
                [3, 'running_state', tuya.valueConverterBasic.lookup({heat: tuya.enum(0), idle: tuya.enum(1)})],
                [4, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
                [5, 'local_temperature', tuya.valueConverter.divideBy10],
                [7, 'child_lock', tuya.valueConverter.lockUnlock],
                [28, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(1)],
                [29, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(2)],
                [30, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(3)],
                [31, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(4)],
                [32, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(5)],
                [33, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(6)],
                [34, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(7)],
                [35, null, tuya.valueConverter.errorOrBatteryLow],
                [36, 'frost_protection', tuya.valueConverter.onOff],
                [39, 'scale_protection', tuya.valueConverter.onOff],
                [47, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration2],
            ],
        },
    }

module.exports =  definition;

I haven't tried the scheduler variables, but the important things like heating and target temperature works.

Don't forget when you update your converter file, to make sure its named in the configuration file and restart Zigbee, check the logs while its restarting, search for the name of your converter file to make sure it loaded correctly.

Give that a whirl. I'm confident it will work! 👍🏾

alehelley commented 1 day ago

OMG !!! Thank you so much !!! It works ! You can't imagine how grateful I am ! You gave an end to weeks of late night sleep ! Thank you so much

Koenkk commented 1 day ago

Added the device for out of the box support, thanks @dweng0 !

Changes will be available in the dev branch in a few hours from now.