Skip to content

Commit

Permalink
feat(add): Avatto ME168 - CR fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
andreypuhovsky committed Jan 25, 2025
1 parent 152a2e7 commit 9b4969c
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 59 deletions.
75 changes: 39 additions & 36 deletions src/devices/tuya.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5518,13 +5518,12 @@ const definitions: DefinitionWithExtend[] = [
},
},
{
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_ybsqljjg' /* model: 'ME168', vendor: 'AVATTO' */]),
model: 'TS0601_thermostat_5',
vendor: 'Tuya',
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_ybsqljjg']),
model: 'AVATTO_ME168',
vendor: 'AVATTO',
description: 'Thermostatic radiator valve',
fromZigbee: [tuya.fz.datapoints],
toZigbee: [tuya.tz.datapoints],
whiteLabel: [tuya.whitelabel('AVATTO', 'AVATTO_ME168', 'Thermostatic radiator valve', ['_TZE200_ybsqljjg'])],
onEvent: tuya.onEventSetTime,
configure: tuya.configureMagicPacket,
ota: true,
Expand All @@ -5533,9 +5532,8 @@ const definitions: DefinitionWithExtend[] = [
//! to fix as the exposed format is bitmap
e.numeric('error', ea.STATE).withDescription('If NTC is damaged, "Er" will be on the TRV display.'),
e.child_lock().withCategory('config'),

e
.enum('running_mode', ea.STATE, ['auto', 'manual', 'off', 'eco', 'comfort', 'rapid'])
.enum('running_mode', ea.STATE, ['auto', 'manual', 'off', 'eco', 'comfort', 'boost'])
.withDescription('Actual TRV running mode')
.withCategory('diagnostic'),
e
Expand All @@ -5546,13 +5544,11 @@ const definitions: DefinitionWithExtend[] = [
.withSetpoint('current_heating_setpoint', 4, 35, 1, ea.STATE_SET)
.withLocalTemperature(ea.STATE)
.withLocalTemperatureCalibration(-30, 30, 1, ea.STATE_SET),

e
.binary('window_detection', ea.STATE_SET, 'ON', 'OFF')
.withDescription('Enables/disables window detection on the device')
.withCategory('config'),
e.window_open(),

e
.binary('frost_protection', ea.STATE_SET, 'ON', 'OFF')
.withDescription(
Expand All @@ -5569,7 +5565,6 @@ const definitions: DefinitionWithExtend[] = [
'again.',
)
.withCategory('config'),

e
.numeric('boost_time', ea.STATE_SET)
.withUnit('min')
Expand All @@ -5578,45 +5573,65 @@ const definitions: DefinitionWithExtend[] = [
.withValueMax(255)
.withCategory('config'),
e.numeric('boost_timeset_countdown', ea.STATE).withUnit('min').withDescription('Boost time remaining'),

e.eco_temperature().withValueMin(5).withValueMax(35).withValueStep(1).withCategory('config'),
e.comfort_temperature().withValueMin(5).withValueMax(35).withValueStep(1).withCategory('config'),

...tuya.exposes
.scheduleAllDays(ea.STATE_SET, '06:00/21.0 08:00/16.0 12:00/21.0 14:00/16.0 18:00/21.0 22:00/16.0')
.map((text) => text.withCategory('config')),
],
meta: {
tuyaDatapoints: [
// mode (RW Enum [0=auto, 1=manual, 2=off, 3=eco, 4=comfort, 5=rapid])
[2, null, tuya.valueConverter.thermostatME168_systemModeAndPreset(null)],
[2, 'preset', tuya.valueConverter.thermostatME168_systemModeAndPreset('preset')],
[2, 'system_mode', tuya.valueConverter.thermostatME168_systemModeAndPreset('system_mode')],

// mode (RW Enum [0=auto, 1=manual, 2=off, 3=eco, 4=comfort, 5=boost])
[
2,
null,
tuya.valueConverter.thermostatSystemModeAndPresetMap(
{
0: {device_mode: 'auto', system_mode: 'auto', preset: 'none'},
1: {device_mode: 'manual', system_mode: 'heat', preset: 'none'},
2: {device_mode: 'off', system_mode: 'off', preset: 'none'},
3: {device_mode: 'eco', system_mode: 'heat', preset: 'eco'},
4: {device_mode: 'comfort', system_mode: 'heat', preset: 'comfort'},
5: {device_mode: 'boost', system_mode: 'heat', preset: 'boost'},
},
null,
),
],
[
2,
'system_mode',
tuya.valueConverter.thermostatSystemModeAndPresetMap(null, {
auto: new tuya.Enum(0), // auto
heat: new tuya.Enum(1), // manual
off: new tuya.Enum(2), // off
}),
],
[
2,
'preset',
tuya.valueConverter.thermostatSystemModeAndPresetMap(null, {
none: new tuya.Enum(1), // manual
eco: new tuya.Enum(3), // eco
comfort: new tuya.Enum(4), // comfort
boost: new tuya.Enum(5), // boost
}),
],
// work_state (RO Enum [0=opened, 1=closed])
[3, 'running_state', tuya.valueConverterBasic.lookup({heat: tuya.enum(0), idle: tuya.enum(1)})],

// temp_set (RW Integer, 40-350 C, scale 1 step 10)
[4, 'current_heating_setpoint', tuya.valueConverter.divideBy10],

// temp_current (RO Integer, -0-500 C, scale 1 step 10)
[5, 'local_temperature', tuya.valueConverter.divideBy10],

// battery_percentage (RO, Integer, 0-100 %, scale 0 step 1)
[6, 'battery', tuya.valueConverter.raw],

// child_lock (RW Boolean)
[7, 'child_lock', tuya.valueConverter.lockUnlock],

//! load_status (RW, Enum, range [0=closed, 1=opened]) - Non-functional
// [13, 'load_status', tuya.valueConverterBasic.lookup({CLOSE: tuya.enum(0), OPEN: tuya.enum(1)})],

// window_check (RW Boolean)
[14, 'window_detection', tuya.valueConverter.onOff],

// window_state (RO Enum, range [0=opened, 1=closed])
[15, 'window_open', tuya.valueConverter.trueFalseEnum0],

// week_program_13_(1-7) (RW Raw, maxlen 128, special binary-in-base64 format)
[28, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(1, 6)],
[29, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(2, 6)],
Expand All @@ -5625,40 +5640,28 @@ const definitions: DefinitionWithExtend[] = [
[32, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(5, 6)],
[33, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(6, 6)],
[34, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(7, 6)],

//? error (RO Bitmap, maxlen 2, label [0x=low_battery, x0=sensor_fault]?)
[35, null, tuya.valueConverter.errorOrBatteryLow],

// frost (RW Boolean)
[36, 'frost_protection', tuya.valueConverter.onOff],

//! rapid_switch (RW Boolean) - Non-functional
// [37, 'rapid_switch', tuya.valueConverter.onOff],

//! rapid_countdown (RW Integer, 1-12 h, scale 0 step 1) - Non-functional
// [38, 'rapid_countdown', tuya.valueConverter.raw],

// scale_switch (RW Boolean)
[39, 'scale_protection', tuya.valueConverter.onOff],

// temp_correction (RW Integer, -10-10 C, scale 0 step 1)
[47, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration2],

// comfort_temp (RW Integer, 100-250 C, scale 1 step 10)
[101, 'comfort_temperature', tuya.valueConverter.divideBy10],

//! switch (RW Boolean) - Non-functional
// [102, 'switch', tuya.valueConverter.onOff],

// rapid_time_set (RW Integer, 0-180 min, scale 0 step 1)
[103, 'boost_time', tuya.valueConverter.raw],

// heating_countdown (RO Integer, 0-3600 min, scale 0 step 1)
[104, 'boost_timeset_countdown', tuya.valueConverter.countdown],

// eco_temp (RW Integer, 100-200 C, scale 1 step 10)
[105, 'eco_temperature', tuya.valueConverter.divideBy10],

//! eco (RW Boolean) - Non-functional
// [106, 'eco', tuya.valueConverter.onOff],
],
Expand Down
30 changes: 7 additions & 23 deletions src/lib/tuya.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1529,34 +1529,18 @@ export const valueConverter = {
return data;
},
},
thermostatME168_systemModeAndPreset: (toKey: string) => {
/** @param toMap the key is 'system_mode' or 'preset' related value */
thermostatSystemModeAndPresetMap: (
fromMap: {[modeId: number]: {device_mode: string; system_mode: string; preset: string}},
toMap: {[key: string]: Enum},
) => {
return {
from: (v: string) => {
utils.assertNumber(v, 'system_mode');
const modeMap: {[mode: number]: {name: string; system_mode: string; preset: string}} = {
0: {name: 'auto', system_mode: 'auto', preset: 'none'},
1: {name: 'manual', system_mode: 'heat', preset: 'none'},
2: {name: 'off', system_mode: 'off', preset: 'none'},
3: {name: 'eco', system_mode: 'heat', preset: 'eco'},
4: {name: 'comfort', system_mode: 'heat', preset: 'comfort'},
5: {name: 'rapid', system_mode: 'heat', preset: 'boost'},
};
return {running_mode: modeMap[v].name, preset: modeMap[v].preset, system_mode: modeMap[v].system_mode};
return {running_mode: fromMap[v].device_mode, system_mode: fromMap[v].system_mode, preset: fromMap[v].preset};
},
to: (v: string) => {
const presetLookup = {
none: new Enum(1), // manual
eco: new Enum(3), // eco
comfort: new Enum(4), // comfort
boost: new Enum(5), // rapid
};
const systemModeLookup = {
auto: new Enum(0), // auto
heat: new Enum(1), // manual
off: new Enum(2), // off
};
const lookup = toKey === 'preset' ? presetLookup : systemModeLookup;
return utils.getFromLookup(v, lookup);
return utils.getFromLookup(v, toMap);
},
};
},
Expand Down

0 comments on commit 9b4969c

Please sign in to comment.