Skip to content

Instantly share code, notes, and snippets.

@steinuil
Last active January 9, 2024 01:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steinuil/acebcc0d03f7db4507f5c9abf2f9f1dd to your computer and use it in GitHub Desktop.
Save steinuil/acebcc0d03f7db4507f5c9abf2f9f1dd to your computer and use it in GitHub Desktop.
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 extend = require('zigbee-herdsman-converters/lib/extend');
// const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
// const utils = require('zigbee-herdsman-converters/lib/utils');
// const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;
const localTemperatureCalibrationConverter = {
from: (v) => Math.round(v / 10),
to: (v) => {
const value = Math.round(v * 10);
if (value < 0) return 0xFFFFFFFF + value + 1;
return value;
},
};
// Unhandled non-datapoint messages:
// manuSpecificTuya.commandMcuSyncTime
// manuSpecificTuya.commandMcuVersionResponse
const definition = {
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_mhswlizg']),
whiteLabel: [
{ model: 'HY01BW', vendor: 'Hysen' },
{ model: 'LL0211Z', vendor: 'LEDLUX' },
],
model: 'LL0211Z',
vendor: 'LEDLUX',
description: 'Wall-mount thermostat',
fromZigbee: [
tuya.fz.datapoints,
],
toZigbee: [
tuya.tz.datapoints,
],
// Says you need to use this if you're getting no converter for commandMcuSyncTime,
// but I'm still getting it.
onEvent: tuya.onEventSetTime,
configure: tuya.configureMagicPacket,
exposes: [
e.climate()
.withLocalTemperature(ea.STATE_GET)
.withSetpoint('current_heating_setpoint', 5, 35, 0.5, ea.STATE_SET)
.withLocalTemperatureCalibration(-9, 9, 1, ea.STATE_SET)
.withRunningState(['idle', 'heat'])
.withRunningMode(['off', 'heat'], ea.STATE_SET),
e.max_temperature()
.withValueMin(20)
.withValueMax(70),
e.min_temperature()
.withValueMin(1)
.withValueMax(20),
e.min_temperature_limit()
.withValueMin(1)
.withValueMax(10),
e.binary('min_temperature_limit_status', ea.STATE_SET, 'ON', 'OFF')
.withDescription('Enables/disables the minimum temperature limit'),
e.binary('max_temperature_limit_status', ea.STATE_SET, 'ON', 'OFF')
.withDescription('Enables/disables the maximum temperature limit'),
e.child_lock(),
e.enum('programming_operation_mode', ea.ALL, ['manual', 'schedule', 'away', 'temporary_manual'])
.withDescription('Controls how programing affects the thermostat. Possible values: setpoint (only use specified setpoint), schedule (follow programmed setpoint schedule), away (only use specified away setpoint), temporary_manual (use specified setpoint until the local temperature reaches the setpoint, then switch back to schedule mode). Changing this value does not clear programmed schedules.'),
e.away_preset_days(),
e.away_preset_temperature(),
e.week(),
tuya.exposes.powerOutageMemory(),
],
meta: {
// Look at src/devices/tuya.ts:2947 for property names about holidays
// Almost the same as src/devices/tuya.ts:4254
tuyaDatapoints: [
[102, 'running_state', tuya.valueConverterBasic.lookup({'idle': false, 'heat': true})],
[103, 'external_temperature', tuya.valueConverter.divideBy10], // always reports 0 when sensor_type is internal
[104, 'away_preset_days', tuya.valueConverter.raw],
[105, 'away_preset_temperature', tuya.valueConverter.raw],
[106, 'max_temperature_protection', tuya.valueConverter.onOff],
[107, 'min_temperature_protection', tuya.valueConverter.onOff],
// 108: unknown
[109, 'local_temperature_calibration', localTemperatureCalibrationConverter],
[110, 'hysteresis', tuya.valueConverter.divideBy10],
[111, 'hysteresis_for_protection', tuya.valueConverter.divideBy10],
[112, 'max_temperature_limit', tuya.valueConverter.raw],
[113, 'min_temperature_limit', tuya.valueConverter.raw],
[114, 'max_temperature', tuya.valueConverter.raw],
[115, 'min_temperature', tuya.valueConverter.raw],
[116, 'sensor_type', tuya.valueConverterBasic.lookup({'internal': 0, 'external': 1, 'both':2})],
[117, 'power_outage_memory', tuya.valueConverterBasic.lookup({'restore': 0, 'off': 1, 'on': 2})],
[118, 'week', tuya.valueConverterBasic.lookup({'5+2': 0, '6+1': 1, '7': 2})],
// 119, 120, 121, 122: sent when min/max/limit temperature change. supposedly workday/holiday schedule.
// 123-124: unknown
[125, 'running_mode', tuya.valueConverterBasic.lookup({'off': false, 'heat': true})], // should be system_mode off/heat?
[126, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
[127, 'local_temperature', tuya.valueConverter.divideBy10],
[128, 'programming_operation_mode', tuya.valueConverterBasic.lookup({'manual': 0, 'schedule': 1, 'away': 2, 'temporary_manual': 3})],
[129, 'child_lock', tuya.valueConverter.lockUnlock],
[130, 'alarm', tuya.valueConverter.raw],
],
},
};
module.exports = definition;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment