[New device support]: TS0601 TRV Devices - Unsupported
Link
https://www.aliexpress.com/item/1005005454936849.html?spm=a2g0o.order_list.order_list_main.5.5f321802cPC0l2
Database entry
{"id":88,"type":"EndDevice","ieeeAddr":"0xa4c1389273b1279f","nwkAddr":14059,"manufId":4417,"manufName":"_TZE204_zljqtner","powerSource":"Battery","modelId":"TS0601","epList":[1],"endpoints":{"1":{"profId":260,"epId":1,"devId":81,"inClusterList":[0,4,5,61184],"outClusterList":[25,10],"clusters":{"genBasic":{"attributes":{"65487":14400,"65503":"G�.iH�.iI�.iK�.iN�.iR�.iU�.fV�.\u0012","65506":56,"65508":0,"stackVersion":0,"dateCode":"","appVersion":74}}},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":74,"stackVersion":0,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"meta":{},"lastSeen":1724761166920} {"id":89,"type":"EndDevice","ieeeAddr":"0xa4c138425dcc44d1","nwkAddr":41530,"manufId":4417,"manufName":"_TZE204_zljqtner","powerSource":"Battery","modelId":"TS0601","epList":[1],"endpoints":{"1":{"profId":260,"epId":1,"devId":81,"inClusterList":[0,4,5,61184],"outClusterList":[25,10],"clusters":{"genBasic":{"attributes":{"65487":14400,"65503":"\u0000\u0000\u0000\u0000\u0011\u0000\u0000\u0000\u0000\u0011","65506":56,"65508":1,"modelId":"TS0601","manufacturerName":"_TZE204_zljqtner","powerSource":3,"zclVersion":3,"appVersion":74,"stackVersion":0,"hwVersion":1,"dateCode":""}}},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":74,"stackVersion":0,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"meta":{},"lastSeen":1724761172904}
Comments
I'm a complete newbie, and love the way that 99.9% of the items i have added "Just Work" this is the first time i have come across an item that did... please help :
External definition
const definition = {
zigbeeModel: ['TS0601'],
model: 'TS0601',
vendor: '_TZE204_zljqtner',
description: 'Automatically generated definition',
extend: [],
meta: {},
};
module.exports = definition;
Any update and advise yet how to integrate this device properly ?
I have exact same issue - valve is not recognized
У меня такая же проблема. Решение кто нибудь подскажет?
https://houseiq.pl/pl/p/Glowica-termostatyczna-GTZ06-ZigBee-3.0-TUYA/1620
I bought my thermostatic radiator valve at the end of September. I couldn't add it correctly - no support. is there any chance to add support for this thermostatic head?
const definition = { zigbeeModel: ['TS0601'], model: 'TS0601', vendor: '_TZE204_zljqtner', description: 'Automatically generated definition', extend: [], meta: {}, };
I also failed to add it using custom quirks
module.exports = definition;
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days
I managed to get SOME functionality using z2m-edge and converters file. I can get/set temperature, offset, window, child lock. I get idle/heating state back, not sure if battery works correctly. I have not tested the schedules.
Here is the converters.js content:
const fz = require('zigbee-herdsman-converters/converters/fromZigbee'); const tz = require('zigbee-herdsman-converters/converters/toZigbee'); const reporting = require('zigbee-herdsman-converters/lib/reporting'); const modernExtend = require('zigbee-herdsman-converters/lib/modernExtend'); const exposes = require('zigbee-herdsman-converters/lib/exposes'); const tuya = require('zigbee-herdsman-converters/lib/tuya'); const utils = require('zigbee-herdsman-converters/lib/utils'); const e = exposes.presets; const ea = exposes.access;
const definition = { fingerprint: [ {modelID: 'TS0601', manufacturerName: '_TZE204_zljqtner'}, ], model: 'TS0601_thermostat_1', vendor: 'TuYa', description: 'Thermostatic radiator valve', whiteLabel: [ {vendor: 'Unknown/id3.pl', model: 'GTZ06'}, ], onEvent: tuya.onEventSetLocalTime, fromZigbee: [tuya.fz.datapoints], toZigbee: [tuya.tz.datapoints], configure: tuya.configureMagicPacket, exposes: [ e.battery(), e.child_lock(), e.max_temperature().withValueMin(15).withValueMax(45), e.min_temperature().withValueMin(5).withValueMax(15), e.window_detection(), e.binary('window', ea.STATE, 'CLOSED', 'OPEN').withDescription('Window status closed or open '), e.binary('alarm_switch', ea.STATE, 'ON', 'OFF').withDescription('Thermostat in error state'), e.climate() .withLocalTemperature(ea.STATE) .withSetpoint('current_heating_setpoint', 5, 35, 0.5, ea.STATE_SET) .withLocalTemperatureCalibration(-30, 30, 0.1, ea.STATE_SET) .withPreset(['auto', 'manual', 'off', 'on'], 'MANUAL MODE ☝ - In this mode, the device executes manual temperature setting. ' + 'When the set temperature is lower than the "minimum temperature", the valve is closed (forced closed). ' + 'AUTO MODE ⏱ - In this mode, the device executes a preset week programming temperature time and temperature. ' + 'ON - In this mode, the thermostat stays open ' + 'OFF - In this mode, the thermostat stays closed') .withSystemMode(['auto', 'heat', 'off'], ea.STATE) .withRunningState(['idle', 'heat'], ea.STATE), ...tuya.exposes.scheduleAllDays(ea.STATE_SET, 'HH:MM/C HH:MM/C HH:MM/C HH:MM/C'), ], meta: { tuyaDatapoints: [ [1, null, { from: (v) => { utils.assertNumber(v, 'system_mode'); const presetLookup = {0: 'auto', 1: 'manual', 2: 'off', 3: 'on'}; const systemModeLookup = {0: 'auto', 1: 'auto', 2: 'off', 3: 'heat'}; return {preset: presetLookup[v], system_mode: systemModeLookup[v]}; }, }, ], [1, 'system_mode', tuya.valueConverterBasic.lookup({'auto': tuya.enum(1), 'off': tuya.enum(2), 'heat': tuya.enum(3)})], [1, 'preset', tuya.valueConverterBasic.lookup( {'auto': tuya.enum(0), 'manual': tuya.enum(1), 'off': tuya.enum(2), 'on': tuya.enum(3)})], [2, 'current_heating_setpoint', tuya.valueConverter.divideBy10], [3, 'local_temperature', tuya.valueConverter.divideBy10], [6, 'running_state', tuya.valueConverterBasic.lookup({'heat': 1, 'idle': 0})], [7, 'window', tuya.valueConverterBasic.lookup({'OPEN': 1, 'CLOSE': 0})], [8, 'window_detection', tuya.valueConverter.onOff], [9, 'max_temperature', tuya.valueConverter.divideBy10], [10, 'min_temperature', tuya.valueConverter.divideBy10], [12, 'child_lock', tuya.valueConverter.lockUnlock], [13, 'battery', tuya.valueConverter.raw], //[14, 'alarm_switch', tuya.valueConverter.onOff], [101, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration1], [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)], ], }, };
module.exports = definition;
Hi there, Here are the codes I obtained for the tuyadatapoints. Not sure how to implement that properly in an external converter, if someone could help, that'd be appreciated. best,
{ "1":"Mode", "2":"Target temperature", "3":"Current temperature", "6":"Working status", "7":"Window status", "8":"Open window", "9":"Max. limit temperature", "10":"Min. limit temperature", "12":"Child lock", "13":"Battery", "14":"Fault alarm", "101":"Room sensor calibration", "102":"周程序1", // Weekly program 1 "103":"周程序2", // Weekly program 2 "104":"周程序3", // Weekly program 3 "105":"周程序4", // Weekly program 4 "106":"周程序5", // Weekly program 5 "107":"周程序6", // Weekly program 6 "108":"周程序7", // Weekly program 7 "109":"机型", //model "110":"Motor thrust", "111":"Display brightness", "112":"Software version", "113":"Screen orientation", "114":"Valve", "115":"Switch deviation (energy-saving mode only)", "116":"电机数据", //motor data "117":"假期时长", //Holiday duration "118":"Boost 模式时长", //Boost mode duration "119":"舒适模式温度", //Comfort mode temperature "120":"节能模式温度", //Energy saving mode temperature "121":"防冻模式温度", //Antifreeze mode temperature "122":"防冻使能", //Antifreeze enable "123":"气压指数", //pressure index "124":"临时模式开始时间", //Temporary mode start time "125":"功能点", //Function point "126":"app支持特性", //app support features "127":"System mode" }
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days
Hi there, I have been working on tuning down the external converter for this device, and I'm missing just one thing: Synchronizing Time. That is, if I link the device to SmartLife, the schedule works as expected, then I switch it to zigbee2mqtt stack, it still works, but I observe that it looses 8sec every hour, so the next day, it's completely out of sync.
In z2m logs I see:
[2025-12-14 20:02:34] debug: zh:controller: Received payload: clusterID=61184, address=60516, groupID=0, endpoint=1, destinationEndpoint=1, wasBroadcast=false, linkQuality=78, frame={"header":{"frameControl":{"frameType":1,"manufacturerSpecific":false,"direction":1,"disableDefaultResponse":false,"reservedBits":0},"transactionSequenceNumber":156,"commandIdentifier":36},"payload":{"payloadSize":160},"command":{"ID":36,"parameters":[{"name":"payloadSize","type":33}],"name":"mcuSyncTime"}} [2025-12-14 20:02:34] debug: zh:controller:endpoint: ZCL command 0xa4c1386fbd1a0125/1 manuSpecificTuya.defaultRsp({"cmdId":36,"statusCode":0}, {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":0,"reservedBits":0,"transactionSequenceNumber":156,"writeUndiv":false}) [2025-12-14 20:02:34] debug: zh:zstack: sendZclFrameToEndpointInternal 0xa4c1386fbd1a0125:60516/1 (0,0,1) [2025-12-14 20:02:34] debug: zh:zstack:znp: --> SREQ: AF - dataRequest - {"dstaddr":60516,"destendpoint":1,"srcendpoint":1,"clusterid":61184,"transid":4,"options":0,"radius":30,"len":5,"data":{"type":"Buffer","data":[16,156,11,36,0]}} [2025-12-14 20:02:34] debug: zh:zstack:unpi:writer: --> frame [254,15,36,1,100,236,1,1,0,239,4,0,30,5,16,156,11,36,0,241] [2025-12-14 20:02:34] debug: zh:zstack:unpi:parser: --- parseNext [] [2025-12-14 20:02:34] debug: z2m: Received Zigbee message from 'TRV-SdB', type 'commandMcuSyncTime', cluster 'manuSpecificTuya', data '{"payloadSize":160}' from endpoint 1 with groupID 0 [2025-12-14 20:02:34] debug: z2m: No converter available for 'TRV601' with cluster 'manuSpecificTuya' and type 'commandMcuSyncTime' and data '{"payloadSize":160}'
I do have the following line, but I still see the no converter available [...] "commandMcuSyncTime":
onEvent: tuya.onEventSetTime,
I even tried to make a custom function, but it's as if the onEvent was never fired. I'm unsure if this is a leftover from older versions of z2m, and unsure how to do it now, with the following versions:
The fix in this post seems to work and resync the time properly for this device too. I removed the onEvent attribute. I re-paired, and the schedule was back on track.
Here is the updated external converter:
const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const legacy = require('zigbee-herdsman-converters/lib/legacy');
const logger = require('zigbee-herdsman-converters/lib/logger');
const e = exposes.presets;
const ea = exposes.access;
const allModes = {
0: { preset:"off" , systemMode: "off", deviceMode: "off" , isSystemMode: true },
1: { preset:"comfort" , systemMode: "auto", deviceMode: "comfort" , },
2: { preset:"manual" , systemMode: "auto", deviceMode: "manual" , },
3: { preset:"on" , systemMode: "heat", deviceMode: "on" , isSystemMode: true },
4: { preset:"eco" , systemMode: "auto", deviceMode: "eco" , },
5: { preset:"anti-frost" , systemMode: "off", deviceMode: "anti-frost" , },
6: { preset:"schedule" , systemMode: "auto", deviceMode: "schedule" , isSystemMode: true },
};
const allModesByName = Object.fromEntries(
Object.entries(allModes)
.map(([k, v]) => [
v.preset, { ...v, 'index': k }
])
);
function customThermostatScheduleDay() {
/// Each day is split into slots of 30minutes.
/// Each slot is 4 bits, encoding the mode in which the valve should be put into.
/// e.g. 69 20 ...
/// Means at 00:00 use mode (69 >> 4) = 4 aka "eco"
/// at 00:30 use mode (69 & 15) = 5 aka "anti-frost"
/// at 01:00 use mode (20 >> 4) = 1 aka "comfort"
/// at 01:30 use mode (20 & 15) = 4 aka "eco"
return {
from: (v) => {
const daySchedule = [];
let previousMode = null;
for (let index = 0; index < 48; index++) {
const hour = Math.floor(index / 2);
const minutes = (index % 2) ? 30 : 0;
const hour_values = parseInt(v[hour], 10);
const mode = (index % 2) ? (hour_values & 15) : (hour_values >> 4);
if (allModes[mode] === undefined) {
throw new Error(`Invalid mode half-byte: "${mode}" (${hour_values} index ${index})`);
}
const modeString = allModes[mode].preset;
if (mode != previousMode)
{
const schedule = String(hour).padStart(2, '0') +
':' +
String(minutes).padStart(2, '0') +
'/' +
modeString;
daySchedule.push(schedule);
previousMode = mode;
}
}
return Array.from(new Set(daySchedule)).join(' ');
},
to: (v) => {
const parseTransition = (transition) => {
const parts = transition.split('/');
if (parts.length !== 2) {
throw new Error(`Invalid schedule: wrong transition format "${transition}"`);
}
const [timePart, setting] = parts;
const timeParts = timePart.split(':');
if (timeParts.length !== 2) {
throw new Error(`Invalid time format in: "${transition}"`);
}
const hour = parseInt(timeParts[0], 10);
const min = parseInt(timeParts[1], 10);
if (hour < 0 || hour > 23 || (min != 0 && min != 30)) {
throw new Error(`Invalid hour or minute in: "${transition}"`);
}
return { minutesSinceMidnight: hour * 60 + min, setting };
};
const inputTransitions = v.split(/\s+/).filter(Boolean);
if (inputTransitions.length < 1 || inputTransitions.length > 48) {
throw new Error(`Invalid schedule: there should be between 1 and 48 transitions, got "${inputTransitions.length}"`);
}
const transitions = [];
const seenTimes = new Set();
for (const inputTransition of inputTransitions) {
const transition = parseTransition(inputTransition);
if (!seenTimes.has(transition.minutesSinceMidnight)) {
seenTimes.add(transition.minutesSinceMidnight);
transitions.push(transition);
}
}
if (transitions.length === 0) {
throw new Error('No valid transitions found.');
}
transitions.sort((a, b) => a.minutesSinceMidnight - b.minutesSinceMidnight);
const payload = [];
function encodeNextMode(minutesSinceMidnight, setting) {
// Device only supports these 3 modes in schedule mode
if (setting != "eco" && setting != "comfort") {
setting = "anti-frost";
}
const mode = allModesByName[setting.toLowerCase()];
if (!mode) {
throw new Error(`Invalid mode: "${setting}"`);
}
if ((minutesSinceMidnight % 60) == 0) {
payload.push(mode.index << 4);
} else {
payload[payload.length - 1] |= (mode.index & 15);
}
}
let previousTime = 0;
let previousMode = null;
for (const { minutesSinceMidnight, setting } of transitions) {
if (previousMode == null) {
previousMode = setting;
}
for (let time = previousTime + 30; time < minutesSinceMidnight; time += 30) {
encodeNextMode(time, previousMode);
}
encodeNextMode(minutesSinceMidnight, setting);
previousTime = minutesSinceMidnight;
previousMode = setting;
}
if (previousMode != null) {
for (let time = previousTime + 30; time < 24*60; time += 30) {
encodeNextMode(time, previousMode);
}
}
return payload;
}
}
}
const tuya_set_time_request = {
cluster: 'manuSpecificTuya',
type: ['commandMcuSyncTime'],
convert: async (model, msg, publish, options, meta) => {
const OneJanuary2000 = new Date('January 01, 2000 00:00:00 UTC+00:00').getTime();
const currentTime = new Date().getTime();
const utcTime = Math.round((currentTime - OneJanuary2000) / 1000);
const localTime = Math.round(currentTime / 1000) - (new Date()).getTimezoneOffset() * 60;
const endpoint = msg.endpoint;
const payload = {
payloadSize: 8,
payload: [
...tuya.convertDecimalValueTo4ByteHexArray(utcTime),
...tuya.convertDecimalValueTo4ByteHexArray(localTime),
],
};
await endpoint.command('manuSpecificTuya', 'mcuSyncTime', payload, {});
},
};
const definition = {
fingerprint: tuya.fingerprint("TS0601", ["_TZE204_zljqtner"]),
model: "TRV601Z",
vendor: "TuYa", // White label
description: "Thermostatic radiator valve",
fromZigbee: [tuya.fz.datapoints, tuya_set_time_request],
toZigbee: [tuya.tz.datapoints],
configure: tuya.configureMagicPacket,
exposes: [
e
.battery()
.withCategory('diagnostic'),
e
.binary("window", ea.STATE, "CLOSED", "OPEN")
.withCategory('diagnostic')
.withDescription("Window status: closed or open."),
e
.enum("valve", ea.STATE, ["CLOSED", "OPEN"])
.withCategory('diagnostic')
.withDescription("Valve status: closed or open."),
e
.numeric("holiday_duration", ea.STATE_SET)
.withUnit("day")
.withValueMin(0)
.withValueMax(60)
.withValueStep(1)
.withDescription("Duration of the holiday mode before going back to previous mode. If the value is other than 0, then holiday mode is active."),
e
.numeric("boost_duration", ea.STATE_SET)
.withUnit("min")
.withValueMin(0)
.withValueMax(120)
.withValueStep(1)
.withDescription("Duration of the boost mode before going back to previous mode. If the value is other than 0, then boost mode is active."),
e
.climate()
.withLocalTemperature(ea.STATE)
.withSetpoint("current_heating_setpoint", 5, 35, 0.5, ea.STATE_SET)
.withLocalTemperatureCalibration(-10, 10, 0.1, ea.STATE_SET)
.withPreset(Object.values(allModes).map(e => e.preset),
"// Comfort -- the device setpoint is set to comfort temperature. " +
"// Eco -- the device setpoint is set to eco temperature. " +
"// Manual -- the device setpoint can be adjusted manually. " +
"When the set temperature is lower than the \"temperature set point\", the valve is closed (forced closed). " +
"// ON -- In this mode, the thermostat stays open. " +
"// OFF -- In this mode, the thermostat stays closed. " +
"// Anti-frost -- device setpoint is set to anti-frost temperature. " +
"// Schedule -- device setpoint is changed according to the scheduled parameters."
)
.withSystemMode(["auto", "heat", "off"], ea.STATE_SET)
.withRunningState(["idle", "heat"], ea.STATE),
e
.child_lock(),
e
.comfort_temperature()
.withCategory('config')
.withDescription("Comfort mode temperature")
.withValueMin(18)
.withValueMax(35)
.withValueStep(0.5),
e
.eco_temperature()
.withCategory('config')
.withDescription("Eco mode temperature")
.withValueMin(5)
.withValueMax(20)
.withValueStep(0.5),
...tuya.exposes.scheduleAllDays(ea.STATE_SET, "00:00/eco 00:30/comfort 01:00/anti-frost ...")
.map(e => e.withCategory('config')),
e
.binary("frost_protection", ea.STATE_SET, "ON", "OFF")
.withCategory('config')
.withDescription(
"When the room temperature is lower than 5 °C (or the choosen one), the valve opens; when the temperature rises to 8 °C, the valve closes",
),
e
.numeric("frost_protection_temperature", ea.STATE_SET)
.withUnit("°C")
.withCategory('config')
.withValueMin(5)
.withValueMax(18)
.withValueStep(0.5)
.withDescription(""),
e
.numeric("switch_deviation", ea.STATE_SET)
.withUnit("°C")
.withCategory('config')
.withValueMin("0.5")
.withValueMax("5")
.withValueStep("0.1")
.withDescription(
"Hysteresis - comfort > switches off/on exactly at reached temperature with valve smooth from 0 to 100%, eco > 0.5 degrees above or below, valve either 0 or 100%",
),
e
.max_temperature()
.withCategory('config')
.withValueMin(20)
.withValueMax(35)
.withValueStep(1),
e
.min_temperature()
.withCategory('config')
.withValueMin(5)
.withValueMax(15)
.withValueStep(1),
e
.enum("brightness", ea.STATE_SET, ["low", "medium", "high"])
.withCategory('config')
.withDescription("Screen Brightness"),
e
.enum("screen_orientation", ea.STATE_SET, ["up", "down"])
.withCategory('config')
.withDescription("Screen orientation"),
e
.enum("motor_thrust", ea.STATE_SET, ["strong", "middle", "weak"])
.withCategory('config'),
e
.binary("alarm_switch", ea.STATE, "ON", "OFF")
.withCategory('diagnostic')
.withDescription("Thermostat in error state"),
e
.binary('window_detection', ea.STATE_SET, 'ON', 'OFF')
.withDescription('Enables/disables window detection on the device')
.withCategory('config'),
],
meta: {
tuyaDatapoints: [
[
1,
null,
tuya.valueConverter.thermostatSystemModeAndPresetMap({
fromMap: allModes,
}),
],
[
1,
"system_mode",
tuya.valueConverter.thermostatSystemModeAndPresetMap({
toMap: Object.fromEntries(
Object.entries(allModes).filter(e => e[1].isSystemMode)
.map(([k, v]) => [
v.systemMode, new tuya.Enum(k)
])
),
}),
],
[
1,
"preset",
tuya.valueConverter.thermostatSystemModeAndPresetMap({
toMap: Object.fromEntries(
Object.entries(allModes)
.map(([k, v]) => [
v.preset, tuya.enum(parseInt(k))
])
),
}),
],
[2, "current_heating_setpoint", tuya.valueConverter.divideBy10],
[3, "local_temperature", tuya.valueConverter.divideBy10],
[6, "running_state", tuya.valueConverterBasic.lookup({heat: 1, idle: 0})],
[7, "window", tuya.valueConverterBasic.lookup({OPEN: 1, CLOSE: 0})],
[8, "window_detection", tuya.valueConverter.onOff],
[9, "max_temperature", tuya.valueConverter.divideBy10],
[10, "min_temperature", tuya.valueConverter.divideBy10],
[12, "child_lock", tuya.valueConverter.lockUnlock],
[13, "battery", tuya.valueConverter.raw],
[14, "alarm_switch", tuya.valueConverter.onOff],
[101, "local_temperature_calibration", tuya.valueConverter.localTempCalibration1],
[102, "schedule_sunday", customThermostatScheduleDay()],
[103, "schedule_monday", customThermostatScheduleDay()],
[104, "schedule_tuesday", customThermostatScheduleDay()],
[105, "schedule_wednesday", customThermostatScheduleDay()],
[106, "schedule_thursday", customThermostatScheduleDay()],
[107, "schedule_friday", customThermostatScheduleDay()],
[108, "schedule_saturday", customThermostatScheduleDay()],
[
110,
"motor_thrust",
tuya.valueConverterBasic.lookup({
strong: tuya.enum(0),
middle: tuya.enum(1),
weak: tuya.enum(2),
}),
],
[
111,
"brightness",
tuya.valueConverterBasic.lookup({
low: tuya.enum(2),
medium: tuya.enum(1),
high: tuya.enum(0),
}),
],
[
113,
"screen_orientation",
tuya.valueConverterBasic.lookup({
up: tuya.enum(0),
down: tuya.enum(1),
}),
],
[114, "valve", tuya.valueConverterBasic.lookup({ OPEN: 1000, CLOSED: 0 })],
[115, "switch_deviation", tuya.valueConverter.divideBy10],
[117, "holiday_duration", tuya.valueConverter.raw],
[118, "boost_duration", tuya.valueConverter.raw],
[119, "comfort_temperature", tuya.valueConverter.divideBy10],
[120, "eco_temperature", tuya.valueConverter.divideBy10],
[121, "frost_protection_temperature", tuya.valueConverter.divideBy10],
[122, "frost_protection", tuya.valueConverter.onOff],
// Unused
[109, "mode", tuya.valueConverter.text],
[112, "version", tuya.valueConverter.text],
[116, "motor_data", tuya.valueConverter.raw],
[123, "pressure_index", tuya.valueConverter.raw],
[124, "temporary_mode_starttime", tuya.valueConverter.raw],
[125, "function_point", tuya.valueConverter.raw],
[126, "app_features", tuya.valueConverter.raw],
[127, "system_mode2", tuya.valueConverter.raw],
],
},
};
module.exports = definition;
For future references, here is how it looks in Z2M:
And here is how it looks in Home Assistant:
Hi @levak, thanks for your updated converter. I'll take a look on that. 🙏🏼