"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 zigbee_herdsman_1 = require("zigbee-herdsman");
const fz = __importStar(require("../converters/fromZigbee"));
const tz = __importStar(require("../converters/toZigbee"));
const exposes = __importStar(require("../lib/exposes"));
const logger_1 = require("../lib/logger");
const m = __importStar(require("../lib/modernExtend"));
const reporting = __importStar(require("../lib/reporting"));
const utils_1 = require("../lib/utils");
const NS = "zhc:yale";
const e = exposes.presets;
const ea = exposes.access;
const lockExtend = (meta = {}, lockStateOptions = null, binds = ["closuresDoorLock", "genPowerCfg"]) => {
    return {
        fromZigbee: [
            fz.lock,
            fz.battery,
            fz.lock_operation_event,
            fz.lock_programming_event,
            fz.lock_pin_code_response,
            fz.lock_user_status_response,
        ],
        toZigbee: [tz.lock, tz.pincode_lock, tz.lock_userstatus, tz.lock_auto_relock_time, tz.lock_sound_volume],
        meta: { pinCodeCount: 250, ...meta },
        exposes: [
            e.lock(),
            e.battery(),
            e.pincode(),
            e.lock_action(),
            e.lock_action_source_name(),
            e.lock_action_user(),
            e.auto_relock_time().withValueMin(0).withValueMax(3600),
            e.sound_volume(),
            e.battery_low(),
        ],
        configure: [
            async (device, coordinatorEndpoint) => {
                const endpoint = device.getEndpoint(1);
                await reporting.bind(endpoint, coordinatorEndpoint, binds);
                if (lockStateOptions !== false) {
                    await reporting.lockState(endpoint, lockStateOptions);
                }
                await reporting.batteryPercentageRemaining(endpoint);
                try {
                    await reporting.batteryAlarmState(endpoint);
                }
                catch {
                    // Fails for some: https://github.com/Koenkk/zigbee-herdsman-converters/pull/5414
                }
            },
        ],
        isModernExtend: true,
    };
};
const yaleExtend = {
    addManuSpecificAssaDoorLockCluster: () => m.deviceAddCustomCluster("manuSpecificAssaDoorLock", {
        name: "manuSpecificAssaDoorLock",
        ID: 0xfc00,
        attributes: {
            autoLockTime: { name: "autoLockTime", ID: 0x0012, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
            wrongCodeAttempts: { name: "wrongCodeAttempts", ID: 0x0013, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
            shutdownTime: { name: "shutdownTime", ID: 0x0014, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
            batteryLevel: { name: "batteryLevel", ID: 0x0015, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
            insideEscutcheonLED: { name: "insideEscutcheonLED", ID: 0x0016, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
            volume: { name: "volume", ID: 0x0017, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
            lockMode: { name: "lockMode", ID: 0x0018, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
            language: { name: "language", ID: 0x0019, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
            allCodesLockout: { name: "allCodesLockout", ID: 0x001a, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN, write: true },
            oneTouchLocking: { name: "oneTouchLocking", ID: 0x001b, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN, write: true },
            privacyButtonSetting: { name: "privacyButtonSetting", ID: 0x001c, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN, write: true },
            /* enableLogging: {ID: 0x0020, type: Zcl.DataType.BOOLEAN, write: true},*/ // marked in C4 driver as not supported
            numberLogRecordsSupported: { name: "numberLogRecordsSupported", ID: 0x0021, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 0xffff },
            numberPinsSupported: { name: "numberPinsSupported", ID: 0x0030, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
            numberScheduleSlotsPerUser: { name: "numberScheduleSlotsPerUser", ID: 0x0040, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
            alarmMask: { name: "alarmMask", ID: 0x0050, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
        },
        commands: {
            getLockStatus: { name: "getLockStatus", ID: 0x10, response: 0, parameters: [] },
            getBatteryLevel: { name: "getBatteryLevel", ID: 0x12, parameters: [] },
            setRFLockoutTime: { name: "setRFLockoutTime", ID: 0x13, parameters: [] },
            /* getLogRecord: {ID: 0x20,
                parameters: [],
            },*/ // marked in C4 driver as not supported
            userCodeSet: {
                name: "userCodeSet",
                ID: 0x30,
                parameters: [
                    // bit pack ("bbb", slot, status, pinLength) .. pin
                    { name: "payload", type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR },
                ],
            },
            userCodeGet: {
                name: "userCodeGet",
                ID: 0x31,
                parameters: [
                    // bit pack ("b", slot)
                    { name: "payload", type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR },
                ],
            },
            userCodeClear: {
                name: "userCodeClear",
                ID: 0x32,
                parameters: [
                    // bit pack ("b", slot)
                    { name: "payload", type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR },
                ],
            },
            clearAllUserCodes: { name: "clearAllUserCodes", ID: 0x33, parameters: [] },
            setUserCodeStatus: { name: "setUserCodeStatus", ID: 0x34, parameters: [] },
            getUserCodeStatus: { name: "getUserCodeStatus", ID: 0x35, parameters: [] },
            getLastUserIdEntered: { name: "getLastUserIdEntered", ID: 0x36, parameters: [] },
            userAdded: { name: "userAdded", ID: 0x37, parameters: [] },
            userDeleted: { name: "userDeleted", ID: 0x38, parameters: [] },
            setScheduleSlot: {
                name: "setScheduleSlot",
                ID: 0x40,
                parameters: [
                    // bit pack ("bbbbbbb", 0, slot, weeklyScheduleNumber, startHour, startMinute, hours, minutes)
                    { name: "payload", type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR },
                ],
            },
            getScheduleSlot: {
                name: "getScheduleSlot",
                ID: 0x41,
                parameters: [
                    // bit pack ("bb", slot, userId)
                    { name: "payload", type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR },
                ],
            },
            setScheduleSlotStatus: {
                name: "setScheduleSlotStatus",
                ID: 0x42,
                parameters: [
                    // bit pack ("bbb", 0, slot, status)
                    { name: "payload", type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR },
                ],
            },
            reflash: {
                name: "reflash",
                ID: 0x60,
                response: 1,
                parameters: [
                    // bit pack ("bI", version, length)
                    { name: "payload", type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR },
                ],
            },
            reflashData: {
                name: "reflashData",
                ID: 0x61,
                response: 2,
                parameters: [
                    // bit pack ("IH", segmentId - 1, length) .. string sub (data, start, finish)
                    { name: "payload", type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR },
                ],
            },
            reflashStatus: {
                name: "reflashStatus",
                ID: 0x62,
                response: 3,
                parameters: [
                    // bit pack ("bI", reflashStatusParameter, 0x00)
                    { name: "payload", type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR },
                ],
            },
            getReflashLock: { name: "getReflashLock", ID: 0x90, parameters: [] },
            getHistory: { name: "getHistory", ID: 0xa0, parameters: [] },
            getLogin: { name: "getLogin", ID: 0xa1, parameters: [] },
            getUser: { name: "getUser", ID: 0xa2, parameters: [] },
            getUsers: { name: "getUsers", ID: 0xa3, parameters: [] },
            getMandatoryAttributes: { name: "getMandatoryAttributes", ID: 0xb0, parameters: [] },
            readAttribute: { name: "readAttribute", ID: 0xb1, parameters: [] },
            writeAttribute: { name: "writeAttribute", ID: 0xb2, parameters: [] },
            configureReporting: { name: "configureReporting", ID: 0xb3, parameters: [] },
            getBasicClusterAttributes: { name: "getBasicClusterAttributes", ID: 0xb4, parameters: [] },
        },
        commandsResponse: {
            getLockStatusRsp: { name: "getLockStatusRsp", ID: 0x00, parameters: [{ name: "status", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff }] },
            reflashRsp: { name: "reflashRsp", ID: 0x01, parameters: [{ name: "status", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff }] },
            reflashDataRsp: { name: "reflashDataRsp", ID: 0x02, parameters: [{ name: "status", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff }] },
            reflashStatusRsp: { name: "reflashStatusRsp", ID: 0x03, parameters: [{ name: "status", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff }] },
            /* boltStateRsp: {ID: 4,
                parameters: [
                    {name: 'state', type: Zcl.DataType.UINT8, max: 0xff},
                ],
            },*/ // C4 driver has this response yet there is no command - maybe a non-specific cluster response?
            /* lockStatusReportRsp: {ID: 5,
                parameters: [
                    {name: 'status', type: Zcl.DataType.UINT8, max: 0xff},
                ],
            },*/ // C4 driver has this response yet there is no command - maybe a non-specific cluster response?
            /* handleStateRsp: {ID: 6,
                parameters: [
                    {name: 'state', type: Zcl.DataType.UINT8, max: 0xff},
                ],
            },*/ // C4 driver has this response yet there is no command - maybe a non-specific cluster response?
            /* userStatusRsp: {ID: 7,
                parameters: [
                    {name: 'status', type: Zcl.DataType.UINT8, max: 0xff},
                ],
            },*/ // C4 driver has this response yet there is no command - maybe a non-specific cluster response?
        },
    }),
};
const fzLocal = {
    c4_alarm: {
        cluster: "genAlarms",
        type: ["commandAlarm"],
        convert: async (model, msg, publish, options, meta) => {
            let result = {};
            if (msg.data.clusterid === 64512) {
                const alarmcode = msg.data.alarmcode;
                const lookup = {
                    9: { state: "UNLOCKED", lock_state: "not_fully_locked", alarm: "deadbolt_jammed" },
                    18: { action: "keypad_lock", state: "LOCKED", lock_state: "locked" },
                    19: { action: "keypad_unlock", state: "UNLOCKED", lock_state: "unlocked" },
                    21: { action: "manual_lock_key_or_thumbturn", state: "LOCKED", lock_state: "locked" },
                    22: { action: "manual_unlock_key_or_thumbturn", state: "UNLOCKED", lock_state: "unlocked" },
                    24: { action: "lock_module", state: "LOCKED", lock_state: "locked" },
                    25: { action: "unlock_module", state: "UNLOCKED", lock_state: "unlocked" },
                    27: { action: "auto_lock", state: "LOCKED", lock_state: "locked" },
                    32: { action: "manual_lock_touch", state: "LOCKED", lock_state: "locked" },
                    48: { alarm: "lock_reset_to_factory_defaults" },
                    112: { alarm: "master_code_changed" },
                    113: { alarm: "duplicate_pin_code_error" },
                    128: { alarm: "battery_replaced", battery_low: false },
                    129: { alarm: "handing_cycle_completed_right" },
                    130: { alarm: "rf_module_power_cycled" },
                    131: { alarm: "handing_cycle_completed_left" },
                    161: { alarm: "tamper_alarm_keypad_attempts", tamper: true },
                    162: { alarm: "tamper_alarm_front_escutcheon", tamper: true },
                    167: { alarm: "tamper_alarm_low_battery", tamper: true, battery_low: true },
                    168: { alarm: "tamper_alarm_critical_battery", tamper: true, battery_low: true },
                    169: { alarm: "low_battery", battery_low: true },
                };
                result = (0, utils_1.getFromLookup)(alarmcode, lookup);
                // reset tamper and battery_low values as these will not self clear and will also be re-reported by device
                if (!("tamper" in result)) {
                    result.tamper = false;
                }
                if (!("battery_low" in result)) {
                    result.battery_low = false;
                }
            }
            // We need to read the lock attributes as these are not reported by the device
            try {
                await msg.endpoint.read("manuSpecificAssaDoorLock", ["batteryLevel"]);
            }
            catch {
                logger_1.logger.warning("Failed to read lock attributes", NS);
            }
            return result;
        },
    },
    c4_assa_lock_attribute: {
        cluster: "manuSpecificAssaDoorLock",
        type: ["readResponse"],
        convert: (model, msg, publish, options, meta) => {
            const data = msg.data;
            const result = {};
            if (data.autoLockTime) {
                const lookup = {
                    0: "off",
                    30: "30seconds",
                    60: "60seconds",
                    120: "2minutes",
                    180: "3minutes",
                };
                result.auto_lock_time = (0, utils_1.getFromLookup)(data.autoLockTime, lookup);
            }
            if (data.wrongCodeAttempts) {
                result.wrong_code_attempts = data.wrongCodeAttempts;
            }
            if (data.shutdownTime) {
                result.shutdown_time = data.shutdownTime;
            }
            if (data.batteryLevel) {
                result.battery = data.batteryLevel;
                result.battery_low = data.batteryLevel <= 15;
            }
            if (data.insideEscutcheonLED) {
                result.inside_escutcheon_led = data.insideEscutcheonLED === 1;
            }
            if (data.volume) {
                const lookup = {
                    1: "silent",
                    2: "low",
                    3: "high",
                };
                result.volume = (0, utils_1.getFromLookup)(data.volume, lookup);
            }
            if (data.lockMode) {
                const lookup = {
                    0: "normal",
                    1: "vacation",
                    2: "privacy",
                };
                result.lock_mode = (0, utils_1.getFromLookup)(data.lockMode, lookup);
            }
            if (data.language) {
                const lookup = {
                    1: "english",
                    2: "spanish",
                    3: "french",
                };
                result.lock_mode = (0, utils_1.getFromLookup)(data.language, lookup);
            }
            if (data.allCodesLockout) {
                result.all_codes_lockout = data.allCodesLockout;
            }
            if (data.oneTouchLocking) {
                result.one_touch_locking = data.oneTouchLocking;
            }
            if (data.privacyButtonSetting) {
                result.privacy_button = data.privacyButtonSetting;
            }
            if (data.numberLogRecordsSupported) {
                result.number_log_records_supported = data.numberLogRecordsSupported;
            }
            if (data.numberPinsSupported) {
                result.number_pins_supported = data.numberPinsSupported;
            }
            if (data.numberScheduleSlotsPerUser) {
                result.number_schedule_slots_per_user = data.numberScheduleSlotsPerUser;
            }
            if (data.alarmMask) {
                result.alarm_mask = data.alarmMask;
            }
            return result;
        },
    },
    c4_lock_operation_event: {
        cluster: "genAlarms",
        type: ["commandAlarm"],
        convert: async (model, msg, publish, options, meta) => {
            let result = {};
            if (msg.data.clusterid === 64512) {
                const alarmcode = msg.data.alarmcode;
                const lookup = {
                    9: { action: "error_jammed", state: "UNLOCK", lock_state: "not_fully_locked" },
                    21: { action: "manual_lock", state: "LOCK", lock_state: "locked" },
                    22: { action: "manual_unlock", state: "UNLOCK", lock_state: "unlocked" },
                    24: { action: "lock", state: "LOCK", lock_state: "locked" },
                    25: { action: "unlock", state: "UNLOCK", lock_state: "unlocked" },
                    27: { action: "auto_lock", state: "LOCK", lock_state: "locked" },
                };
                if (!(alarmcode in lookup)) {
                    result.action = "unknown";
                    logger_1.logger.warning(`Unrecognized Operation Event (${alarmcode})`, NS);
                    // We need to read the lock state as the alarm code is unknown
                    try {
                        await msg.endpoint.read("closuresDoorLock", ["lockState"]);
                    }
                    catch {
                        logger_1.logger.warning("Failed to read lock state", NS);
                    }
                }
                else {
                    result = (0, utils_1.getFromLookup)(alarmcode, lookup);
                }
            }
            return result;
        },
    },
    ymc_action: {
        cluster: "closuresDoorLock",
        type: ["raw"],
        convert: (model, msg, publish, options, meta) => {
            const actionLookup = {
                0: "password_unlock",
                1: "unlock",
                2: "auto_lock",
                3: "rfid_unlock",
                4: "fingerprint_unlock",
                5: "unlock_failure_invalid_pin_or_id",
                6: "unlock_failure_invalid_schedule",
                7: "one_touch_lock",
                8: "key_lock",
                9: "key_unlock",
                10: "auto_lock",
                11: "schedule_lock",
                12: "schedule_unlock",
                13: "manual_lock",
                14: "manual_unlock",
                15: "non_access_user_operational_event",
            };
            // NOTE: do NOT derive state/lock_state from operation events here. These
            // devices report lockState via attributeReport on real bolt movement, and
            // operation events can arrive without the bolt moving (or with codes that
            // differ per firmware generation), which caused phantom unlocks in HA.
            return {
                action: actionLookup[msg.data[3]] ?? "unknown",
                action_source_user: msg.data[5],
            };
        },
    },
    solis_action: {
        cluster: "closuresDoorLock",
        type: ["raw"],
        convert: (model, msg, publish, options, meta) => {
            // The Solis (SOLIS01) sends the standard ZCL operation event notification
            // (command 0x20) in a frame that fails ZCL parsing, so it lands here raw.
            // Field layout follows the ZCL spec (validated against live frames):
            //   data[3] = operation event source (0 keypad / 1 rf / 2 manual / 3 rfid / 4 indeterminate)
            //   data[4] = operation event code (same table as fz.lock_operation_event)
            //   data[5..6] = user id (uint16 LE)
            // data[3] is the SOURCE, not the action code — decoding it as the action
            // (as ymc_action does) misreports events, e.g. a real manual unlock
            // (source=2, code=2) came out as "auto_lock".
            const eventLookup = {
                0: "unknown",
                1: "lock",
                2: "unlock",
                3: "lock_failure_invalid_pin_or_id",
                4: "lock_failure_invalid_schedule",
                5: "unlock_failure_invalid_pin_or_id",
                6: "unlock_failure_invalid_schedule",
                7: "one_touch_lock",
                8: "key_lock",
                9: "key_unlock",
                10: "auto_lock",
                11: "schedule_lock",
                12: "schedule_unlock",
                13: "manual_lock",
                14: "manual_unlock",
                15: "non_access_user_operational_event",
            };
            const sourceLookup = {
                0: "keypad",
                1: "rf",
                2: "manual",
                3: "rfid",
                4: "indeterminate",
            };
            const source = msg.data[3];
            const code = msg.data[4];
            // No state/lock_state here on purpose: the Solis reports lockState via
            // attributeReport within the same second of a real operation, and it also
            // emits operation events while the bolt does not move (e.g. right after a
            // reboot), so deriving state from events causes phantom unlocks.
            return {
                action: eventLookup[code] ?? `unknown_${code}`,
                action_source_name: sourceLookup[source] ?? `unknown_${source}`,
                action_user: msg.data[5] | (msg.data[6] << 8),
            };
        },
    },
};
const tzLocal = {
    auto_lock_time: {
        key: ["auto_lock_time"],
        convertSet: async (entity, key, value, meta) => {
            const lookup = {
                off: 0,
                "30seconds": 30,
                "60seconds": 60,
                "2minutes": 120,
                "3minutes": 180,
            };
            await entity.write("manuSpecificAssaDoorLock", { autoLockTime: (0, utils_1.getFromLookup)(value, lookup) }, { disableDefaultResponse: true });
            return { state: { auto_lock_time: value } };
        },
        convertGet: async (entity, key, meta) => {
            await entity.read("manuSpecificAssaDoorLock", ["autoLockTime"]);
        },
    },
    volume: {
        key: ["volume"],
        convertSet: async (entity, key, value, meta) => {
            const lookup = {
                silent: 1,
                low: 2,
                high: 3,
            };
            await entity.write("manuSpecificAssaDoorLock", { volume: (0, utils_1.getFromLookup)(value, lookup) }, { disableDefaultResponse: true });
            return { state: { volume: value } };
        },
        convertGet: async (entity, key, meta) => {
            await entity.read("manuSpecificAssaDoorLock", ["volume"]);
        },
    },
};
exports.definitions = [
    {
        zigbeeModel: ["YRD446 BLE TSDB"],
        model: "YRD426NRSC",
        vendor: "Yale",
        description: "Assure lock",
        extend: [lockExtend()],
    },
    {
        zigbeeModel: ["YRL256 TS"],
        model: "YRL256 TS",
        vendor: "Yale",
        description: "Assure lock",
        extend: [m.battery(), m.lock({ pinCodeCount: 250 })],
    },
    {
        zigbeeModel: ["YRD226 TSDB", "YRD226L TSDB"],
        model: "YRD226HA2619",
        vendor: "Yale",
        description: "Assure lock",
        extend: [lockExtend()],
    },
    {
        zigbeeModel: ["YRD256 TSDB", "YRD256L TSDB"],
        model: "YRD256HA20BP",
        vendor: "Yale",
        description: "Assure lock SL",
        extend: [lockExtend()],
    },
    {
        zigbeeModel: ["YRD256-TSDB"],
        model: "YAYRD256HA2619",
        vendor: "Yale",
        description: "Assure lock SL",
        fromZigbee: [fzLocal.c4_lock_operation_event],
        extend: [lockExtend({}, false)],
    },
    {
        zigbeeModel: ["YRD652 TSDB", "YRD652L TSDB"],
        model: "YRD652HA20BP",
        vendor: "Yale",
        description: "Assure lock SL",
        extend: [lockExtend()],
    },
    {
        zigbeeModel: ["0600000001"],
        model: "YMF30",
        vendor: "Yale",
        description: "Digital lock",
        extend: [lockExtend({ battery: { dontDividePercentage: true } })],
    },
    {
        zigbeeModel: ["iZBModule01", "0700000001"],
        model: "YMF40/YDM4109+/YDF40",
        vendor: "Yale",
        description: "Real living lock / Intelligent biometric digital lock",
        extend: [lockExtend({ battery: { dontDividePercentage: true } })],
    },
    {
        zigbeeModel: ["YRD210 PB DB"],
        model: "YRD210-HA-605",
        vendor: "Yale",
        description: "Real living keyless push button deadbolt lock",
        extend: [lockExtend({ battery: { dontDividePercentage: true } })],
    },
    {
        zigbeeModel: ["YRL220 TS LL"],
        // The zigbee module card indicate that the module will work on YRD 221 and YRD 221RL also
        model: "YRL-220L",
        vendor: "Yale",
        description: "Real living keyless leveler lock",
        extend: [lockExtend({ battery: { dontDividePercentage: true } })],
    },
    {
        zigbeeModel: ["YRD226/246 TSDB"],
        model: "YRD226/246 TSDB",
        vendor: "Yale",
        description: "Assure lock",
        extend: [lockExtend()],
    },
    {
        zigbeeModel: ["YRD220/240 TSDB"],
        model: "YRD220/YRD221",
        vendor: "Yale",
        description: "Lockwood keyless push button deadbolt lock",
        extend: [lockExtend({ battery: { dontDividePercentage: true } })],
    },
    {
        zigbeeModel: ["YRD246 TSDB"],
        model: "YRD246HA20BP",
        vendor: "Yale",
        description: "Assure lock key free deadbolt with Zigbee",
        extend: [lockExtend({ battery: { dontDividePercentage: true } })],
    },
    {
        zigbeeModel: ["YRM476 TS BLE"],
        model: "YRM476",
        vendor: "Yale",
        description: "Assure lock",
        extend: [m.battery(), m.lock({ pinCodeCount: 250 })],
    },
    {
        zigbeeModel: ["YRD216 PBDB"],
        model: "YRD216-HA2-619",
        vendor: "Yale",
        description: "Real living keyless push button deadbolt lock",
        extend: [lockExtend({ battery: { dontDividePercentage: true } })],
    },
    {
        zigbeeModel: ["YRL226L TS"],
        model: "YRL226L TS",
        vendor: "Yale",
        description: "Assure lock SL",
        extend: [lockExtend()],
    },
    {
        zigbeeModel: ["YRL226 TS"],
        model: "YRL226 TS",
        vendor: "Yale",
        description: "Assure lock SL",
        extend: [lockExtend()],
    },
    {
        zigbeeModel: ["YRD410 TS", "YRD410 PB"],
        model: "YRD410-BLE",
        vendor: "Yale",
        description: "Assure lock 2",
        extend: [lockExtend()],
    },
    {
        zigbeeModel: ["YRD420 TS"],
        model: "YRD420-BLE",
        vendor: "Yale",
        description: "Assure lock 2",
        extend: [lockExtend()],
    },
    {
        zigbeeModel: ["YMC420", "YMC 420", "YMC420 W", "YMC 420 W"],
        model: "YMC420-W",
        vendor: "Yale",
        description: "Digital Lock YMC 420 W",
        fromZigbee: [fzLocal.ymc_action],
        extend: [lockExtend()],
        exposes: [
            e.action([
                "password_unlock",
                "unlock",
                "auto_lock",
                "rfid_unlock",
                "fingerprint_unlock",
                "unlock_failure_invalid_pin_or_id",
                "unlock_failure_invalid_schedule",
                "one_touch_lock",
                "key_lock",
                "key_unlock",
                "schedule_lock",
                "schedule_unlock",
                "manual_lock",
                "manual_unlock",
                "non_access_user_operational_event",
            ]),
        ],
    },
    {
        zigbeeModel: ["YDM60"],
        model: "YDM60",
        vendor: "Yale",
        description: "Digital lock",
        fromZigbee: [fzLocal.ymc_action],
        extend: [lockExtend()],
        exposes: [
            e.action([
                "password_unlock",
                "unlock",
                "auto_lock",
                "rfid_unlock",
                "fingerprint_unlock",
                "unlock_failure_invalid_pin_or_id",
                "unlock_failure_invalid_schedule",
                "one_touch_lock",
                "key_lock",
                "key_unlock",
                "schedule_lock",
                "schedule_unlock",
                "manual_lock",
                "manual_unlock",
                "non_access_user_operational_event",
            ]),
        ],
    },
    {
        zigbeeModel: ["SOLIS01"],
        model: "SOLIS01",
        vendor: "Yale",
        description: "Solis digital lock",
        fromZigbee: [fzLocal.solis_action],
        // Solis reports batteryPercentageRemaining on a 0-100 scale (not the ZCL
        // 0-200): a live frame reporting 58 corresponds to ~58%, and right after a
        // reboot the firmware sends placeholder values (200/0) until it re-measures.
        extend: [lockExtend({ battery: { dontDividePercentage: true } })],
    },
    {
        zigbeeModel: ["YRD430 TS", "YRD430 PB"],
        model: "YRD430-BLE",
        vendor: "Yale",
        description: "Assure lock 2",
        extend: [lockExtend()],
    },
    {
        zigbeeModel: ["YRD450 TS", "YRD450-F TS"],
        model: "YRD450-BLE",
        vendor: "Yale",
        description: "Assure lock 2",
        extend: [lockExtend()],
    },
    {
        zigbeeModel: ["LIA"],
        model: "LIA",
        vendor: "Yale",
        description: "Digital Lock Lia",
        extend: [lockExtend()],
    },
    {
        // Appears to be a slightly rebranded Assure lock SL
        // Just with Lockwood | Assa Abloy branding instead of Yale
        // Appears to have been part of a deal with Telstra, hence the T-Lock name
        zigbeeModel: ["YDD-D4F0 TSDB"],
        model: "YDD-D4F0-TSDB",
        vendor: "Yale",
        description: "Lockwood T-Lock",
        extend: [lockExtend()],
    },
    {
        zigbeeModel: ["c700000202", "06ffff2029"],
        model: "YDF40",
        vendor: "Yale",
        description: "Real living lock / Intelligent biometric digital lock",
        extend: [lockExtend({ battery: { dontDividePercentage: true } }, { max: 900 }, ["closuresDoorLock"])],
    },
    {
        zigbeeModel: ["06ffff2027", "06e01d220c"],
        model: "YMF40A RL",
        vendor: "Yale",
        description: "Real living lock / Intelligent biometric digital lock",
        extend: [lockExtend({ battery: { dontDividePercentage: true } })],
    },
    {
        zigbeeModel: ["06e0152204"],
        model: "YMI70A",
        vendor: "Yale",
        description: "Biometric digital lock",
        extend: [m.battery(), m.lock({ pinCodeCount: 100 })],
    },
    {
        fingerprint: [
            {
                type: "EndDevice",
                manufacturerName: "Yale",
                manufacturerID: 43690,
                powerSource: "Battery",
                endpoints: [
                    { ID: 1, profileID: 260, deviceID: 10, inputClusters: [0, 9, 10, 257, 64512, 1], outputClusters: [] },
                    { ID: 196, profileID: 260, deviceID: 10, inputClusters: [1], outputClusters: [] },
                ],
            },
        ],
        model: "ZYA-C4-MOD-S",
        vendor: "Yale",
        description: "Control4 module for Yale KeyFree/Keyless/Doorman/Assure/nexTouch locks",
        extend: [yaleExtend.addManuSpecificAssaDoorLockCluster()],
        fromZigbee: [fz.lock, fzLocal.c4_alarm, fzLocal.c4_assa_lock_attribute],
        toZigbee: [tz.lock, tzLocal.auto_lock_time, tzLocal.volume],
        exposes: [
            e.lock(),
            e.lock_action(),
            e.battery(),
            e.battery_low(),
            e.enum("auto_lock_time", ea.ALL, ["off", "30seconds", "60seconds", "2minutes", "3minutes"]),
            e.enum("volume", ea.ALL, ["silent", "low", "high"]),
        ],
        configure: async (device, coordinatorEndpoint) => {
            const endpoint = device.getEndpoint(1);
            await endpoint.read("closuresDoorLock", ["lockState"]);
            await endpoint.read("manuSpecificAssaDoorLock", [
                "autoLockTime",
                "wrongCodeAttempts",
                "shutdownTime",
                "batteryLevel",
                "volume",
            ]);
            await reporting.bind(endpoint, coordinatorEndpoint, ["manuSpecificAssaDoorLock"]);
        },
    },
];
//# sourceMappingURL=yale.js.map