Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New device support]: Moes Thermostat - _TZE204_lpedvtvr #25038

Open
TesterTurner opened this issue Dec 3, 2024 · 15 comments
Open

[New device support]: Moes Thermostat - _TZE204_lpedvtvr #25038

TesterTurner opened this issue Dec 3, 2024 · 15 comments
Labels
new device support New device support request

Comments

@TesterTurner
Copy link

Link

https://www.aliexpress.com/item/1005008017004760.html?src=google&pdp_npi=4%40dis%21GBP%2170.30%2130.29%21%21%21%21%21%40%2112000043377898982%21ppc%21%21%21&src=google&albch=shopping&acnt=494-037-6276&isdl=y&slnk=&plac=&mtctp=&albbt=Google_7_shopping&aff_platform=google&aff_short_key=UneMJZVf&gclsrc=aw.ds&&albagn=888888&&ds_e_adid=&ds_e_matchtype=&ds_e_device=c&ds_e_network=x&ds_e_product_group_id=&ds_e_product_id=en1005008017004760&ds_e_product_merchant_id=680478118&ds_e_product_country=GB&ds_e_product_language=en&ds_e_product_channel=online&ds_e_product_store_id=&ds_url_v=2&albcp=17859500389&albag=&isSmbAutoCall=false&needSmbHouyi=false&gad_source=1&gclid=CjwKCAiA9bq6BhAKEiwAH6bqoMyzGa27lfVQmlZ0p5iPXlytCHGEa1BQZJNKFUxZJDIftZi1K48KrBoCDSAQAvD_BwE

Database entry

{"id":41,"type":"Router","ieeeAddr":"0xa4c1383ebb899b92","nwkAddr":57155,"manufId":4417,"manufName":"_TZE204_lpedvtvr","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":"\u0007\u000b�.i\u0007\u000b�.i","65506":56,"65508":0,"stackVersion":0,"dateCode":"","appVersion":74}}},"binds":[],"configuredReportings":[],"meta":{}},"242":{"profId":41440,"epId":242,"devId":97,"inClusterList":[],"outClusterList":[33],"clusters":{},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":74,"stackVersion":0,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"meta":{},"lastSeen":1733251203681}

Zigbee2MQTT version

1.42.0-2

Comments

Good Evening, I am struggling to get a working converter for this new thermostat released by Moes. Am unable to locate anything similar to attempt to clone or Frankenstein to get basic functionality. I apologise, I don't seem to have the required skill set to get it running, it has provided no information under the 'Expose' Tab, Could you please assist.

External definition

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

module.exports = definition;

What does/doesn't work with the external definition?

the external definition only provides link quality, No further functionality.

@TesterTurner TesterTurner added the new device support New device support request label Dec 3, 2024
@TesterTurner
Copy link
Author

I have still not had any luck so far trying to use an alternate configuration to get basic functionality from the thermostat.

@Racermouse
Copy link

Racermouse commented Dec 6, 2024

You are not alone!

@Racermouse
Copy link

My coding skills are very weak, and could not get this to work either.
Here's all I could find out from the z2m debug log:

Temp set point:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,205],"type":"Buffer"},"datatype":2,"dp":50}],"seq":4352}' from endpoint 1 with groupID 0

Internal temp sensor reading:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,180],"type":"Buffer"},"datatype":2,"dp":16}],"seq":15616}' from endpoint 1 with groupID 0

External temp sensor reading:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,195],"type":"Buffer"},"datatype":2,"dp":109}],"seq":9984}' from endpoint 1 with groupID 0

Heating on:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":4,"dp":47}],"seq":26112}' from endpoint 1 with groupID

Heating off:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[1],"type":"Buffer"},"datatype":4,"dp":47}],"seq":29184}' from endpoint 1 with groupID 0

ON/OFF

On:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[1],"type":"Buffer"},"datatype":1,"dp":1}],"seq":23040}' from endpoint 1 with groupID 0

Off:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":1,"dp":1}],"seq":34048}' from endpoint 1 with groupID 0

WORK MODE

Manual:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":4,"dp":2}],"seq":60672}' from endpoint 1 with groupID 0

Temporary manual:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[1],"type":"Buffer"},"datatype":4,"dp":2}],"seq":51968}' from endpoint 1 with groupID 0

Programming
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[2],"type":"Buffer"},"datatype":4,"dp":2}],"seq":46336}' from endpoint 1 with groupID 0

Eco:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[3],"type":"Buffer"},"datatype":4,"dp":2}],"seq":42240}' from endpoint 1 with groupID 0

SCREEN BRIGHTNESS

Standby brightness adjustment:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,66],"type":"Buffer"},"datatype":2,"dp":48}],"seq":4608}' from endpoint 1 with groupID 0

CHILD LOCK

Child lock on:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[1],"type":"Buffer"},"datatype":1,"dp":39}],"seq":13312}' from endpoint 1 with groupID 0

