UNPKG

zigbee-herdsman-converters

Version:

Collection of device converters to be used with zigbee-herdsman

1,243 lines 63.4 kB
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.definitions = void 0;
const exposes = __importStar(require("../lib/exposes"));
const tuya = __importStar(require("../lib/tuya"));
const utils = __importStar(require("../lib/utils"));
const e = exposes.presets;
const ea = exposes.access;
exports.definitions = [
    {
        fingerprint: tuya.fingerprint("TS0601", ["_TZE200_oahqgdig", "_TZE200_zaabefnt"]),
        model: "ECB62-ZB",
        vendor: "ENGO",
        description: "Control box for underfloor heating system",
        extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
        exposes: [
            e.enum("pump_delay_time", ea.STATE_SET, ["OFF", "3_min", "5_min", "15_min"]).withDescription("Pump shutdown delay"),
            e.binary("zone_1", ea.STATE, "ON", "OFF").withDescription("Zigbee zone 1 heat demand"),
            e.binary("zone_2", ea.STATE, "ON", "OFF").withDescription("Zigbee zone 2 heat demand"),
            e.binary("zone_3", ea.STATE, "ON", "OFF").withDescription("Zigbee zone 3 heat demand"),
            e.binary("zone_4", ea.STATE, "ON", "OFF").withDescription("Zigbee zone 4 heat demand"),
            e.binary("zone_5", ea.STATE, "ON", "OFF").withDescription("Zigbee zone 5 heat demand"),
            e.binary("zone_6", ea.STATE, "ON", "OFF").withDescription("Zigbee zone 6 heat demand"),
            e.binary("zone_a", ea.STATE, "ON", "OFF").withDescription("Wired zone A heat demand"),
            e.binary("zone_b", ea.STATE, "ON", "OFF").withDescription("Wired zone B heat demand"),
            e.binary("boiler_state", ea.STATE, "ON", "OFF").withDescription("Boiler output"),
            e.binary("pump_state", ea.STATE, "ON", "OFF").withDescription("Pump output"),
            e.binary("zone_1_linked", ea.STATE, "ON", "OFF").withDescription("Zone 1 thermostat connection status"),
            e.binary("zone_2_linked", ea.STATE, "ON", "OFF").withDescription("Zone 2 thermostat connection status"),
            e.binary("zone_3_linked", ea.STATE, "ON", "OFF").withDescription("Zone 3 thermostat connection status"),
            e.binary("zone_4_linked", ea.STATE, "ON", "OFF").withDescription("Zone 4 thermostat connection status"),
            e.binary("zone_5_linked", ea.STATE, "ON", "OFF").withDescription("Zone 5 thermostat connection status"),
            e.binary("zone_6_linked", ea.STATE, "ON", "OFF").withDescription("Zone 6 thermostat connection status"),
            e.text("zone_a_name", ea.STATE_SET).withDescription("Custom name for wired zone A"),
            e.text("zone_b_name", ea.STATE_SET).withDescription("Custom name for wired zone B"),
            e.text("zone_1_name", ea.STATE_SET).withDescription("Custom name for zigbee zone 1"),
            e.text("zone_2_name", ea.STATE_SET).withDescription("Custom name for zigbee zone 2"),
            e.text("zone_3_name", ea.STATE_SET).withDescription("Custom name for zigbee zone 3"),
            e.text("zone_4_name", ea.STATE_SET).withDescription("Custom name for zigbee zone 4"),
            e.text("zone_5_name", ea.STATE_SET).withDescription("Custom name for zigbee zone 5"),
            e.text("zone_6_name", ea.STATE_SET).withDescription("Custom name for zigbee zone 6"),
            e.voltage(),
        ],
        meta: {
            tuyaDatapoints: [
                [1, "zone_1", tuya.valueConverter.onOff],
                [2, "zone_2", tuya.valueConverter.onOff],
                [3, "zone_3", tuya.valueConverter.onOff],
                [4, "zone_4", tuya.valueConverter.onOff],
                [5, "zone_5", tuya.valueConverter.onOff],
                [6, "zone_6", tuya.valueConverter.onOff],
                [101, "pump_state", tuya.valueConverter.onOff],
                [102, "boiler_state", tuya.valueConverter.onOff],
                [103, "zone_a", tuya.valueConverter.onOff],
                [104, "zone_b", tuya.valueConverter.onOff],
                [105, "zone_1_linked", tuya.valueConverter.onOff],
                [106, "zone_2_linked", tuya.valueConverter.onOff],
                [107, "zone_3_linked", tuya.valueConverter.onOff],
                [108, "zone_4_linked", tuya.valueConverter.onOff],
                [109, "zone_5_linked", tuya.valueConverter.onOff],
                [110, "zone_6_linked", tuya.valueConverter.onOff],
                [111, "zone_a_name", tuya.valueConverter.raw],
                [112, "zone_b_name", tuya.valueConverter.raw],
                [113, "zone_1_name", tuya.valueConverter.raw],
                [114, "zone_2_name", tuya.valueConverter.raw],
                [115, "zone_3_name", tuya.valueConverter.raw],
                [116, "zone_4_name", tuya.valueConverter.raw],
                [117, "zone_5_name", tuya.valueConverter.raw],
                [118, "zone_6_name", tuya.valueConverter.raw],
                [
                    119,
                    "pump_delay_time",
                    tuya.valueConverterBasic.lookup({
                        OFF: tuya.enum(0),
                        "3_min": tuya.enum(1),
                        "5_min": tuya.enum(2),
                        "15_min": tuya.enum(3),
                    }),
                ],
                [120, "voltage", tuya.valueConverter.divideBy10],
            ],
        },
    },
    {
        fingerprint: tuya.fingerprint("TS0601", ["_TZE204_djurk6p5"]),
        model: "EONE",
        vendor: "ENGO",
        description: "Smart thermostat",
        extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true, timeStart: "1970" })],
        options: [
            e.binary("expose_device_state", ea.SET, true, false).withDescription("Expose device power state as a separate property when enabled."),
        ],
        exposes: (device, options) => {
            const exposesList = [
                e
                    .climate()
                    .withSetpoint("current_heating_setpoint", 5, 45, 0.5, ea.STATE_SET)
                    .withLocalTemperature(ea.STATE)
                    .withLocalTemperatureCalibration(-3.5, 3.5, 0.5, ea.STATE_SET)
                    .withSystemMode(["off", "heat", "cool"], ea.STATE_SET)
                    .withRunningState(["idle", "heat", "cool"], ea.STATE)
                    .withPreset(["manual", "schedule", "holiday", "temporary", "occupancy_off", "frost"]),
                e.max_temperature().withValueMin(5).withValueMax(45),
                e.min_temperature().withValueMin(5).withValueMax(45),
                e.humidity(),
                e.battery(),
                e.child_lock(),
                e.enum("sensor_choose", ea.STATE_SET, ["internal", "floor", "external", "occupancy"]).withDescription("Temperature input source"),
                e.numeric("brightness", ea.STATE_SET).withUnit("%").withValueMin(10).withValueMax(100).withValueStep(10),
                e
                    .enum("control_algorithm", ea.STATE_SET, [
                    "TPI_UFH",
                    "TPI_RAD",
                    "TPI_ELE",
                    "HIS_02",
                    "HIS_04",
                    "HIS_06",
                    "HIS_08",
                    "HIS_10",
                    "HIS_20",
                    "HIS_30",
                    "HIS_40",
                ])
                    .withDescription("Control algorithm used to regulate temperature"),
                e
                    .numeric("frost_set", ea.STATE_SET)
                    .withUnit("°C")
                    .withValueMin(5)
                    .withValueMax(17)
                    .withValueStep(0.5)
                    .withDescription("Frost protection setpoint"),
                e
                    .numeric("holiday_temp_set", ea.STATE_SET)
                    .withUnit("°C")
                    .withValueMin(5)
                    .withValueMax(45)
                    .withValueStep(0.5)
                    .withDescription("Target temperature during holiday mode"),
                e
                    .numeric("holiday_days_set", ea.STATE_SET)
                    .withUnit("day")
                    .withValueMin(1)
                    .withValueMax(30)
                    .withValueStep(1)
                    .withDescription("Number of days for holiday"),
                e
                    .binary("valve_protection", ea.STATE_SET, "ON", "OFF")
                    .withLabel("Valve Protection")
                    .withDescription("Prevents valve blockage during long periods of inactivity."),
                e
                    .enum("warm_floor", ea.STATE_SET, ["OFF", "7_min", "11_min", "15_min", "19_min", "23_min"])
                    .withDescription("Automatically warms the floor every 60 minutes."),
                e.enum("sensor_error", ea.STATE, ["Normal", "E1", "E2"]).withDescription("Sensor error indicator."),
                ...tuya.exposes.scheduleAllDays(ea.STATE_SET, "HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C HH:MM/C"),
            ];
            if (options?.expose_device_state === true) {
                exposesList.unshift(e.binary("state", ea.STATE_SET, "ON", "OFF").withDescription("Turn the thermostat ON or OFF"));
            }
            return exposesList;
        },
        meta: {
            tuyaDatapoints: [
                [
                    1,
                    "state",
                    {
                        to: async (value, meta) => {
                            if (meta.options?.expose_device_state === true) {
                                await tuya.sendDataPointBool(meta.device.endpoints[0], 1, utils.getFromLookup(value, { on: true, off: false }), "dataRequest", 1);
                            }
                        },
                        from: (value, meta, options) => {
                            const isOn = value === true;
                            meta.state.system_mode = isOn ? (meta.state.system_mode_device ?? "heat") : "off";
                            if (options?.expose_device_state === true) {
                                return isOn ? "ON" : "OFF";
                            }
                            return undefined;
                        },
                    },
                ],
                [
                    2,
                    "system_mode",
                    {
                        to: async (value, meta) => {
                            const entity = meta.device.endpoints[0];
                            await tuya.sendDataPointBool(entity, 1, value !== "off", "dataRequest", 1);
                            switch (value) {
                                case "heat":
                                    await tuya.sendDataPointEnum(entity, 2, 0, "dataRequest", 1);
                                    break;
                                case "cool":
                                    await tuya.sendDataPointEnum(entity, 2, 1, "dataRequest", 1);
                                    break;
                            }
                        },
                        from: (value, meta) => {
                            const modes = ["heat", "cool"];
                            const mode = modes[value];
                            meta.state.system_mode_device = mode;
                            const fallbackMode = "heat";
                            return mode ?? fallbackMode;
                        },
                    },
                ],
                [
                    3,
                    "running_state",
                    tuya.valueConverterBasic.lookup({
                        heat: tuya.enum(1),
                        cool: tuya.enum(3),
                    }, "idle"),
                ],
                [16, "current_heating_setpoint", tuya.valueConverter.divideBy10],
                [19, "max_temperature", tuya.valueConverter.divideBy10],
                [24, "local_temperature", tuya.valueConverter.divideBy10],
                [26, "min_temperature", tuya.valueConverter.divideBy10],
                [27, "local_temperature_calibration", tuya.valueConverter.raw],
                [32, "holiday_temp_set", tuya.valueConverter.divideBy10],
                [33, "holiday_days_set", tuya.valueConverter.raw],
                [34, "humidity", tuya.valueConverter.raw],
                [35, "battery", tuya.valueConverter.raw],
                [40, "child_lock", tuya.valueConverter.lockUnlock],
                [
                    43,
                    "sensor_choose",
                    tuya.valueConverterBasic.lookup({
                        internal: tuya.enum(0),
                        floor: tuya.enum(1),
                        external: tuya.enum(2),
                        occupancy: tuya.enum(3),
                    }),
                ],
                [44, "brightness", tuya.valueConverter.raw],
                [
                    58,
                    "preset",
                    tuya.valueConverterBasic.lookup({
                        manual: tuya.enum(0),
                        schedule: tuya.enum(1),
                        holiday: tuya.enum(2),
                        temporary: tuya.enum(3),
                        occupancy_off: tuya.enum(4),
                        frost: tuya.enum(5),
                    }, "manual"),
                ],
                [
                    101,
                    "control_algorithm",
                    tuya.valueConverterBasic.lookup({
                        TPI_UFH: tuya.enum(0),
                        TPI_RAD: tuya.enum(1),
                        TPI_ELE: tuya.enum(2),
                        HIS_02: tuya.enum(3),
                        HIS_04: tuya.enum(4),
                        HIS_06: tuya.enum(5),
                        HIS_08: tuya.enum(6),
                        HIS_10: tuya.enum(7),
                        HIS_20: tuya.enum(8),
                        HIS_30: tuya.enum(9),
                        HIS_40: tuya.enum(10),
                    }),
                ],
                [106, "frost_set", tuya.valueConverter.divideBy10],
                [107, "valve_protection", tuya.valueConverter.onOff],
                [109, "schedule_monday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                [110, "schedule_tuesday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                [111, "schedule_wednesday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                [112, "schedule_thursday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                [113, "schedule_friday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                [114, "schedule_saturday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                [115, "schedule_sunday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                [
                    118,
                    "warm_floor",
                    tuya.valueConverterBasic.lookup({
                        OFF: tuya.enum(0),
                        "7_min": tuya.enum(1),
                        "11_min": tuya.enum(2),
                        "15_min": tuya.enum(3),
                        "19_min": tuya.enum(4),
                        "23_min": tuya.enum(5),
                    }),
                ],
                [
                    120,
                    "sensor_error",
                    tuya.valueConverterBasic.lookup({
                        Normal: tuya.enum(0),
                        E1: tuya.enum(1),
                        E2: tuya.enum(2),
                    }),
                ],
            ],
        },
    },
    {
        fingerprint: tuya.fingerprint("TS0601", ["_TZE204_cmyc8g5i"]),
        model: "E25-230",
        vendor: "ENGO",
        description: "Smart thermostat",
        extend: [tuya.modernExtend.tuyaBase({ dp: true })],
        exposes: [
            e.binary("state", ea.STATE_SET, "ON", "OFF").withDescription("Turn the thermostat ON/OFF"),
            e
                .climate()
                .withSystemMode(["heat", "cool"], ea.STATE_SET)
                .withSetpoint("current_heating_setpoint", 5, 35, 0.5, ea.STATE_SET)
                .withLocalTemperature(ea.STATE)
                .withLocalTemperatureCalibration(-3.5, 3.5, 0.5, ea.STATE_SET)
                .withRunningState(["idle", "heat", "cool"], ea.STATE)
                .withPreset(["Manual", "Frost"]),
            e
                .enum("control_algorithm", ea.STATE_SET, [
                "TPI_UFH",
                "TPI_RAD",
                "TPI_ELE",
                "HIS_04",
                "HIS_08",
                "HIS_12",
                "HIS_16",
                "HIS_20",
                "HIS_30",
                "HIS_40",
            ])
                .withDescription("Sets the control algorithim of the thermostat"),
            e.max_temperature().withValueMin(5).withValueMax(45),
            e.min_temperature().withValueMin(5).withValueMax(45),
            e.child_lock(),
            e
                .binary("valve_protection", ea.STATE_SET, "ON", "OFF")
                .withLabel("Valve Protection")
                .withDescription("Prevents valve blockage during long periods of inactivity."),
            e.enum("relay_mode", ea.STATE_SET, ["NO", "NC", "OFF"]).withDescription("Sets the internal relay function"),
            e
                .numeric("backlight", ea.STATE_SET)
                .withDescription("Set the backlight brightness of the thermostat.")
                .withUnit("%")
                .withValueMin(0)
                .withValueMax(100)
                .withValueStep(10),
            e
                .numeric("frost_set", ea.STATE_SET)
                .withDescription("Set the frost protection temperature.")
                .withUnit("°C")
                .withValueMin(5)
                .withValueMax(17)
                .withValueStep(0.5),
        ],
        meta: {
            tuyaDatapoints: [
                [1, "state", tuya.valueConverter.onOff],
                [2, "system_mode", tuya.valueConverterBasic.lookup({ heat: tuya.enum(0), cool: tuya.enum(1) })],
                [
                    3,
                    "running_state",
                    tuya.valueConverterBasic.lookup({ heat: tuya.enum(2), cool: tuya.enum(3), idle: tuya.enum(4), idle_c: tuya.enum(5) }),
                ],
                [16, "current_heating_setpoint", tuya.valueConverter.divideBy10],
                [19, "max_temperature", tuya.valueConverter.divideBy10],
                [24, "local_temperature", tuya.valueConverter.divideBy10],
                [26, "min_temperature", tuya.valueConverter.divideBy10],
                [27, "local_temperature_calibration", tuya.valueConverter.divideBy10],
                [40, "child_lock", tuya.valueConverter.lockUnlock],
                [44, "backlight", tuya.valueConverter.raw],
                [
                    58,
                    "preset",
                    tuya.valueConverterBasic.lookup({
                        Manual: tuya.enum(0),
                        Frost: tuya.enum(3),
                    }),
                ],
                [
                    101,
                    "control_algorithm",
                    tuya.valueConverterBasic.lookup({
                        TPI_UFH: tuya.enum(0),
                        TPI_RAD: tuya.enum(1),
                        TPI_ELE: tuya.enum(2),
                        HIS_04: tuya.enum(3),
                        HIS_08: tuya.enum(4),
                        HIS_12: tuya.enum(5),
                        HIS_16: tuya.enum(6),
                        HIS_20: tuya.enum(8),
                        HIS_30: tuya.enum(9),
                        HIS_40: tuya.enum(10),
                    }),
                ],
                [106, "frost_set", tuya.valueConverter.divideBy10],
                [107, "valve_protection", tuya.valueConverter.onOff],
                [
                    108,
                    "relay_mode",
                    tuya.valueConverterBasic.lookup({
                        NO: tuya.enum(0),
                        NC: tuya.enum(1),
                        OFF: tuya.enum(2),
                    }),
                ],
            ],
        },
    },
    {
        fingerprint: tuya.fingerprint("TS0601", ["_TZE204_lnxdk2ch", "_TZE204_glk6viwg"]),
        model: "E40",
        vendor: "ENGO",
        description: "Zigbee smart thermostat",
        options: [
            e
                .binary("expose_device_state", ea.SET, true, false)
                .withDescription("Expose device power state as a separate property when enabled. Restart z2m after changing this setting."),
        ],
        extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true, timeStart: "1970" })],
        exposes: (device, options) => {
            const exposesList = [
                e
                    .climate()
                    .withSystemMode(["off", "heat", "cool"], ea.STATE_SET)
                    .withSetpoint("current_heating_setpoint", 5, 45, 0.5, ea.STATE_SET)
                    .withLocalTemperature(ea.STATE)
                    .withLocalTemperatureCalibration(-3.5, 3.5, 0.5, ea.STATE_SET)
                    .withRunningState(["idle", "heat", "cool"], ea.STATE)
                    .withPreset(["manual", "schedule", "frost"]),
                e
                    .numeric("backlight", ea.STATE_SET)
                    .withUnit("%")
                    .withDescription("Backlight brightness")
                    .withValueMin(0)
                    .withValueMax(100)
                    .withValueStep(10),
                e.enum("sensor_error", ea.STATE, ["Normal", "E1", "E2"]),
                e.child_lock(),
                e
                    .binary("temperature_set_enabled_while_blocked", ea.STATE_SET, "ON", "OFF")
                    .withLabel("Enable temperature control during child lock")
                    .withDescription("Option to control temperature buttons while child lock is enabled. (Available only in newer version of regulator software)."),
                e.enum("relay_mode", ea.STATE_SET, ["NO", "NC", "OFF"]),
                e.enum("sensor_choose", ea.STATE_SET, ["internal", "all", "external"]),
                e.enum("control_algorithm", ea.STATE_SET, [
                    "TPI_UFH",
                    "TPI_RAD",
                    "TPI_ELE",
                    "HIS_02",
                    "HIS_04",
                    "HIS_06",
                    "HIS_08",
                    "HIS_10",
                    "HIS_20",
                    "HIS_30",
                    "HIS_40",
                ]),
                e.numeric("frost_set", ea.STATE_SET).withUnit("°C").withValueMin(5).withValueMax(17).withValueStep(0.5),
                e
                    .enum("valve_protection", ea.STATE_SET, ["off", "on", "anti_stop"])
                    .withLabel("Valve Protection")
                    .withDescription("Prevents valve blockage during long periods of inactivity."),
                e
                    .enum("comfort_warm_floor", ea.STATE_SET, ["OFF", "LEVEL1", "LEVEL2", "LEVEL3", "LEVEL4", "LEVEL5"])
                    .withDescription("Automatically warms the floor every 60 minutes for 7, 11, 15, 19 or 23 minutes according to the level number."),
                e.max_temperature().withValueMin(5).withValueMax(45),
                e.min_temperature().withValueMin(5).withValueMax(45),
                e.text("schedule_monday", ea.STATE_SET),
                e.text("schedule_tuesday", ea.STATE_SET),
                e.text("schedule_wednesday", ea.STATE_SET),
                e.text("schedule_thursday", ea.STATE_SET),
                e.text("schedule_friday", ea.STATE_SET),
                e.text("schedule_saturday", ea.STATE_SET),
                e.text("schedule_sunday", ea.STATE_SET),
                e
                    .numeric("delta_t_rcwc_alg", ea.STATE_SET)
                    .withLabel("Delta RCWC Algorithm")
                    .withDescription("Defines how fast the TRV will react on temperature change. Defaults to 2.0")
                    .withUnit("°C")
                    .withValueMin(0.5)
                    .withValueStep(0.5)
                    .withValueMax(5),
                e
                    .enum("device_pair_state", ea.STATE, ["none", "commutation_center", "trv"])
                    .withLabel("Device Pair State")
                    .withDescription("Defines paired devices type: None, Commutation Center or TRV"),
                e.battery().withDescription("Battery percentage of the paired TRV (can take up to 24 hours after pairing/restarting to appear)"),
                e.numeric("trv_latest_firmware", ea.STATE).withLabel("TRV Latest Firmware").withDescription("Shows TRV latest firmware version"),
                e
                    .numeric("trv_firmware", ea.STATE)
                    .withLabel("TRV Current Firmware")
                    .withDescription("Shows TRV current firmware version for paired TRV"),
            ];
            if (options?.expose_device_state === true) {
                exposesList.unshift(e.binary("state", ea.STATE_SET, "ON", "OFF").withDescription("Turn the thermostat ON or OFF"));
            }
            return exposesList;
        },
        meta: {
            tuyaDatapoints: [
                [
                    1,
                    "state",
                    {
                        to: async (value, meta) => {
                            if (meta.options?.expose_device_state === true) {
                                await tuya.sendDataPointBool(meta.device.endpoints[0], 1, utils.getFromLookup(value, { on: true, off: false }), "dataRequest", 1);
                            }
                        },
                        from: (value, meta, options) => {
                            const isOn = value === true;
                            meta.state.system_mode = isOn ? (meta.state.system_mode_device ?? "heat") : "off";
                            if (options?.expose_device_state === true) {
                                return isOn ? "ON" : "OFF";
                            }
                            return undefined;
                        },
                    },
                ],
                [
                    2,
                    "system_mode",
                    {
                        to: async (value, meta) => {
                            const entity = meta.device.endpoints[0];
                            await tuya.sendDataPointBool(entity, 1, value !== "off", "dataRequest", 1);
                            switch (value) {
                                case "heat":
                                    await tuya.sendDataPointEnum(entity, 2, 0, "dataRequest", 1);
                                    break;
                                case "cool":
                                    await tuya.sendDataPointEnum(entity, 2, 1, "dataRequest", 1);
                                    break;
                            }
                        },
                        from: (value, meta) => {
                            const modes = ["heat", "cool"];
                            const mode = modes[value];
                            meta.state.system_mode_device = mode;
                            const fallbackMode = "heat";
                            return mode ?? fallbackMode;
                        },
                    },
                ],
                [
                    3,
                    "running_state",
                    tuya.valueConverterBasic.lookup({
                        heat: tuya.enum(2),
                        cool: tuya.enum(3),
                        idle: tuya.enum(4),
                        idle_0: tuya.enum(0),
                    }),
                ],
                [16, "current_heating_setpoint", tuya.valueConverter.divideBy10],
                [19, "max_temperature", tuya.valueConverter.divideBy10],
                [24, "local_temperature", tuya.valueConverter.divideBy10],
                [26, "min_temperature", tuya.valueConverter.divideBy10],
                [
                    27,
                    "local_temperature_calibration",
                    {
                        from: (v) => {
                            let value = v;
                            if (value > 0x7fffffff)
                                value -= 4294967296;
                            return value / 10;
                        },
                        to: (v) => {
                            let val = Math.round(v * 10);
                            if (val < 0)
                                val += 4294967296;
                            return val;
                        },
                    },
                ],
                [35, "battery", tuya.valueConverter.raw],
                [40, "child_lock", tuya.valueConverter.lockUnlock],
                [43, "sensor_choose", tuya.valueConverterBasic.lookup({ internal: tuya.enum(0), all: tuya.enum(1), external: tuya.enum(2) })],
                [44, "backlight", tuya.valueConverter.raw],
                [
                    45,
                    "comfort_warm_floor",
                    tuya.valueConverterBasic.lookup({
                        OFF: tuya.enum(0),
                        LEVEL1: tuya.enum(1),
                        LEVEL2: tuya.enum(2),
                        LEVEL3: tuya.enum(3),
                        LEVEL4: tuya.enum(4),
                        LEVEL5: tuya.enum(5),
                    }),
                ],
                [58, "preset", tuya.valueConverterBasic.lookup({ manual: tuya.enum(0), schedule: tuya.enum(1), frost: tuya.enum(3) })],
                [
                    101,
                    "control_algorithm",
                    tuya.valueConverterBasic.lookup({
                        TPI_UFH: tuya.enum(0),
                        TPI_RAD: tuya.enum(1),
                        TPI_ELE: tuya.enum(2),
                        HIS_02: tuya.enum(3),
                        HIS_04: tuya.enum(4),
                        HIS_06: tuya.enum(5),
                        HIS_08: tuya.enum(6),
                        HIS_10: tuya.enum(7),
                        HIS_20: tuya.enum(8),
                        HIS_30: tuya.enum(9),
                        HIS_40: tuya.enum(10),
                    }),
                ],
                [102, "delta_t_rcwc_alg", tuya.valueConverter.divideBy10],
                [
                    103,
                    "device_pair_state",
                    tuya.valueConverterBasic.lookup({
                        none: tuya.enum(0),
                        commutation_center: tuya.enum(1),
                        trv: tuya.enum(2),
                    }),
                ],
                [105, "temperature_set_enabled_while_blocked", tuya.valueConverter.onOff],
                [106, "frost_set", tuya.valueConverter.divideBy10],
                [
                    107,
                    "valve_protection",
                    tuya.valueConverterBasic.lookup({
                        off: tuya.enum(0),
                        on: tuya.enum(1),
                        anti_stop: tuya.enum(2),
                    }),
                ],
                [108, "relay_mode", tuya.valueConverterBasic.lookup({ NO: tuya.enum(0), NC: tuya.enum(1), OFF: tuya.enum(2) })],
                [109, "schedule_monday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(1)],
                [110, "schedule_tuesday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(2)],
                [111, "schedule_wednesday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(3)],
                [112, "schedule_thursday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(4)],
                [113, "schedule_friday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(5)],
                [114, "schedule_saturday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(6)],
                [115, "schedule_sunday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(7)],
                [120, "sensor_error", tuya.valueConverterBasic.lookup({ normal: tuya.enum(0), E1: tuya.enum(1), E2: tuya.enum(2) })],
                [136, "trv_latest_firmware", tuya.valueConverter.divideBy10],
                [137, "trv_firmware", tuya.valueConverter.raw],
            ],
        },
    },
    {
        fingerprint: tuya.fingerprint("TS0601", ["_TZE204_ca3i8m8p", "_TZE200_awnadkan"]),
        model: "EONE-230W",
        vendor: "ENGO",
        description: "Zigbee smart thermostat",
        extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000", queryOnConfigure: true })],
        exposes: [
            e.binary("state", ea.STATE_SET, "ON", "OFF").withDescription("Turn the thermostat ON/OFF"),
            e
                .climate()
                .withSystemMode(["heat", "cool"], ea.STATE_SET)
                .withSetpoint("current_heating_setpoint", 5, 45, 0.5, ea.STATE_SET)
                .withLocalTemperature(ea.STATE)
                .withLocalTemperatureCalibration(-3.5, 3.5, 0.5, ea.STATE_SET)
                .withRunningState(["idle", "heat", "cool"], ea.STATE)
                .withPreset(["manual", "schedule", "holiday", "frost"]),
            e.numeric("local_temperature", ea.STATE).withUnit("°C").withDescription("Measured room temperature"),
            e.numeric("floor_temperature", ea.STATE).withUnit("°C").withDescription("Measured floor temperature"),
            e.numeric("humidity", ea.STATE).withUnit("%").withDescription("Measured humidity"),
            e.numeric("backlight", ea.STATE_SET).withUnit("%").withDescription("Backlight brightness").withValueMin(0).withValueMax(100),
            e.enum("sensor_error", ea.STATE, ["normal", "E1", "E2"]).withDescription("Sensor error status"),
            e.child_lock(),
            e.enum("relay_mode", ea.STATE_SET, ["NO", "NC", "OFF"]).withDescription("Relay mode"),
            e
                .enum("sensor_choose", ea.STATE_SET, ["internal", "floor_temp", "external", "external_on_off"])
                .withDescription("Sensor selection S1/S2"),
            e
                .numeric("holiday_temperature", ea.STATE_SET)
                .withUnit("°C")
                .withDescription("Holiday temperature")
                .withValueMin(5)
                .withValueMax(45)
                .withValueStep(0.5),
            e
                .numeric("holiday_days", ea.STATE_SET)
                .withUnit("days")
                .withDescription("Number of holiday days")
                .withValueMin(1)
                .withValueMax(30)
                .withValueStep(1),
            e
                .numeric("frost_set", ea.STATE_SET)
                .withUnit("°C")
                .withDescription("Frost protection temperature")
                .withValueMin(5)
                .withValueMax(17)
                .withValueStep(0.5),
            e
                .numeric("max_floor_temp_heating", ea.STATE_SET)
                .withUnit("°C")
                .withDescription("Maximum floor temperature while heating (requires sensor mode floor_temp)")
                .withValueMin(5)
                .withValueMax(45)
                .withValueStep(0.5),
            e
                .numeric("min_floor_temp_heating", ea.STATE_SET)
                .withUnit("°C")
                .withDescription("Minimum floor temperature while heating (requires sensor mode floor_temp)")
                .withValueMin(5)
                .withValueMax(45)
                .withValueStep(0.5),
            e
                .numeric("max_floor_temp_cooling", ea.STATE_SET)
                .withUnit("°C")
                .withDescription("Maximum floor temperature while cooling (requires sensor mode floor_temp)")
                .withValueMin(5)
                .withValueMax(45)
                .withValueStep(0.5),
            e
                .numeric("min_floor_temp_coolnig", ea.STATE_SET)
                .withUnit("°C")
                .withDescription("Minimum floor temperature while cooling (requires sensor mode floor_temp)")
                .withValueMin(5)
                .withValueMax(45)
                .withValueStep(0.5),
            e
                .enum("control_algorithm", ea.STATE_SET, [
                "TPI_UFH",
                "TPI_RAD",
                "TPI_ELE",
                "HIS_02",
                "HIS_04",
                "HIS_06",
                "HIS_08",
                "HIS_10",
                "HIS_20",
                "HIS_30",
                "HIS_40",
            ])
                .withDescription("Control algorithm"),
            e
                .enum("valve_protection", ea.STATE_SET, ["off", "on", "anti_stop"])
                .withLabel("Valve Protection")
                .withDescription("Prevents valve blockage during long periods of inactivity"),
            e
                .enum("comfort_warm_floor", ea.STATE_SET, ["OFF", "LEVEL1", "LEVEL2", "LEVEL3", "LEVEL4", "LEVEL5"])
                .withDescription("Comfort warm floor setting"),
            e.enum("temp_resolution", ea.STATE_SET, ["one", "five"]).withDescription("Temperature resolution"),
            e.max_temperature().withValueMin(5).withValueMax(45).withDescription("Max temperature"),
            e.min_temperature().withValueMin(5).withValueMax(45).withDescription("Min temperature"),
            e.text("schedule_monday", ea.STATE_SET).withDescription("Schedule Monday"),
            e.text("schedule_tuesday", ea.STATE_SET).withDescription("Schedule Tuesday"),
            e.text("schedule_wednesday", ea.STATE_SET).withDescription("Schedule Wednesday"),
            e.text("schedule_thursday", ea.STATE_SET).withDescription("Schedule Thursday"),
            e.text("schedule_friday", ea.STATE_SET).withDescription("Schedule Friday"),
            e.text("schedule_saturday", ea.STATE_SET).withDescription("Schedule Saturday"),
            e.text("schedule_sunday", ea.STATE_SET).withDescription("Schedule Sunday"),
        ],
        meta: {
            tuyaDatapoints: [
                [1, "state", tuya.valueConverter.onOff],
                [2, "system_mode", tuya.valueConverterBasic.lookup({ heat: tuya.enum(0), cool: tuya.enum(1) })],
                [3, "running_state", tuya.valueConverterBasic.lookup({ heat: tuya.enum(1), idle: tuya.enum(2) })],
                [16, "current_heating_setpoint", tuya.valueConverter.divideBy10],
                [19, "max_temperature", tuya.valueConverter.divideBy10],
                [24, "local_temperature", tuya.valueConverter.divideBy10],
                [26, "min_temperature", tuya.valueConverter.divideBy10],
                [27, "local_temperature_calibration", tuya.valueConverter.divideBy10],
                [32, "holiday_temperature", tuya.valueConverter.divideBy10],
                [33, "holiday_days", tuya.valueConverter.raw],
                [34, "humidity", tuya.valueConverter.raw],
                [40, "child_lock", tuya.valueConverter.lockUnlock],
                [
                    43,
                    "sensor_choose",
                    tuya.valueConverterBasic.lookup({
                        internal: tuya.enum(0),
                        floor_temp: tuya.enum(1),
                        external: tuya.enum(2),
                        external_on_off: tuya.enum(3),
                    }),
                ],
                [44, "backlight", tuya.valueConverter.raw],
                [
                    58,
                    "preset",
                    tuya.valueConverterBasic.lookup({
                        manual: tuya.enum(0),
                        schedule: tuya.enum(1),
                        holiday: tuya.enum(2),
                        frost: tuya.enum(5),
                    }),
                ],
                [
                    101,
                    "control_algorithm",
                    tuya.valueConverterBasic.lookup({
                        TPI_UFH: tuya.enum(0),
                        TPI_RAD: tuya.enum(1),
                        TPI_ELE: tuya.enum(2),
                        HIS_02: tuya.enum(3),
                        HIS_04: tuya.enum(4),
                        HIS_06: tuya.enum(5),
                        HIS_08: tuya.enum(6),
                        HIS_10: tuya.enum(7),
                        HIS_20: tuya.enum(8),
                        HIS_30: tuya.enum(9),
                        HIS_40: tuya.enum(10),
                    }),
                ],
                [102, "max_floor_temp_heating", tuya.valueConverter.divideBy10],
                [103, "min_floor_temp_heating", tuya.valueConverter.divideBy10],
                [104, "max_floor_temp_cooling", tuya.valueConverter.divideBy10],
                [105, "min_floor_temp_cooling", tuya.valueConverter.divideBy10],
                [106, "frost_set", tuya.valueConverter.divideBy10],
                [108, "relay_mode", tuya.valueConverterBasic.lookup({ NO: tuya.enum(0), NC: tuya.enum(1), OFF: tuya.enum(2) })],
                [109, "schedule_monday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(1)],
                [110, "schedule_tuesday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(2)],
                [111, "schedule_wednesday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(3)],
                [112, "schedule_thursday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(4)],
                [113, "schedule_friday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(5)],
                [114, "schedule_saturday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(6)],
                [115, "schedule_sunday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(7)],
                [116, "floor_temperature", tuya.valueConverter.divideBy10],
                [117, "temp_resolution", tuya.valueConverterBasic.lookup({ one: tuya.enum(0), five: tuya.enum(1) })],
                [
                    118,
                    "comfort_warm_floor",
                    tuya.valueConverterBasic.lookup({
                        OFF: tuya.enum(0),
                        LEVEL1: tuya.enum(1),
                        LEVEL2: tuya.enum(2),
                        LEVEL3: tuya.enum(3),
                        LEVEL4: tuya.enum(4),
                        LEVEL5: tuya.enum(5),
                    }),
                ],
                [120, "sensor_error", tuya.valueConverterBasic.lookup({ normal: tuya.enum(0), E1: tuya.enum(1), E2: tuya.enum(2) })],
                [
                    122,
                    "valve_protection",
                    tuya.valueConverterBasic.lookup({
                        off: tuya.enum(0),
                        on: tuya.enum(1),
                        anti_stop: tuya.enum(2),
                    }),
                ],
            ],
        },
    },
    {
        fingerprint: tuya.fingerprint("TS0601", ["_TZE204_cg8hdnjv"]),
        model: "E25-BATB",
        vendor: "ENGO",
        description: "Zigbee Smart Thermostat Wireless",
        extend: [tuya.modernExtend.tuyaBase({ dp: true })],
        exposes: [
            e.binary("state", ea.STATE_SET, "ON", "OFF").withDescription("Turn the thermostat  ON/OFF"),
            e
                .climate()
                .withSetpoint("current_heating_setpoint", 5, 35, 0.5, ea.STATE_SET)
                .withLocalTemperature(ea.STATE)
                .withLocalTemperatureCalibration(-3.0, 3.0, 0.5, ea.STATE_SET)
                .withSystemMode(["heat", "cool"], ea.STATE_SET)
                .withRunningState(["idle", "heat", "cool"], ea.STATE)
                .withPreset(["manual", "schedule", "frost protection"]),
            e.max_temperature().withValueMin(5).withValueMax(45),
            e.min_temperature().withValueMin(5).withValueMax(45),
            e.battery(),
            e.child_lock(),
            e
                .numeric("backlight_brightness", ea.STATE_SET)
                .withUnit("%")
                .withLabel("Backlight Brightness")
                .withValueMin(10)
                .withValueStep(10)
                .withValueMax(100),
            e
                .enum("control_type", ea.STATE_SET, [
                "TPI_UFH",
                "TPI_RAD",
                "TPI_ELE",
                "HIS_02",
                "HIS_04",
                "HIS_08",
                "HIS_12",
                "HIS_16",
                "HIS_20",
                "HIS_30",
                "HIS_40",
            ])
                .withLabel("Control Type")
                .withDescription("Type of device controlled: Any for heating machines, histeresis only for cooling (non-invertor ACs)"),
            e
                .numeric("delta_t_rcwc_alg", ea.STATE_SET)
                .withLabel("Delta RCWC Algorithm")
                .withDescription("Defines how fast the TRV will react on temperature change. Defaults to 2.0")
                .withUnit("°C")
                .withValueMin(0.5)
                .withValueStep(0.5)
                .withValueMax(5),
            e
                .enum("device_pair_state", ea.STATE, ["none", "commutation_center", "trv"])
                .withLabel("Device Pair State")
                .withDescription("Defines paired devices type: None, Commutation Center or TRV"),
            e
                .numeric("frost_set", ea.STATE_SET)
                .withLabel("Frost Mode Temperature")
                .withDescription("Defines temperature for frost mode. Defaults to 7.0")
                .withUnit("°C")
                .withValueMin(5)
                .withValueStep(0.5)
                .withValueMax(17),
            e
                .binary("valve_protection", ea.STATE_SET, "ON", "OFF")
                .withLabel("Valve Protection")
                .withDescription("Prevents valve blockage during long periods of inactivity"),
            ...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
                .numeric("trv_work_state", ea.STATE)
                .withLabel("TRV Current State")
                .withDescription("Shows TRV current state for each TRV. Opened or closed"),
            e
                .binary("trv_frost_protection", ea.STATE_SET, "ON", "OFF")
                .withLabel("TRV Frost Protection")
                .withDescription("Enables frost protection for TRVs"),
            e.numeric("trv_latest_firmware", ea.STATE).withLabel("TRV Latest Firmware").withDescription("Shows TRV latest firmware option"),
            e.numeric("trv_firmware", ea.STATE).withLabel("TRV Current Firmware").withDescription("Shows TRV current firmware for each TRV"),
        ],
        meta: {
            tuyaDatapoints: [
                [1, "state", tuya.valueConverter.onOff],
                [
                    2,
                    "system_mode",
                    tuya.valueConverterBasic.lookup({
                        heat: tuya.enum(0),
                        cool: tuya.enum(1),
                    }),
                ],
                [
                    3,
                    "running_state",
                    tuya.valueConverterBasic.lookup({
                        heat: tuya.enum(2),
                        cool: tuya.enum(3),
                    }, "idle"),
                ],
                [16, "current_heating_setpoint", tuya.valueConverter.divideBy10],
                [19, "max_temperature", tuya.valueConverter.divideBy10],
                [24, "local_temperature", tuya.valueConverter.divideBy10],
                [26, "min_temperature", tuya.valueConverter.divideBy10],
                [27, "local_temperature_calibration", tuya.valueConverter.divideBy10],
                [35, "battery", tuya.valueConverter.raw],
                [40, "child_lock", tuya.valueConverter.lockUnlock],
                [44, "backlight_brightness", tuya.valueConverter.raw],
                [
                    58,
                    "preset",
                    tuya.valueConverterBasic.lookup({
                        manual: tuya.enum(0),
                        schedule: tuya.enum(1),
                        "frost protection": tuya.enum(3),
                    }),
                ],
                [
                    101,
                    "control_type",
                    tuya.valueConverterBasic.lookup({
                        TPI_UFH: tuya.enum(0),
                        TPI_RAD: tuya.enum(1),
                        TPI_ELE: tuya.enum(2),
                        HIS_02: tuya.enum(3),
                        HIS_04: tuya.enum(4),
                        HIS_08: tuya.enum(5),
                        HIS_12: tuya.enum(6),
                        HIS_16: tuya.enum(7),
                        HIS_20: tuya.enum(8),
                        HIS_30: tuya.enum(9),
                        HIS_40: tuya.enum(10),
                    }),
                ],
                [102, "delta_t_rcwc_alg", tuya.valueConverter.divideBy10],
                [
                    103,
                    "device_pair_state",
                    tuya.valueConverterBasic.lookup({
                        none: tuya.enum(0),
                        commutation_center: tuya.enum(1),
                        trv: tuya.enum(2),
                    }),
                ],
                [106, "frost_set", tuya.valueConverter.divideBy10],
                [107, "valve_protection", tuya.valueConverter.onOff],
                [109, "schedule_monday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                [110, "schedule_tuesday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                [111, "schedule_wednesday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                [112, "schedule_thursday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                [113, "schedule_friday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                [114, "schedule_saturday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                [115, "schedule_sunday", tuya.valueConverter.thermostatScheduleDayMultiDPWithTransitionCount(6)],
                // not implemented
                // [119, "pin_to_unlock", tuya.valueConverter.raw],
                // [120, "sensor_status", tuya.valueConverter.raw],
                // [121, "pin_to_settings", tuya.valueConverter.raw],
                // [122, "trv_state", tuya.valueConverter.raw],
                [123, "trv_work_state", tuya.valueConverter.raw],
                [128, "trv_frost_protection", tuya.valueConverter.raw],
                // not implemented
                // [129, "trv_calibration", tuya.valueConverter.raw],
                // [135, "trv_ota_trigger", tuya.valueConverter.raw],
                [136, "trv_latest_firmware", tuya.valueConverter.divideBy10],
                [137, "trv_firmware", tuya.valueConverter.raw],
            ],
        },
    },
    {
        fingerprint: tuya.fingerprint("TS0601", ["_TZE200_gtouvmvl"]),
        model: "EONE-BATB",
        vendor: "ENGO",
        description: "Zigbee smart thermostat",
        extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000", queryOnConfigure: true })],
        exposes: [
            e.binary("state", ea.STATE_SET, "ON", "OFF").withDescription("Turn the thermostat ON/OFF"),
            e
                .climate()
                .withSystemMode(["heat", "cool"], ea.STATE_SET)
                .withSetpoint("current_heating_setpoint", 5, 45, 0.5, ea.STATE_SET)
                .withLocalTemperature(ea.STATE)
                .withLocalTemperatureCalibration(-3.5, 3.5, 0.5, ea.STATE_SET)
                .withRunningState(["idle", "heat", "cool"], ea.STATE)
                .withPreset(["manual", "schedule", "holiday", "frost"]),
            e.numeric("local_temperature", ea.STATE).withUnit("°C").withDescription("Measured room temperature"),
            e.numeric("floor_temperature", ea.STATE).withUnit("°C").withDescription("Measured floor temperature"),
            e.numeric("humidity", ea.STATE).withUnit("%").withDescription("Measured humidity"),
            e.numeric("backlight", ea.STATE_SET).withUnit("%").withDescription("Backlight brightness").withValueMin(0).withValueMax(100),
            e.enum("sensor_error", ea.STATE, ["normal", "E1", "E2"]).withDescription("Sensor error status"),
            e.child_lock(),
            e.battery(),
            e
                .enum("sensor_choose", ea.STATE_SET, ["internal", "floor_temp", "external", "external_on_off"])
                .withDescription("Sensor selection S1/S2"),
            e
                .numeric("holiday_temperature", ea.STATE_SET)
                .withUnit("°C")
                .withDescription("Holiday temperature")
                .withValueMin(5)
                .withValueMax(45)
                .withValueStep(0.5),
            e
                .numeric("holiday_days", ea.STATE_SET)
                .withUnit("days")
                .withDescription("Number of holiday days")
                .withValueMin(1)
                .withValueMax(30)
                .withValueStep(1),
            e
                .numeric("frost_set", ea.STATE_SET)
                .withUnit("°C")
                .withDescription("Frost protection temperature")
                .withValueMin(5)
                .withValueMax(17)
                .withValueStep(0.5),
            e
                .numeric("max_floor_temp_heating", ea.STATE_SET)
                .withUnit("°C")
                .withDescription("Maximum floor temperature while heating (requires sensor mode floor_temp)")
                .withValueMin(5)
                .withValueMax(45)
                .withValueStep(0.5),
            e
                .numeric("min_floor_temp_heating", ea.STATE_SET)
                .withUnit("°C")
                .withDescription("Minimum floor temperature while heating (requires sensor mode floor_temp)")
                .withValueMin(5)
                .withValueMax(45)
                .withValueStep(0.5),
            e
                .numeric("max_floor_temp_cooling", ea.STATE_SET)
                .withUnit("°C")
                .withDescription("Maximum floor temperature while cooling (requires sensor mode floor_temp)")
                .withValueMin(5)
                .withValueMax(45)
                .withValueStep(0.5),
            e
                .numeric("min_floor_temp_coolnig", ea.STATE_SET)
                .withUnit("°C")
                .withDescription("Minimum floor temperature while cooling (requires sensor mode floor_temp)")
                .withValueMin(5)
                .withValueMax(45)
                .withValueStep(0.5),
            e
                .enum("control_algorithm", ea.STATE_SET, [
                "TPI_UFH",
                "TPI_RAD",
                "TPI_ELE",
                "HIS_02",
                "HIS_04",
                "HIS_06",
                "HIS_08",
                "HIS_10",
                "HIS_20",
                "HIS_30",
                "HIS_40",
            ])
                .withDescription("Control algorithm"),
            e
                .enum("valve_protection", ea.STATE_SET, ["off", "on", "anti_stop"])
                .withLabel("Valve Protection")
                .withDescription("Prevents valve blockage during long periods of inactivity"),
            e
                .enum("comfort_warm_floor", ea.STATE_SET, ["OFF", "LEVEL1", "LEVEL2", "LEVEL3", "LEVEL4", "LEVEL5"])
                .withDescription("Comfort warm floor setting"),
            e.enum("temp_resolution", ea.STATE_SET, ["one", "five"]).withDescription("Temperature resolution"),
            e.max_temperature().withValueMin(5).withValueMax(45).withDescription("Max temperature"),
            e.min_temperature().withValueMin(5).withValueMax(45).withDescription("Min temperature"),
            e.text("schedule_monday", ea.STATE_SET).withDescription("Schedule Monday"),
            e.text("schedule_tuesday", ea.STATE_SET).withDescription("Schedule Tuesday"),
            e.text("schedule_wednesday", ea.STATE_SET).withDescription("Schedule Wednesday"),
            e.text("schedule_thursday", ea.STATE_SET).withDescription("Schedule Thursday"),
            e.text("schedule_friday", ea.STATE_SET).withDescription("Schedule Friday"),
            e.text("schedule_saturday", ea.STATE_SET).withDescription("Schedule Saturday"),
            e.text("schedule_sunday", ea.STATE_SET).withDescription("Schedule Sunday"),
        ],
        meta: {
            tuyaDatapoints: [
                [1, "state", tuya.valueConverter.onOff],
                [2, "system_mode", tuya.valueConverterBasic.lookup({ heat: tuya.enum(0), cool: tuya.enum(1) })],
                [3, "running_state", tuya.valueConverterBasic.lookup({ heat: tuya.enum(1), idle: tuya.enum(2) })],
                [16, "current_heating_setpoint", tuya.valueConverter.divideBy10],
                [19, "max_temperature", tuya.valueConverter.divideBy10],
                [24, "local_temperature", tuya.valueConverter.divideBy10],
                [26, "min_temperature", tuya.valueConverter.divideBy10],
                [27, "local_temperature_calibration", tuya.valueConverter.divideBy10],
                [32, "holiday_temperature", tuya.valueConverter.divideBy10],
                [33, "holiday_days", tuya.valueConverter.raw],
                [34, "humidity", tuya.valueConverter.raw],
                [35, "battery", tuya.valueConverter.raw],
                [40, "child_lock", tuya.valueConverter.lockUnlock],
                [
                    43,
                    "sensor_choose",
                    tuya.valueConverterBasic.lookup({
                        internal: tuya.enum(0),
                        floor_temp: tuya.enum(1),
                        external: tuya.enum(2),
                        external_on_off: tuya.enum(3),
                    }),
                ],
                [44, "backlight", tuya.valueConverter.raw],
                [
                    58,
                    "preset",
                    tuya.valueConverterBasic.lookup({
                        manual: tuya.enum(0),
                        schedule: tuya.enum(1),
                        holiday: tuya.enum(2),
                        frost: tuya.enum(5),
                    }),
                ],
                [
                    101,
                    "control_algorithm",
                    tuya.valueConverterBasic.lookup({
                        TPI_UFH: tuya.enum(0),
                        TPI_RAD: tuya.enum(1),
                        TPI_ELE: tuya.enum(2),
                        HIS_02: tuya.enum(3),
                        HIS_04: tuya.enum(4),
                        HIS_06: tuya.enum(5),
                        HIS_08: tuya.enum(6),
                        HIS_10: tuya.enum(7),
                        HIS_20: tuya.enum(8),
                        HIS_30: tuya.enum(9),
                        HIS_40: tuya.enum(10),
                    }),
                ],
                [102, "max_floor_temp_heating", tuya.valueConverter.divideBy10],
                [103, "min_floor_temp_heating", tuya.valueConverter.divideBy10],
                [104, "max_floor_temp_cooling", tuya.valueConverter.divideBy10],
                [105, "min_floor_temp_cooling", tuya.valueConverter.divideBy10],
                [106, "frost_set", tuya.valueConverter.divideBy10],
                // [107], "Setpoint change, when device locked" not implemented
                [
                    108,
                    "valve_protection",
                    tuya.valueConverterBasic.lookup({
                        off: tuya.enum(0),
                        on: tuya.enum(1),
                        anti_stop: tuya.enum(2),
                    }),
                ],
                [109, "schedule_monday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(1)],
                [110, "schedule_tuesday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(2)],
                [111, "schedule_wednesday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(3)],
                [112, "schedule_thursday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(4)],
                [113, "schedule_friday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(5)],
                [114, "schedule_saturday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(6)],
                [115, "schedule_sunday", tuya.valueConverter.thermostatScheduleDayMultiDPWithDayNumber(7)],
                [116, "floor_temperature", tuya.valueConverter.divideBy10],
                [117, "temp_resolution", tuya.valueConverterBasic.lookup({ one: tuya.enum(0), five: tuya.enum(1) })],
                [
                    118,
                    "comfort_warm_floor",
                    tuya.valueConverterBasic.lookup({
                        OFF: tuya.enum(0),
                        LEVEL1: tuya.enum(1),
                        LEVEL2: tuya.enum(2),
                        LEVEL3: tuya.enum(3),
                        LEVEL4: tuya.enum(4),
                        LEVEL5: tuya.enum(5),
                    }),
                ],
                [120, "sensor_error", tuya.valueConverterBasic.lookup({ normal: tuya.enum(0), E1: tuya.enum(1), E2: tuya.enum(2) })],
            ],
        },
    },
];
//# sourceMappingURL=engo.js.map