"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 fz = __importStar(require("../converters/fromZigbee"));
const tz = __importStar(require("../converters/toZigbee"));
const exposes = __importStar(require("../lib/exposes"));
const legacy = __importStar(require("../lib/legacy"));
const m = __importStar(require("../lib/modernExtend"));
const reporting = __importStar(require("../lib/reporting"));
const globalStore = __importStar(require("../lib/store"));
const tuya = __importStar(require("../lib/tuya"));
const utils = __importStar(require("../lib/utils"));
const e = exposes.presets;
const ea = exposes.access;
const fzLocal = {
    // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
    FB20002_on: {
        cluster: "genOnOff",
        type: "commandTuyaAction",
        convert: (model, msg, publish, options, meta) => {
            return { action: "on" };
        },
    },
    // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
    HG06668_doorbell_button: {
        cluster: "ssIasZone",
        type: "commandStatusChangeNotification",
        convert: (model, msg, publish, options, meta) => {
            if (utils.hasAlreadyProcessedMessage(msg, model))
                return;
            const lookup = { 1: "pressed" };
            const zoneStatus = msg.data.zonestatus;
            return {
                action: lookup[zoneStatus & 1],
                tamper: (zoneStatus & (1 << 2)) > 0,
                battery_low: (zoneStatus & (1 << 3)) > 0,
            };
        },
    },
};
const valueConverterLocal = {
    wateringState: {
        from: (value, meta, options, publish) => {
            const result = {
                state: value ? "ON" : "OFF",
                ...(value
                    ? {}
                    : {
                        // ensure time_left is set to zero when it's OFF
                        time_left: 0,
                    }),
            };
            // prepare the time reporting for water scheduler
            // indications when the watering was triggered by scheduler:
            // - scheduling is enabled
            // - current state is on
            // - time_left wasn't reported before and is 0
            // - current hour & minute matches scheduling period
            if (meta.state.schedule_mode !== "OFF" &&
                result.state === "ON" &&
                meta.state.time_left === 0 &&
                !globalStore.hasValue(meta.device, "watering_timer_active_time_slot")) {
                const now = new Date();
                const timeslot = [1, 2, 3, 4, 5, 6]
                    .map((slotNumber) => utils.getObjectProperty(meta.state, `schedule_slot_${slotNumber}`, {}))
                    // @ts-expect-error ignore
                    .find((ts) => ts.state === "ON" && ts.start_hour === now.getHours() && ts.start_minute === now.getMinutes() && ts.timer > 0);
                if (timeslot) {
                    // @ts-expect-error ignore
                    const iterationDuration = timeslot.timer + timeslot.pause;
                    // automatic watering detected
                    globalStore.putValue(meta.device, "watering_timer_active_time_slot", {
                        timeslot_start_timestamp: now.getTime(),
                        // end of last watering excluding last pause
                        // @ts-expect-error ignore
                        timeslot_end_timestamp: now.getTime() + (timeslot.iterations * iterationDuration - timeslot.pause) * 60 * 1000,
                        // @ts-expect-error ignore
                        timer: timeslot.timer,
                        iteration_inverval: null, // will be set in the next step
                        iteration_start_timestamp: 0, // will be set in the next step
                    });
                }
            }
            // setup time reporting for water scheduler when necessary
            if (globalStore.hasValue(meta.device, "watering_timer_active_time_slot")) {
                const ts = globalStore.getValue(meta.device, "watering_timer_active_time_slot");
                if (
                // time slot execution is already completed
                Date.now() > ts.timeslot_end_timestamp - 5000 ||
                    // scheduling was interrupted by turning watering on manually
                    // @ts-expect-error ignore
                    (result.state === "ON" && result.state !== meta.state.state && meta.state.time_left > 0)) {
                    // reporting is no longer necessary
                    clearInterval(ts.iteration_inverval);
                    globalStore.clearValue(meta.device, "watering_timer_active_time_slot");
                }
                else if (result.state === "OFF" && result.state !== meta.state.state) {
                    // turned off --> disable reporting for this iteration only
                    clearInterval(ts.iteration_inverval);
                    ts.iteration_inverval = null;
                }
                else if (result.state === "ON" && result.state !== meta.state.state && meta.state.time_left === 0) {
                    // automatic scheduling detected (reported as ON, but without any info about duration)
                    ts.iteration_report = true;
                    ts.iteration_start_timestamp = Date.now();
                    if (ts.timer > 1) {
                        // report every minute
                        ts.iteration_inverval = setInterval(() => {
                            const now = Date.now();
                            const wateringEndTime = ts.iteration_start_timestamp + ts.timer * 60 * 1000;
                            const timeLeftInMinutes = Math.round((wateringEndTime - now) / 1000 / 60);
                            if (timeLeftInMinutes > 0) {
                                if (timeLeftInMinutes === 1) {
                                    clearInterval(ts.iteration_inverval);
                                }
                                publish({
                                    time_left: timeLeftInMinutes,
                                });
                            }
                        }, 60 * 1000).unref();
                    }
                    // initial reporting
                    result.time_left = ts.timer;
                }
            }
            return result;
        },
    },
    wateringScheduleMode: {
        from: (value) => {
            const [scheduleMode, scheduleValue] = value;
            const isWeekday = scheduleMode === 0;
            return {
                schedule_mode: scheduleValue === 0 ? "OFF" : isWeekday ? "WEEKDAY" : "PERIODIC",
                schedule_periodic: !isWeekday ? scheduleValue : 0,
                schedule_weekday: ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"].reduce((scheduleMap, dayName, index) => ({
                    // biome-ignore lint/performance/noAccumulatingSpread: ignored using `--suppress`
                    ...scheduleMap,
                    [dayName]: isWeekday && (scheduleValue & (1 << index)) > 0 ? "ON" : "OFF",
                }), {}),
            };
        },
    },
    wateringSchedulePeriodic: {
        to: (value) => {
            if (!utils.isInRange(0, 7, value))
                throw new Error(`Invalid value: ${value} (expected ${0} to ${7})`);
            // Note: mode value of 0 switches to disabled weekday scheduler
            const scheduleMode = value > 0 ? 1 : 0;
            return [scheduleMode, value];
        },
    },
    wateringScheduleWeekday: {
        to: (value, meta) => {
            // map each day to ON/OFF and use current state as default to allow partial updates
            const dayValues = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]
                // @ts-expect-error ignore
                .map((dayName) => utils.getObjectProperty(value, dayName, utils.getObjectProperty(meta.state.schedule_weekday, dayName, "OFF")));
            const scheduleValue = dayValues.reduce((dayConfig, value, index) => {
                // @ts-expect-error ignore
                return dayConfig | (value === "ON" ? 1 << index : 0);
            }, 0);
            // value of 0 switches to weekday scheduler
            const scheduleMode = 0;
            return [scheduleMode, scheduleValue];
        },
    },
    wateringScheduleSlot: (timeSlotNumber) => ({
        from: (buffer) => {
            return {
                state: buffer.readUInt8(0) === 1 ? "ON" : "OFF",
                start_hour: utils.numberWithinRange(buffer.readUInt8(1), 0, 23), // device reports non-valid value 255 initially
                start_minute: utils.numberWithinRange(buffer.readUInt8(2), 0, 59), // device reports non-valid value 255 initially
                timer: utils.numberWithinRange(buffer.readUInt8(3) * 60 + buffer.readUInt8(4), 1, 599), // device reports non-valid value 0 initially
                pause: utils.numberWithinRange(buffer.readUInt8(6) * 60 + buffer.readUInt8(7), 0, 599),
                iterations: utils.numberWithinRange(buffer.readUInt8(9), 1, 9), // device reports non-valid value 0 initially
            };
        },
        to: (value, meta) => {
            // use default values from current config to allow partial updates
            const timeslot = utils.getObjectProperty(meta.state, `schedule_slot_${timeSlotNumber}`, {});
            const state = utils.getObjectProperty(value, "state", timeslot.state ?? false);
            const startHour = utils.getObjectProperty(value, "start_hour", timeslot.start_hour ?? 23);
            const startMinute = utils.getObjectProperty(value, "start_minute", timeslot.start_minute ?? 59);
            const duratonInMin = utils.getObjectProperty(value, "timer", timeslot.timer ?? 1);
            const iterations = utils.getObjectProperty(value, "iterations", timeslot.iterations ?? 1);
            const pauseInMin = utils.getObjectProperty(value, "pause", timeslot.pause ?? 0);
            if (!utils.isInRange(0, 23, startHour))
                throw new Error(`Invalid start hour value ${startHour} (expected ${0} to ${23})`);
            if (!utils.isInRange(0, 59, startMinute))
                throw new Error(`Invalid start minute value: ${startMinute} (expected ${0} to ${59})`);
            if (!utils.isInRange(1, 599, duratonInMin))
                throw new Error(`Invalid timer value: ${duratonInMin} (expected ${1} to ${599})`);
            if (!utils.isInRange(1, 9, iterations))
                throw new Error(`Invalid iterations value: ${iterations} (expected ${1} to ${9})`);
            if (!utils.isInRange(0, 599, pauseInMin))
                throw new Error(`Invalid pause value: ${pauseInMin} (expected ${0} to ${599})`);
            if (iterations > 1 && pauseInMin === 0)
                throw new Error("Pause value must be at least 1 minute when using multiple iterations");
            return [
                // @ts-expect-error ignore
                state === "ON" ? 1 : 0, // time slot enabled or not
                startHour, // start hour
                startMinute, // start minute
                Math.floor(duratonInMin / 60), // duration for n hours
                duratonInMin % 60, // duration + n minutes
                0, // what's this? -> was always reported as 0
                Math.floor(pauseInMin / 60), // pause in hours
                pauseInMin % 60, // pause + n minutes
                0, // what's this? -> was always reported as 0
                iterations, // iterations
            ];
        },
    }),
};
exports.definitions = [
    {
        fingerprint: [
            { manufacturerName: "_TZ3000_kdi2o9m6" }, // EU
            { modelID: "TS011F", manufacturerName: "_TZ3000_plyvnuf5" }, // CH
            { modelID: "TS011F", manufacturerName: "_TZ3000_wamqdr3f" }, // FR
            { modelID: "TS011F", manufacturerName: "_TZ3000_00mk2xzy" }, // BS
            { modelID: "TS011F", manufacturerName: "_TZ3000_upjrsxh1" }, // DK
            { manufacturerName: "_TZ3000_00mk2xzy" }, // BS
        ],
        model: "HG06337",
        vendor: "Lidl",
        description: "Silvercrest smart plug (EU, CH, FR, BS, DK)",
        extend: [tuya.modernExtend.tuyaBase(), tuya.modernExtend.tuyaOnOff({ indicatorMode: true })],
        configure: async (device, coordinatorEndpoint) => {
            const endpoint = device.getEndpoint(11);
            await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff"]);
            await reporting.onOff(endpoint);
        },
    },
    {
        fingerprint: tuya.fingerprint("TS011F", ["_TZ3000_j1v25l17", "_TZ3000_ynmowqk2", "_TZ3000_3uimvkn6"]),
        model: "HG08673",
        vendor: "Lidl",
        description: "Silvercrest smart plug with power monitoring (EU, FR)",
        ota: true,
        extend: [
            tuya.modernExtend.tuyaBase(),
            tuya.modernExtend.tuyaOnOff({ electricalMeasurements: true, powerOutageMemory: true, indicatorMode: true, childLock: true }),
            tuya.modernExtend.electricityMeasurementPoll({
                electricalMeasurement: false,
                metering: true,
                optionDescription: "Only the energy value is polled for this device.",
            }),
        ],
        configure: async (device, coordinatorEndpoint) => {
            const endpoint = device.getEndpoint(1);
            await tuya.configureMagicPacket(device, coordinatorEndpoint);
            await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff", "haElectricalMeasurement"]);
            await reporting.rmsVoltage(endpoint, { change: 5 });
            await reporting.rmsCurrent(endpoint, { change: 50 });
            await reporting.activePower(endpoint, { change: 10 });
            // Energy reporting (currentSummDelivered) doesn't work; requires polling: https://github.com/Koenkk/zigbee2mqtt/issues/14356
            endpoint.saveClusterAttributeKeyValue("haElectricalMeasurement", { acCurrentDivisor: 1000, acCurrentMultiplier: 1 });
            endpoint.saveClusterAttributeKeyValue("seMetering", { divisor: 100, multiplier: 1 });
            device.save();
        },
        whiteLabel: [tuya.whitelabel("Lidl", "HG08673-BS", "Silvercrest smart plug with power monitoring (BS)", ["_TZ3000_3uimvkn6"])],
    },
    {
        fingerprint: tuya.fingerprint("TS004F", ["_TZ3000_rco1yzb1"]),
        model: "HG08164",
        vendor: "Lidl",
        description: "Silvercrest smart button",
        extend: [tuya.clusters.addTuyaGenOnOffCluster()],
        fromZigbee: [fz.command_on, fz.command_off, fz.command_step, fz.command_stop, fz.battery, tuya.fz.on_off_action],
        toZigbee: [],
        configure: async (device, coordinatorEndpoint) => {
            const endpoint = device.getEndpoint(1);
            await endpoint.read("genBasic", [0x0004, 0x000, 0x0001, 0x0005, 0x0007, 0xfffe]);
            await endpoint.read("genOnOff", ["tuyaOperationMode"]);
            try {
                await endpoint.read(0xe001, [0xd011]);
            }
            catch {
                /* do nothing */
            }
            await endpoint.read("genPowerCfg", ["batteryVoltage", "batteryPercentageRemaining"]);
            await reporting.bind(endpoint, coordinatorEndpoint, ["genPowerCfg"]);
            await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff"]);
            await reporting.batteryPercentageRemaining(endpoint);
        },
        exposes: [e.action(["on", "off", "brightness_stop", "brightness_step_up", "brightness_step_down", "single", "double"]), e.battery()],
    },
    {
        fingerprint: tuya.fingerprint("TS0211", ["_TZ1800_ladpngdx", "_TZ1800_akzvkzqq"]),
        model: "HG06668",
        vendor: "Lidl",
        description: "Silvercrest smart wireless door bell button",
        fromZigbee: [fz.battery, fzLocal.HG06668_doorbell_button],
        toZigbee: [],
        configure: async (device, coordinatorEndpoint) => {
            const endpoint = device.getEndpoint(1);
            await reporting.bind(endpoint, coordinatorEndpoint, ["genPowerCfg"]);
            await reporting.batteryPercentageRemaining(endpoint);
        },
        exposes: [e.battery(), e.action(["pressed"]), e.battery_low(), e.tamper()],
    },
    {
        fingerprint: tuya.fingerprint("TY0202", ["_TZ1800_fcdjzz3s"]),
        model: "HG06335/HG07310",
        vendor: "Lidl",
        description: "Silvercrest smart motion sensor",
        extend: [
            m.iasZoneAlarm({ zoneType: "occupancy", zoneStatusReporting: true, zoneAttributes: ["alarm_1", "tamper", "battery_low"] }),
            m.battery(),
        ],
    },
    {
        fingerprint: tuya.fingerprint("TY0203", ["_TZ1800_ejwkn2h2", "_TZ1800_ho6i0zk9"]),
        model: "HG06336",
        vendor: "Lidl",
        description: "Silvercrest smart window and door sensor",
        extend: [m.iasZoneAlarm({ zoneType: "contact", zoneAttributes: ["alarm_1", "tamper"] }), m.battery()],
    },
    {
        fingerprint: tuya.fingerprint("TS1001", ["_TYZB01_bngwdjsr"]),
        model: "FB20-002",
        vendor: "Lidl",
        description: "Livarno Lux switch and dimming light remote control",
        extend: [tuya.clusters.addTuyaGenOnOffCluster()],
        exposes: [
            e.action(["on", "off", "brightness_stop", "brightness_step_up", "brightness_step_down", "brightness_move_up", "brightness_move_down"]),
        ],
        fromZigbee: [fz.command_on, fz.command_off, fz.command_step, fz.command_move, fz.command_stop, fzLocal.FB20002_on],
        toZigbee: [],
    },
    {
        fingerprint: tuya.fingerprint("TS1001", ["_TYZB01_hww2py6b"]),
        model: "FB21-001",
        vendor: "Lidl",
        description: "Livarno Lux switch and dimming light remote control",
        extend: [tuya.clusters.addTuyaGenOnOffCluster()],
        exposes: [
            e.action([
                "on",
                "off",
                "brightness_stop",
                "brightness_step_up",
                "brightness_step_down",
                "brightness_move_up",
                "brightness_move_down",
                "switch_scene",
            ]),
        ],
        fromZigbee: [fz.command_on, fz.command_off, fz.command_step, fz.command_move, fz.command_stop, tuya.fz.switch_scene],
        toZigbee: [],
    },
    {
        fingerprint: tuya.fingerprint("TS011F", [
            "_TZ3000_wzauvbcs",
            "_TZ3000_oznonj5q",
            "_TZ3000_1obwwnmq",
            "_TZ3000_4uf3d0ax",
            "_TZ3000_vzopcetz",
            "_TZ3000_vmpbygs5",
        ]),
        model: "HG06338",
        vendor: "Lidl",
        description: "Silvercrest 3 gang switch, with 4 USB (EU, FR, CZ, BS)",
        extend: [tuya.modernExtend.tuyaBase(), tuya.modernExtend.tuyaOnOff({ endpoints: ["l1", "l2", "l3"] })],
        meta: { multiEndpoint: true },
        configure: async (device, coordinatorEndpoint) => {
            await tuya.configureMagicPacket(device, coordinatorEndpoint);
            for (const ID of [1, 2, 3]) {
                await reporting.bind(device.getEndpoint(ID), coordinatorEndpoint, ["genOnOff"]);
            }
        },
        endpoint: (device) => {
            return { l1: 1, l2: 2, l3: 3 };
        },
    },
    {
        fingerprint: tuya.fingerprint("TS0601", ["_TZE200_s8gkrkxk"]),
        model: "HG06467",
        vendor: "Lidl",
        description: "Melinera smart LED string lights",
        toZigbee: [tz.on_off, legacy.tz.silvercrest_smart_led_string],
        fromZigbee: [fz.on_off, legacy.fz.silvercrest_smart_led_string],
        exposes: [e.light_brightness_colorhs().setAccess("brightness", ea.STATE_SET).setAccess("color_hs", ea.STATE_SET)],
    },
    {
        fingerprint: tuya.fingerprint("TS0504B", ["_TZ3210_sroezl0s"]),
        model: "14153806L",
        vendor: "Lidl",
        description: "Livarno smart LED ceiling light",
        extend: [tuya.modernExtend.tuyaLight({ colorTemp: { range: [153, 500] }, color: true })],
        configure: (device, coordinatorEndpoint) => {
            device.getEndpoint(1).saveClusterAttributeKeyValue("lightingColorCtrl", { colorCapabilities: 29 });
        },
    },
    {
        fingerprint: tuya.fingerprint("TS0601", ["_TZE200_htnnfasr"]),
        model: "PSBZS A1",
        vendor: "Lidl",
        description: "Parkside smart watering timer",
        fromZigbee: [fz.ignore_tuya_set_time, fz.ignore_onoff_report],
        extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true, timeStart: "1970" })],
        onEvent: async (event) => {
            if (event.type === "deviceInterview" && event.data.status === "successful") {
                // dirty hack: reset frost guard & frost alarm to get the initial state
                // wait 10 seconds to ensure configure is done
                await utils.sleep(10000);
                const endpoint = event.data.device.getEndpoint(1);
                try {
                    await tuya.sendDataPointBool(endpoint, 109, false);
                    await tuya.sendDataPointBool(endpoint, 108, false);
                }
                catch {
                    // ignore, just prevent any crashes
                }
            }
        },
        configure: async (device, coordinatorEndpoint) => {
            await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ["genOnOff"]);
            // set reporting interval of genOnOff to max to "disable" it
            // background: genOnOff reporting does not respect timer or button, that makes the on/off reporting pretty useless
            // the device is reporting it's state change anyway via tuya DPs
            await reporting.onOff(device.getEndpoint(1), { max: 0xffff });
        },
        exposes: [
            e.battery(),
            tuya.exposes.switch(),
            e
                .numeric("timer", ea.STATE_SET)
                .withValueMin(1)
                .withValueMax(599)
                .withUnit("min")
                .withDescription("Auto off after specific time for manual watering."),
            e.numeric("time_left", ea.STATE).withUnit("min").withDescription("Remaining time until the watering turns off."),
            e
                .binary("frost_lock", ea.STATE, "ON", "OFF")
                .withDescription("Indicates if the frost guard is currently active. " +
                "If the temperature drops below 5° C, device activates frost guard and disables irrigation. " +
                "You need to reset the frost guard to activate irrigation again. Note: There is no way to enable frost guard manually."),
            e.enum("reset_frost_lock", ea.SET, ["RESET"]).withDescription("Resets frost lock to make the device workable again."),
            e.enum("schedule_mode", ea.STATE, ["OFF", "WEEKDAY", "PERIODIC"]).withDescription("Scheduling mode that is currently in use."),
            e
                .numeric("schedule_periodic", ea.STATE_SET)
                .withValueMin(0)
                .withValueMax(7)
                .withUnit("day")
                .withDescription("Watering by periodic interval: Irrigate every n days"),
            e
                .composite("schedule_weekday", "schedule_weekday", ea.STATE_SET)
                .withDescription("Watering by weekday: Irrigate individually for each day.")
                .withFeature(e.binary("monday", ea.STATE_SET, "ON", "OFF"))
                .withFeature(e.binary("tuesday", ea.STATE_SET, "ON", "OFF"))
                .withFeature(e.binary("wednesday", ea.STATE_SET, "ON", "OFF"))
                .withFeature(e.binary("thursday", ea.STATE_SET, "ON", "OFF"))
                .withFeature(e.binary("friday", ea.STATE_SET, "ON", "OFF"))
                .withFeature(e.binary("saturday", ea.STATE_SET, "ON", "OFF"))
                .withFeature(e.binary("sunday", ea.STATE_SET, "ON", "OFF")),
            ...[1, 2, 3, 4, 5, 6].map((timeSlotNumber) => e
                .composite(`schedule_slot_${timeSlotNumber}`, `schedule_slot_${timeSlotNumber}`, ea.STATE_SET)
                .withDescription(`Watering time slot ${timeSlotNumber}`)
                .withFeature(e.binary("state", ea.STATE_SET, "ON", "OFF").withDescription("On/off state of the time slot"))
                .withFeature(e.numeric("start_hour", ea.STATE_SET).withUnit("h").withValueMin(0).withValueMax(23).withDescription("Starting time (hour)"))
                .withFeature(e
                .numeric("start_minute", ea.STATE_SET)
                .withUnit("min")
                .withValueMin(0)
                .withValueMax(59)
                .withDescription("Starting time (minute)"))
                .withFeature(e
                .numeric("timer", ea.STATE_SET)
                .withUnit("min")
                .withValueMin(1)
                .withValueMax(599)
                .withDescription("Auto off after specific time for scheduled watering."))
                .withFeature(e
                .numeric("pause", ea.STATE_SET)
                .withUnit("min")
                .withValueMin(0)
                .withValueMax(599)
                .withDescription("Pause after each iteration."))
                .withFeature(e
                .numeric("iterations", ea.STATE_SET)
                .withValueMin(1)
                .withValueMax(9)
                .withDescription("Number of watering iterations. Works only if there is a pause."))),
        ],
        meta: {
            tuyaDatapoints: [
                [1, null, valueConverterLocal.wateringState],
                // disable optimistic state reporting (device may not turn on when battery is low)
                [1, "state", tuya.valueConverter.onOff, { optimistic: false }],
                [5, "timer", tuya.valueConverter.raw],
                [6, "time_left", tuya.valueConverter.raw],
                [11, "battery", tuya.valueConverter.raw],
                [108, "frost_lock", tuya.valueConverter.onOff],
                // there is no state reporting for reset
                [109, "reset_frost_lock", tuya.valueConverterBasic.lookup({ RESET: tuya.enum(0) }), { optimistic: false }],
                [107, null, valueConverterLocal.wateringScheduleMode],
                [107, "schedule_periodic", valueConverterLocal.wateringSchedulePeriodic],
                [107, "schedule_weekday", valueConverterLocal.wateringScheduleWeekday],
                [101, "schedule_slot_1", valueConverterLocal.wateringScheduleSlot(1)],
                [102, "schedule_slot_2", valueConverterLocal.wateringScheduleSlot(2)],
                [103, "schedule_slot_3", valueConverterLocal.wateringScheduleSlot(3)],
                [104, "schedule_slot_4", valueConverterLocal.wateringScheduleSlot(4)],
                [105, "schedule_slot_5", valueConverterLocal.wateringScheduleSlot(5)],
                [106, "schedule_slot_6", valueConverterLocal.wateringScheduleSlot(6)],
            ],
        },
    },
    {
        fingerprint: tuya.fingerprint("TS0101", ["_TZ3000_br3laukf"]),
        model: "HG06620",
        vendor: "Lidl",
        description: "Silvercrest garden spike with 2 sockets",
        extend: [tuya.modernExtend.tuyaBase(), tuya.modernExtend.tuyaOnOff()],
        configure: async (device, coordinatorEndpoint) => {
            const endpoint = device.getEndpoint(1);
            await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff"]);
            await reporting.onOff(endpoint);
        },
    },
    {
        fingerprint: tuya.fingerprint("TS0101", ["_TZ3000_pnzfdr9y"]),
        model: "HG06619",
        vendor: "Lidl",
        description: "Silvercrest outdoor plug",
        extend: [tuya.modernExtend.tuyaBase(), tuya.modernExtend.tuyaOnOff()],
        configure: async (device, coordinatorEndpoint) => {
            const endpoint = device.getEndpoint(1);
            await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff"]);
            await reporting.onOff(endpoint);
        },
    },
    {
        fingerprint: tuya.fingerprint("TS0505B", ["_TZ3000_lxw3zcdk"]),
        model: "HG08633",
        vendor: "Lidl",
        description: "Livarno gardenspot RGB",
        extend: [tuya.modernExtend.tuyaLight({ colorTemp: { range: [153, 500] }, color: { modes: ["hs", "xy"] } })],
    },
    {
        fingerprint: tuya.fingerprint("TS0601", ["_TZE200_chyvmhay", "_TZE200_uiyqstza"]),
        model: "368308_2010",
        vendor: "Lidl",
        description: "Silvercrest radiator valve with thermostat",
        fromZigbee: [fz.ignore_tuya_set_time, legacy.fromZigbee.zs_thermostat],
        toZigbee: [
            legacy.toZigbee.zs_thermostat_current_heating_setpoint,
            legacy.toZigbee.zs_thermostat_child_lock,
            legacy.toZigbee.zs_thermostat_comfort_temp,
            legacy.toZigbee.zs_thermostat_eco_temp,
            legacy.toZigbee.zs_thermostat_preset_mode,
            legacy.toZigbee.zs_thermostat_system_mode,
            legacy.toZigbee.zs_thermostat_local_temperature_calibration,
            legacy.toZigbee.zs_thermostat_current_heating_setpoint_auto,
            legacy.toZigbee.zs_thermostat_openwindow_time,
            legacy.toZigbee.zs_thermostat_openwindow_temp,
            legacy.toZigbee.zs_thermostat_binary_one,
            legacy.toZigbee.zs_thermostat_binary_two,
            legacy.toZigbee.zs_thermostat_away_setting,
            legacy.toZigbee.zs_thermostat_local_schedule,
        ],
        extend: [tuya.modernExtend.tuyaBase({ forceTimeUpdates: true, bindBasicOnConfigure: true, timeStart: "1970" })],
        exposes: [
            e.child_lock(),
            e.comfort_temperature(),
            e.eco_temperature(),
            e.battery_voltage(),
            e
                .numeric("current_heating_setpoint_auto", ea.STATE_SET)
                .withValueMin(0.5)
                .withValueMax(29.5)
                .withValueStep(0.5)
                .withUnit("°C")
                .withDescription("Temperature setpoint automatic"),
            e
                .climate()
                .withSetpoint("current_heating_setpoint", 0.5, 29.5, 0.5, ea.STATE_SET)
                .withLocalTemperature(ea.STATE)
                .withLocalTemperatureCalibration(-12.5, 5.5, 0.1, ea.STATE_SET)
                .withSystemMode(["off", "heat", "auto"], ea.STATE_SET)
                .withPreset(["schedule", "manual", "holiday", "boost"]),
            e
                .numeric("detectwindow_temperature", ea.STATE_SET)
                .withUnit("°C")
                .withDescription("Open window detection temperature")
                .withValueMin(-10)
                .withValueMax(35),
            e
                .numeric("detectwindow_timeminute", ea.STATE_SET)
                .withUnit("min")
                .withDescription("Open window time in minute")
                .withValueMin(0)
                .withValueMax(1000),
            e.binary("binary_one", ea.STATE_SET, "ON", "OFF").withDescription("Unknown binary one"),
            e.binary("binary_two", ea.STATE_SET, "ON", "OFF").withDescription("Unknown binary two"),
            e.binary("away_mode", ea.STATE, "ON", "OFF").withDescription("Away mode"),
            e
                .composite("away_setting", "away_setting", ea.STATE_SET)
                .withFeature(e.away_preset_days())
                .setAccess("away_preset_days", ea.ALL)
                .withFeature(e.away_preset_temperature())
                .setAccess("away_preset_temperature", ea.ALL)
                .withFeature(e.numeric("away_preset_year", ea.ALL).withUnit("year").withDescription("Start away year 20xx"))
                .withFeature(e.numeric("away_preset_month", ea.ALL).withUnit("month").withDescription("Start away month"))
                .withFeature(e.numeric("away_preset_day", ea.ALL).withUnit("day").withDescription("Start away day"))
                .withFeature(e.numeric("away_preset_hour", ea.ALL).withUnit("hour").withDescription("Start away hours"))
                .withFeature(e.numeric("away_preset_minute", ea.ALL).withUnit("min").withDescription("Start away minutes")),
            ...["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"].map((day) => {
                const expose = e.composite(day, day, ea.STATE_SET);
                [1, 2, 3, 4, 5, 6, 7, 8, 9].forEach((i) => {
                    expose.withFeature(e
                        .numeric(`${day}_temp_${i}`, ea.ALL)
                        .withValueMin(0.5)
                        .withValueMax(29.5)
                        .withValueStep(0.5)
                        .withUnit("°C")
                        .withDescription(`Temperature ${i}`));
                    expose.withFeature(e
                        .enum(`${day}_hour_${i}`, ea.STATE_SET, [
                        "00",
                        "01",
                        "02",
                        "03",
                        "04",
                        "05",
                        "06",
                        "07",
                        "08",
                        "09",
                        "10",
                        "11",
                        "12",
                        "13",
                        "14",
                        "15",
                        "16",
                        "17",
                        "18",
                        "19",
                        "20",
                        "21",
                        "22",
                        "23",
                        "24",
                    ])
                        .withDescription(`Hour TO for temp ${i}`));
                    expose.withFeature(e.enum(`${day}_minute_${i}`, ea.STATE_SET, ["00", "15", "30", "45"]).withDescription(`Minute TO for temp ${i}`));
                });
                return expose;
            }),
        ],
    },
];
//# sourceMappingURL=lidl.js.map