Child lock off:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":1,"dp":39}],"seq":16128}' from endpoint 1 with groupID 0

SENSOR TYPE

In:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":4,"dp":32}],"seq":30208}' from endpoint 1 with groupID 0

AL:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[1],"type":"Buffer"},"datatype":4,"dp":32}],"seq":35328}' from endpoint 1 with groupID 0

Ou:
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[2],"type":"Buffer"},"datatype":4,"dp":32}],"seq":37376}' from endpoint 1 with groupID 0

What the hell is this:
'Kitchen_Floor_Therm', type 'attributeReport', cluster 'genBasic', data '{"65503":"8\u000f .iF\u000f .iG\u000f .iL\u000f .i[\u000f .if\u000f .ig\u000f .ip\u000f .iv\u000f .iw\u000f .i"}' from endpoint 1 with groupID 0

This Is from startup:

'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,1,194],"type":"Buffer"},"datatype":2,"dp":34}],"seq":256}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,50],"type":"Buffer"},"datatype":2,"dp":18}],"seq":768}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'attributeReport', cluster 'genBasic', data '{"65506":56,"65508":1,"appVersion":74}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[1],"type":"Buffer"},"datatype":1,"dp":115}],"seq":1024}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":4,"dp":47}],"seq":1280}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,250],"type":"Buffer"},"datatype":2,"dp":50}],"seq":1536}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandMcuVersionResponse', cluster 'manuSpecificTuya', data '{"seq":2048,"version":65}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,185],"type":"Buffer"},"datatype":2,"dp":16}],"seq":1792}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[1],"type":"Buffer"},"datatype":1,"dp":1}],"seq":2048}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[1],"type":"Buffer"},"datatype":4,"dp":2}],"seq":2304}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,250],"type":"Buffer"},"datatype":2,"dp":50}],"seq":2560}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":4,"dp":47}],"seq":2816}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[2],"type":"Buffer"},"datatype":4,"dp":32}],"seq":3072}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0],"type":"Buffer"},"datatype":1,"dp":39}],"seq":3328}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,68],"type":"Buffer"},"datatype":2,"dp":48}],"seq":3584}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[255,255,255,250],"type":"Buffer"},"datatype":2,"dp":101}],"seq":3840}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,5],"type":"Buffer"},"datatype":2,"dp":110}],"seq":4096}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,1,194],"type":"Buffer"},"datatype":2,"dp":111}],"seq":4352}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,0],"type":"Buffer"},"datatype":2,"dp":112}],"seq":4608}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,1,44],"type":"Buffer"},"datatype":2,"dp":113}],"seq":4864}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandMcuSyncTime', cluster 'manuSpecificTuya', data '{"payloadSize":20}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,185],"type":"Buffer"},"datatype":2,"dp":16}],"seq":5376}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[0,0,0,185],"type":"Buffer"},"datatype":2,"dp":109}],"seq":5632}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[1],"type":"Buffer"},"datatype":4,"dp":114}],"seq":5888}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'read', cluster 'genTime', data '["localTime"]' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[1,6,0,0,200,11,30,0,200,13,30,0,200,17,30,0,200],"type":"Buffer"},"datatype":0,"dp":102}],"seq":6144}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[2,6,0,0,200,11,30,0,200,13,30,0,200,17,30,0,200],"type":"Buffer"},"datatype":0,"dp":103}],"seq":6400}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[3,6,0,0,200,11,30,0,200,13,30,0,200,17,30,0,200],"type":"Buffer"},"datatype":0,"dp":104}],"seq":6656}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[4,6,0,0,200,11,30,0,200,13,30,0,200,17,30,0,200],"type":"Buffer"},"datatype":0,"dp":105}],"seq":6912}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[5,6,0,0,200,11,30,0,200,13,30,0,200,17,30,0,200],"type":"Buffer"},"datatype":0,"dp":106}],"seq":7168}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[6,6,0,0,200,11,30,0,200,13,30,0,200,17,30,0,200],"type":"Buffer"},"datatype":0,"dp":107}],"seq":7424}' from endpoint 1 with groupID 0
'Kitchen_Floor_Therm', type 'commandDataReport', cluster 'manuSpecificTuya', data '{"dpValues":[{"data":{"data":[7,6,0,0,200,11,30,0,200,13,30,0,200,17,30,0,200],"type":"Buffer"},"datatype":0,"dp":108}],"seq":7680}' from endpoint 1 with groupID 0

@magic1447
Copy link

Hello! Im also very interested in support for this device!

@Racermouse
Copy link

I got it working enough to do the stuff I need to do in Node-Red.
I'll post the converter file later tonight.
Be warned that It is very untidy and contains stuff that does not work.

@Racermouse
Copy link

This converter is a wreck, but it will get basic functionality up and running.
Use at own risk.
moes_zht_sr.zip

Cheers!

@TesterTurner
Copy link
Author

That zip file you have dropped in flags as containing a virus/malware, so I shall play it safe by not opening it, I'm sure its probably just my system playing it safe however to play on the safe side, could you paste your converter directly in?

@Racermouse
Copy link

Racermouse commented Dec 8, 2024

Sure!
I have no idea what the "eco temperature" does. It doesn't seem to have any effect on the relay. It's just always on if in "eco" mode
Dataponts that are not configured with a proper number ends with "NOT SET".
Time is shown correctly for me, but not the day of the week, it's off by two days backwards?!?

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 = {
        fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE204_lpedvtvr'}],
        model: 'ZHT_SR',
        vendor: 'Moes',
        description: 'Thermostat for electric floor',
        fromZigbee: [tuya.fz.datapoints],
        toZigbee: [tuya.tz.datapoints],
        onEvent: tuya.onEventSetTime,
        configure: tuya.configureMagicPacket,
        exposes: [
            e.binary('child_lock', ea.STATE_SET, 'ON', 'OFF').withLabel('Child lock'),
            e.binary('eco_mode', ea.STATE_SET, 'OFF', 'ON').withLabel('ECO mode NOT SET').withDescription('Default: Off'),
            e
                .numeric('eco_temperature', ea.STATE_SET)
                .withValueMin(5)
                .withValueMax(30)
                .withValueStep(1)
                .withUnit('°C')
		.withLabel('Eco temperature')
                .withDescription('Max temperature in ECO mode. Default: 20'),
            e.binary('valve_state', ea.STATE, false, true).withLabel('Heating in process'),
            e
                .climate()
                .withSystemMode(['off', 'heat'], ea.STATE_SET)
                .withPreset(['manual', 'temp_manual', 'programming', 'eco'])
                .withSetpoint('current_heating_setpoint', 5, 35, 0.5, ea.STATE_SET)
                .withLocalTemperature(ea.STATE)
                .withLocalTemperatureCalibration(-9, 9, 1, ea.STATE_SET)
                .withDescription('Default: -3'),
            e
                .numeric('deadzone_temperature', ea.STATE_SET)
                .withValueMin(1)
                .withValueMax(5)
                .withValueStep(1)
                .withUnit('°C')
		.withLabel('Deadzone temperature NOT SET')
                .withDescription('Hysteresis. Default: 1'),

            e.numeric('min_temperature', ea.STATE_SET)
		.withValueMin(5)
		.withValueMax(15)
		.withValueStep(1)
		.withUnit('°C')
		.withLabel('Minimum temperature NOT SET')
		.withDescription('Default: 5'),
            e
                .numeric('max_temperature', ea.STATE_SET)
                .withValueMin(15)
                .withValueMax(45)
                .withValueStep(1)
                .withUnit('°C')
		.withLabel('Maximum temperature NOT SET')
                .withDescription('Default: 35'),
            e
                .numeric('min_temperature_limit', ea.STATE_SET)
                .withValueMin(0)
                .withValueMax(10)
                .withValueStep(1)
                .withUnit('°C')
                .withLabel('Low temperature protection NOT SET')
                .withDescription('Default: 0'),
            e
                .numeric('max_temperature_limit', ea.STATE_SET)
                .withValueMin(25)
                .withValueMax(70)
                .withValueStep(1)
                .withUnit('°C')
                .withLabel('High temperature protection NOT SET')
                .withDescription('Default: 45'),
            e.temperature_sensor_select(['IN', 'OU', 'AL']).withLabel('Sensor').withDescription('Choose which sensor to use. Default: AL'),
            e
                .numeric('external_temperature_input', ea.STATE)
                .withLabel('Floor temperature')
                .withUnit('°C')
                .withDescription('Temperature from floor sensor'),
            e
                .numeric('brightness', ea.STATE_SET)
                .withValueMin(0)
                .withValueMax(8)
                .withValueStep(1)
                .withLabel('Screen brightness NOT SET')
                .withDescription('0 - on for 10 seconds. Default: 6'),
            e
                .numeric('display_brightness', ea.STATE_SET)
                .withValueMin(0)
                .withValueMax(100)
                .withValueStep(1)
                .withLabel('Stanby screen brightness')
                .withDescription('0-100%'),
            e
                .text('schedule_monday', ea.STATE_SET)
                .withLabel('Schedule for monday TIMETABLES NOT TESTED')
                .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
            e
                .text('schedule_tuesday', ea.STATE_SET)
                .withLabel('Schedule for tuesday')
                .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
            e
                .text('schedule_wednesday', ea.STATE_SET)
                .withLabel('Schedule for wednesday')
                .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
            e
                .text('schedule_thursday', ea.STATE_SET)
                .withLabel('Schedule for thursday')
                .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
            e
                .text('schedule_friday', ea.STATE_SET)
                .withLabel('Schedule for friday')
                .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
            e
                .text('schedule_saturday', ea.STATE_SET)
                .withLabel('Schedule for saturday')
                .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
            e
                .text('schedule_sunday', ea.STATE_SET)
                .withLabel('Schedule for sunday')
                .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
            e.enum('factory_reset', ea.STATE_SET, ['factory reset']).withLabel('Factory reset NOT SET').withDescription('Reset all settings to factory ones'),
        ],
        meta: {
            tuyaDatapoints: [
                [1, 'system_mode', tuya.valueConverterBasic.lookup({off: false, heat: true})],
                [2, 'preset', tuya.valueConverterBasic.lookup({manual: tuya.enum(0), temp_manual: tuya.enum(1), programming: tuya.enum(2), eco: tuya.enum(3)})],
                [50, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
                [19, 'max_temperature', tuya.valueConverter.divideBy10],
                [16, 'local_temperature', tuya.valueConverter.divideBy10],
                [26, 'min_temperature', tuya.valueConverter.divideBy10],
                [27, 'local_temperature_calibration', tuya.valueConverter.raw],
                [28, 'factory_reset', tuya.valueConverterBasic.lookup({factory_reset: true})],
                [47, 'valve_state', tuya.valueConverter.trueFalseInvert],
                [39, 'child_lock', tuya.valueConverterBasic.lookup({ON: true, OFF: false})],
                [40, 'eco_mode', tuya.valueConverterBasic.lookup({ON: true, OFF: false})],
                [32, 'sensor', tuya.valueConverterBasic.lookup({IN: tuya.enum(0), OU: tuya.enum(2), AL: tuya.enum(1)})],
                [109, 'external_temperature_input', tuya.valueConverter.divideBy10],
                [110, 'deadzone_temperature', tuya.valueConverter.raw],
                [104, 'max_temperature_limit', tuya.valueConverter.divideBy10],
                [102, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(1)],
                [103, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(2)],
                [104, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(3)],
                [105, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(4)],
                [106, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(5)],
                [107, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(6)],
                [108, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(7)],
                [114, 'min_temperature_limit', tuya.valueConverter.divideBy10],
                [113, 'eco_temperature', tuya.valueConverter.divideBy10],
                [115, 'brightness', tuya.valueConverter.raw],
                [48, 'display_brightness', tuya.valueConverter.raw],
            ],
        },
};

module.exports = definition;

@szheliab
Copy link

szheliab commented Dec 8, 2024

Hi there!

Here are datapoints that I've got from Tuya hub:

{
  "1": "Switch",
  "2": "Work Mode",
  "16": "Current temperature",
  "18": "The lower limit of temperature",
  "28": "Factory data reset",
  "32": "Sensor selection",
  "34": "Set temperature ceiling",
  "39": "Child lock",
  "47": "State of the valve",
  "48": "Backlight brightness",
  "50": "Set temperature",
  "101": "Temp Calibration",
  "102": "Week Program 13 1",
  "103": "Week Program 13 2",
  "104": "Week Program 13 3",
  "105": "Week Program 13 4",
  "106": "Week Program 13 5",
  "107": "Week Program 13 6",
  "108": "Week Program 13 7",
  "109": "Floor temp.",
  "110": "Dead zone temp.",
  "111": "High protect temp.",
  "112": "Low protection temp.",
  "113": "Eco cool temp.",
  "114": "Screen Time Set",
  "115": "Rgblight"
}

@szheliab
Copy link

szheliab commented Dec 8, 2024

...And here's mine version of external converter for this thermostat 😃

const exposes = require('zigbee-herdsman-converters/lib/exposes');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const e = exposes.presets;
const ea = exposes.access;

const definition = {
    zigbeeModel: ['TS0601'],
    model: 'ZHT-SR-GB',
    vendor: 'Moes',
    description: 'Smart knob thermostat',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    exposes: [
        e.binary('child_lock', ea.STATE_SET, 'ON', 'OFF').withLabel('Child lock'),
        e.binary('rgb_backlight', ea.STATE_SET, 'OFF', 'ON').withLabel('RGB backlight').withDescription('Default: Off'),
        e.numeric('eco_temperature', ea.STATE_SET)
            .withValueMin(5)
            .withValueMax(30)
            .withValueStep(1)
            .withUnit('°C')
            .withDescription('Max temperature in ECO mode. Default: 20'),
        e.binary('valve_state', ea.STATE, false, true).withLabel('Heating in process'),
        e.climate()
            .withSystemMode(['off', 'heat'], ea.STATE_SET)
            .withPreset(['manual', 'temporary manual', 'schedule', 'eco'])
            .withSetpoint('current_heating_setpoint', 5, 35, 0.5, ea.STATE_SET)
            .withLocalTemperature(ea.STATE)
            .withLocalTemperatureCalibration(-9, 9, 0.1, ea.STATE_SET)
            .withDescription('Default: -3'),
        e.numeric('deadzone_temperature', ea.STATE_SET)
            .withValueMin(1)
            .withValueMax(5)
            .withValueStep(1)
            .withUnit('°C')
            .withDescription('Hysteresis. Default: 1'),
        e.numeric('min_temperature', ea.STATE_SET)
            .withValueMin(5)
            .withValueMax(15)
            .withValueStep(1)
            .withUnit('°C')
            .withDescription('Default: 5'),
        e.numeric('max_temperature', ea.STATE_SET)
            .withValueMin(15)
            .withValueMax(45)
            .withValueStep(1)
            .withUnit('°C')
            .withDescription('Default: 35'),
        e.numeric('min_temperature_limit', ea.STATE_SET)
            .withValueMin(0)
            .withValueMax(10)
            .withValueStep(1)
            .withUnit('°C')
            .withLabel('Low temperature protection')
            .withDescription('Default: 0'),
        e.numeric('lower_limit_of_temperature', ea.STATE_SET)
            .withValueMin(5)
            .withValueMax(15)
            .withValueStep(1)
            .withUnit('°C')
            .withLabel('The lower limit of temperature')
            .withDescription('Default: 5'),
        e.enum('sensor', ea.STATE_SET, ['IN', 'OU', 'AL']).withLabel('Sensor')
            .withDescription('Choose which sensor to use. Default: AL'),
        e.numeric('external_temperature_input', ea.STATE)
            .withLabel('Floor temperature')
            .withUnit('°C')
            .withDescription('Temperature from floor sensor'),
        e.numeric('brightness', ea.STATE_SET)
            .withValueMin(0)
            .withValueMax(100)
            .withValueStep(1)
            .withLabel('Backlight brightness')
            .withDescription('Backlight brightness in %'),
        e.text('schedule_monday', ea.STATE_SET)
            .withLabel('Schedule for monday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.text('schedule_tuesday', ea.STATE_SET)
            .withLabel('Schedule for tuesday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.text('schedule_wednesday', ea.STATE_SET)
            .withLabel('Schedule for wednesday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.text('schedule_thursday', ea.STATE_SET)
            .withLabel('Schedule for thursday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.text('schedule_friday', ea.STATE_SET)
            .withLabel('Schedule for friday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.text('schedule_saturday', ea.STATE_SET)
            .withLabel('Schedule for saturday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.text('schedule_sunday', ea.STATE_SET)
            .withLabel('Schedule for sunday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.enum('factory_reset', ea.STATE_SET, ['factory_reset'])
            .withLabel('Factory reset')
            .withDescription('Reset all settings to factory ones'),
            
        e.enum('screen_time_set', ea.STATE_SET, ['off', '10s', '30s', '60s'])
            .withLabel('Screen Timeout')
            .withDescription('Set screen timeout duration. Default: off'),
    ],
    meta: {
        tuyaDatapoints: [
            [1, 'system_mode', tuya.valueConverterBasic.lookup({off: false, heat: true})],
            [2, 'preset', tuya.valueConverterBasic.lookup({manual: tuya.enum(0), 'temporary manual': tuya.enum(1), schedule: tuya.enum(2), eco: tuya.enum(3)})],
            [16, 'local_temperature', tuya.valueConverter.divideBy10],
            [18, 'lower_limit_of_temperature', tuya.valueConverter.divideBy10],
            [28, 'factory_reset', tuya.valueConverterBasic.lookup({factory_reset: true})],
            [32, 'sensor', tuya.valueConverterBasic.lookup({IN: tuya.enum(0), OU: tuya.enum(2), AL: tuya.enum(1)})],
            [34, 'max_temperature', tuya.valueConverter.divideBy10],
            [39, 'child_lock', tuya.valueConverterBasic.lookup({ON: true, OFF: false})],
            [47, 'valve_state', tuya.valueConverter.trueFalseInvert],
            [48, 'brightness', tuya.valueConverter.raw],
            [50, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
            [101, 'local_temperature_calibration', tuya.valueConverter.divideBy10],
            [102, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(1)],
            [103, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(2)],
            [104, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(3)],
            [105, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(4)],
            [106, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(5)],
            [107, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(6)],
            [108, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(7)],
            [109, 'external_temperature_input', tuya.valueConverter.divideBy10],
            [110, 'deadzone_temperature', tuya.valueConverter.raw],
            [111, 'max_temperature_limit', tuya.valueConverter.divideBy10],
            [112, 'min_temperature_limit', tuya.valueConverter.divideBy10],
            [113, 'eco_temperature', tuya.valueConverter.divideBy10],
            [114, 'screen_time_set', tuya.valueConverterBasic.lookup({
                off: tuya.enum(0), 
                '10s': tuya.enum(1), 
                '30s': tuya.enum(2), 
                '60s': tuya.enum(3)
            })],
            [115, 'rgb_backlight', tuya.valueConverterBasic.lookup({ON: true, OFF: false})],
        ],
    },
    onEvent: tuya.onEventSetLocalTime,
};

module.exports = definition;

@Racermouse
Copy link

Racermouse commented Dec 8, 2024

Nice.
I have no Tuya bridge, so thanks for the help!
...and I think most of the temp tings are .withValueStep(0.5)

@Racermouse
Copy link

Racermouse commented Dec 8, 2024

Screen timeouts are 10, 20, 30, 40 s.

@Racermouse
Copy link

Can't seem to get the "deadzone_temperature" and "local_temperature_calibration" to work properly. Might have something to do with factors?

@szheliab
Copy link

szheliab commented Dec 9, 2024

Not sure, but seems that calibration works now :)

Here is updated converter (fixed default values, min/max values, etc.), can you please try it?

const exposes = require('zigbee-herdsman-converters/lib/exposes');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const e = exposes.presets;
const ea = exposes.access;

const definition = {
    zigbeeModel: ['TS0601'],
    model: 'ZHT-SR-GB',
    vendor: 'Moes',
    description: 'Smart knob thermostat',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    exposes: [
        e.binary('child_lock', ea.STATE_SET, 'ON', 'OFF').withLabel('Child lock'),
        e.binary('rgb_backlight', ea.STATE_SET, 'ON', 'OFF').withLabel('RGB backlight').withDescription('Default: On'),
        e.numeric('eco_temperature', ea.STATE_SET)
            .withValueMin(10)
            .withValueMax(30)
            .withValueStep(1)
            .withUnit('°C')
            .withDescription('Max temperature in ECO mode. Default: 30'),
        e.binary('valve_state', ea.STATE, false, true).withLabel('Heating in process'),
        e.climate()
            .withSystemMode(['off', 'heat'], ea.STATE_SET)
            .withPreset(['manual', 'temporary manual', 'schedule', 'eco'])
            .withSetpoint('current_heating_setpoint', 5, 45, 0.5, ea.STATE_SET)
            .withLocalTemperature(ea.STATE)
            .withLocalTemperatureCalibration(-10, 10, 1, ea.STATE_SET)
            .withDescription('Default: 22'),
        e.numeric('deadzone_temperature', ea.STATE_SET)
            .withValueMin(0.5)
            .withValueMax(5)
            .withValueStep(0.5)
            .withLabel('Dead zone temperature')
            .withUnit('°C')
            .withDescription('Default: 0.5'),
        e.numeric('max_temperature', ea.STATE_SET)
            .withValueMin(35)
            .withValueMax(45)
            .withValueStep(1)
            .withLabel('Set temperature ceiling')
            .withUnit('°C')
            .withDescription('Default: 45'),
        e.numeric('min_temperature_limit', ea.STATE_SET)
            .withValueMin(0)
            .withValueMax(10)
            .withValueStep(1)
            .withUnit('°C')
            .withLabel('Low temperature protection')
            .withDescription('Default: 0'),
        e.numeric('max_temperature_limit', ea.STATE_SET)
            .withValueMin(10)
            .withValueMax(70)
            .withValueStep(1)
            .withLabel('High temperature protection')
            .withUnit('°C')
            .withDescription('Default: 45'),
        e.numeric('lower_limit_of_temperature', ea.STATE_SET)
            .withValueMin(5)
            .withValueMax(15)
            .withValueStep(1)
            .withUnit('°C')
            .withLabel('The lower limit of temperature')
            .withDescription('Default: 5'),
        e.enum('sensor', ea.STATE_SET, ['IN', 'OU', 'AL']).withLabel('Sensor')
            .withDescription('Choose which sensor to use. Default: AL'),
        e.numeric('external_temperature_input', ea.STATE)
            .withLabel('Floor temperature')
            .withUnit('°C')
            .withDescription('Temperature from floor sensor'),
        e.numeric('brightness', ea.STATE_SET)
            .withValueMin(0)
            .withValueMax(100)
            .withValueStep(1)
            .withLabel('Backlight brightness')
            .withUnit('%')
            .withDescription('Backlight brightness in %. Default: 5%'),
        e.text('schedule_monday', ea.STATE_SET)
            .withLabel('Schedule for monday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.text('schedule_tuesday', ea.STATE_SET)
            .withLabel('Schedule for tuesday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.text('schedule_wednesday', ea.STATE_SET)
            .withLabel('Schedule for wednesday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.text('schedule_thursday', ea.STATE_SET)
            .withLabel('Schedule for thursday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.text('schedule_friday', ea.STATE_SET)
            .withLabel('Schedule for friday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.text('schedule_saturday', ea.STATE_SET)
            .withLabel('Schedule for saturday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.text('schedule_sunday', ea.STATE_SET)
            .withLabel('Schedule for sunday')
            .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
        e.enum('factory_reset', ea.STATE_SET, ['factory_reset'])
            .withLabel('Factory reset')
            .withDescription('Reset all settings to factory ones'),
        e.enum('screen_time_set', ea.STATE_SET, ['10s', '20s', '30s', '40s', '50s', '60s'])
            .withLabel('Screen Timeout')
            .withDescription('Set screen timeout duration. Default: 20s'),
    ],
    meta: {
        tuyaDatapoints: [
            [1, 'system_mode', tuya.valueConverterBasic.lookup({off: false, heat: true})],
            [2, 'preset', tuya.valueConverterBasic.lookup({manual: tuya.enum(0), 'temporary manual': tuya.enum(1), schedule: tuya.enum(2), eco: tuya.enum(3)})],
            [16, 'local_temperature', tuya.valueConverter.divideBy10],
            [18, 'lower_limit_of_temperature', tuya.valueConverter.divideBy10],
            [28, 'factory_reset', tuya.valueConverterBasic.lookup({factory_reset: true})],
            [32, 'sensor', tuya.valueConverterBasic.lookup({IN: tuya.enum(0), OU: tuya.enum(2), AL: tuya.enum(1)})],
            [34, 'max_temperature', tuya.valueConverter.divideBy10],
            [39, 'child_lock', tuya.valueConverterBasic.lookup({ON: true, OFF: false})],
            [47, 'valve_state', tuya.valueConverter.trueFalseInvert],
            [48, 'brightness', tuya.valueConverter.raw],
            [50, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
            [101, 'local_temperature_calibration', tuya.valueConverter.localTemperatureCalibration],
            [102, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(1)],
            [103, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(2)],
            [104, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(3)],
            [105, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(4)],
            [106, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(5)],
            [107, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(6)],
            [108, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(7)],
            [109, 'external_temperature_input', tuya.valueConverter.divideBy10],
            [110, 'deadzone_temperature', tuya.valueConverter.raw],
            [111, 'max_temperature_limit', tuya.valueConverter.divideBy10],
            [112, 'min_temperature_limit', tuya.valueConverter.divideBy10],
            [113, 'eco_temperature', tuya.valueConverter.divideBy10],
            [114, 'screen_time_set', tuya.valueConverterBasic.lookup({
                '10s': tuya.enum(0),
                '20s': tuya.enum(1),
                '30s': tuya.enum(2),
                '40s': tuya.enum(3),
                '50s': tuya.enum(4),
                '60s': tuya.enum(5)
            })],
            [115, 'rgb_backlight', tuya.valueConverterBasic.lookup({ON: true, OFF: false})],
        ],
    },
    onEvent: tuya.onEventSetLocalTime,
};

module.exports = definition;

@Racermouse
Copy link

I tried the code and it worked for me anyway.

Some things I changed to my way of using a floor thermostat.
Limits have been change. Don't know what the real device limits are, but the ones in the code below works.
Dead zone (hysteresis) needs to be multiplied by 10 to work. I have no idea how to do it. Can't find a tuya.valueConverter to do this.

...and I don't know why the code does not show up here properly.
Sorry.

const exposes = require('zigbee-herdsman-converters/lib/exposes');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const e = exposes.presets;
const ea = exposes.access;

const definition = {
zigbeeModel: ['TS0601'],
model: 'ZHT-SR-GB',
vendor: 'Moes',
description: 'Smart knob thermostat',
fromZigbee: [tuya.fz.datapoints],
toZigbee: [tuya.tz.datapoints],
exposes: [
e.binary('child_lock', ea.STATE_SET, 'ON', 'OFF').withLabel('Child lock'),

    e.binary('rgb_backlight', ea.STATE_SET, 'ON', 'OFF').withLabel('Knob light').withDescription('Default: On'),

    e.numeric('eco_temperature', ea.STATE_SET)
        .withValueMin(10)
        .withValueMax(30)
        .withValueStep(0.5)
        .withUnit('°C')
        .withDescription('Max temperature in ECO mode. Default: 30'),

    e.binary('valve_state', ea.STATE, false, true).withLabel('Heating in progress'),

    e.climate()
        .withSystemMode(['off', 'heat'], ea.STATE_SET)
        .withPreset(['manual', 'temporary manual', 'schedule', 'eco'])
        .withSetpoint('current_heating_setpoint', 5, 45, 0.5, ea.STATE_SET)
        .withLocalTemperature(ea.STATE)
        .withLocalTemperatureCalibration(-10, 10, 1, ea.STATE_SET)
        .withDescription('Default: 22'),

    e.numeric('deadzone_temperature', ea.STATE_SET)
        .withValueMin(5)
        .withValueMax(50)
        .withValueStep(5)
        .withLabel('Dead zone temperature')
        .withUnit('°C')
        .withDescription('Default: 0.5'),

    e.numeric('max_temperature', ea.STATE_SET)
        .withValueMin(20)
        .withValueMax(45)
        .withValueStep(0.5)
        .withLabel('Maximum temperature setpont on device')
        .withUnit('°C')
        .withDescription('Default: 45'),

    e.numeric('lower_limit_of_temperature', ea.STATE_SET)
        .withValueMin(5)
        .withValueMax(20)
        .withValueStep(0.5)
        .withUnit('°C')
        .withLabel('Minimum temperature setpont on device')
        .withDescription('Default: 5'),

    e.numeric('external_temperature_input', ea.STATE)
        .withLabel('Floor temperature')
        .withUnit('°C')
        .withDescription('Current temperature measured from floor sensor'),

    e.numeric('max_temperature_limit', ea.STATE_SET)
        .withValueMin(25)
        .withValueMax(45)
        .withValueStep(0.5)
        .withLabel('Maximum floor temperature')
        .withUnit('°C')
        .withDescription('Default: 45'),

    e.numeric('min_temperature_limit', ea.STATE_SET)
        .withValueMin(0)
        .withValueMax(25)
        .withValueStep(0.5)
        .withUnit('°C')
        .withLabel('Minimum floor temperature')
        .withDescription('Default: 0'),

    e.enum('sensor', ea.STATE_SET, ['IN', 'OU', 'AL']).withLabel('Sensor')
        .withDescription('Choose which sensor to use. Default: AL'),

    e.numeric('brightness', ea.STATE_SET)
        .withValueMin(0)
        .withValueMax(100)
        .withValueStep(1)
        .withLabel('Display stanby brightness')
        .withUnit('%')
        .withDescription('Display brightness in %. Default: 5%'),

    e.text('schedule_monday', ea.STATE_SET)
        .withLabel('Schedule for monday')
        .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
    e.text('schedule_tuesday', ea.STATE_SET)
        .withLabel('Schedule for tuesday')
        .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
    e.text('schedule_wednesday', ea.STATE_SET)
        .withLabel('Schedule for wednesday')
        .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
    e.text('schedule_thursday', ea.STATE_SET)
        .withLabel('Schedule for thursday')
        .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
    e.text('schedule_friday', ea.STATE_SET)
        .withLabel('Schedule for friday')
        .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
    e.text('schedule_saturday', ea.STATE_SET)
        .withLabel('Schedule for saturday')
        .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),
    e.text('schedule_sunday', ea.STATE_SET)
        .withLabel('Schedule for sunday')
        .withDescription('Default: 06:00/20.0 11:30/20.0 13:30/20.0 17:30/20.0'),

    e.enum('factory_reset', ea.STATE_SET, ['factory_reset'])
        .withLabel('Factory reset')
        .withDescription('Reset all settings to factory ones'),

    e.enum('screen_time_set', ea.STATE_SET, ['10s', '20s', '30s', '40s', '50s', '60s'])
        .withLabel('Screen Timeout')
        .withDescription('Set screen timeout duration. Default: 20s'),
],
meta: {
    tuyaDatapoints: [
        [1, 'system_mode', tuya.valueConverterBasic.lookup({off: false, heat: true})],
        [2, 'preset', tuya.valueConverterBasic.lookup({manual: tuya.enum(0), 'temporary manual': tuya.enum(1), schedule: tuya.enum(2), eco: tuya.enum(3)})],
        [16, 'local_temperature', tuya.valueConverter.divideBy10],
        [18, 'lower_limit_of_temperature', tuya.valueConverter.divideBy10],
        [28, 'factory_reset', tuya.valueConverterBasic.lookup({factory_reset: true})],
        [32, 'sensor', tuya.valueConverterBasic.lookup({IN: tuya.enum(0), OU: tuya.enum(2), AL: tuya.enum(1)})],
        [34, 'max_temperature', tuya.valueConverter.divideBy10],
        [39, 'child_lock', tuya.valueConverterBasic.lookup({ON: true, OFF: false})],
        [47, 'valve_state', tuya.valueConverter.trueFalseInvert],
        [48, 'brightness', tuya.valueConverter.raw],
        [50, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
        [101, 'local_temperature_calibration', tuya.valueConverter.localTemperatureCalibration],
        [102, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(1)],
        [103, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(2)],
        [104, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(3)],
        [105, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(4)],
        [106, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(5)],
        [107, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(6)],
        [108, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(7)],
        [109, 'external_temperature_input', tuya.valueConverter.divideBy10],
        [110, 'deadzone_temperature', tuya.valueConverter.raw],
        [111, 'max_temperature_limit', tuya.valueConverter.divideBy10],
        [112, 'min_temperature_limit', tuya.valueConverter.divideBy10],
        [113, 'eco_temperature', tuya.valueConverter.divideBy10],
        [114, 'screen_time_set', tuya.valueConverterBasic.lookup({
            '10s': tuya.enum(0),
            '20s': tuya.enum(1),
            '30s': tuya.enum(2),
            '40s': tuya.enum(3),
            '50s': tuya.enum(4),
            '60s': tuya.enum(5)
        })],
        [115, 'rgb_backlight', tuya.valueConverterBasic.lookup({ON: true, OFF: false})],
    ],
},
onEvent: tuya.onEventSetLocalTime,

};

module.exports = definition;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new device support New device support request
Projects
None yet
Development

No branches or pull requests

4 participants