"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.boschSmartPlugExtend = exports.boschBsenExtend = exports.boschDoorWindowContactExtend = exports.boschBsirExtend = exports.boschBmctExtend = exports.boschGeneralExtend = exports.manufacturerOptions = 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 m = __importStar(require("../lib/modernExtend"));
const constants_1 = require("./constants");
const logger_1 = require("./logger");
const reporting_1 = require("./reporting");
const utils = __importStar(require("./utils"));
const utils_1 = require("./utils");
const e = exposes.presets;
const ea = exposes.access;
const NS = "zhc:bosch";
exports.manufacturerOptions = { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.ROBERT_BOSCH_GMBH };
exports.boschGeneralExtend = {
    handleZclVersionReadRequest: () => {
        const onEvent = [
            (event) => {
                if (event.type !== "deviceAnnounce") {
                    return;
                }
                event.data.device.customReadResponse = (frame, endpoint) => {
                    const isZclVersionRequest = frame.isCluster("genBasic") && frame.payload.find((i) => i.attrId === 0);
                    if (!isZclVersionRequest) {
                        return false;
                    }
                    const payload = {
                        zclVersion: 1,
                    };
                    endpoint.readResponse(frame.cluster.name, frame.header.transactionSequenceNumber, payload).catch((e) => {
                        logger_1.logger.warning(`Custom zclVersion response failed for '${event.data.device.ieeeAddr}': ${e}`, NS);
                    });
                    return true;
                };
            },
        ];
        return {
            onEvent,
            isModernExtend: true,
        };
    },
    customSeMeteringCluster: () => m.deviceAddCustomCluster("seMetering", {
        ID: zigbee_herdsman_1.Zcl.Clusters.seMetering.ID,
        attributes: {},
        commands: {
            resetEnergyMeters: {
                ID: 0x80,
                parameters: [],
            },
        },
        commandsResponse: {},
    }),
    resetEnergyMeters: () => {
        const exposes = [
            e
                .enum("reset_energy_meters", ea.SET, ["reset"])
                .withDescription("Triggers the reset of all energy meters on the device to 0 kWh")
                .withCategory("config"),
        ];
        const toZigbee = [
            {
                key: ["reset_energy_meters"],
                convertSet: async (entity, key, value, meta) => {
                    await entity.command("seMetering", "resetEnergyMeters", {}, exports.manufacturerOptions);
                },
            },
        ];
        return {
            exposes,
            toZigbee,
            isModernExtend: true,
        };
    },
    autoOff: (args) => {
        const { endpoint } = args ?? {};
        const offOnLookup = {
            OFF: 0x00,
            ON: 0x01,
        };
        const expose = (device, options) => {
            if (utils.isDummyDevice(device)) {
                return [];
            }
            if (device.modelID === "RBSH-MMR-ZB-EU") {
                const pulsedModeEnabled = device.getEndpoint(1).getClusterAttributeValue("boschEnergyDevice", "pulseLength") !== 0;
                if (pulsedModeEnabled) {
                    return [];
                }
            }
            const autoOffEnabledExpose = e
                .binary("auto_off_enabled", ea.ALL, utils.getFromLookupByValue(0x01, offOnLookup), utils.getFromLookupByValue(0x00, offOnLookup))
                .withLabel("Enable auto-off")
                .withDescription("Enable/disable the automatic turn-off feature")
                .withCategory("config");
            const autoOffTimeExpose = e
                .numeric("auto_off_time", ea.ALL)
                .withLabel("Auto-off time")
                .withDescription("Turn off the output after the specified amount of time. Only in action when the automatic turn-off is enabled.")
                .withUnit("min")
                .withValueMin(0)
                .withValueMax(720)
                .withValueStep(0.5)
                .withCategory("config");
            if (endpoint !== undefined) {
                autoOffEnabledExpose.withEndpoint(endpoint.toString());
                autoOffTimeExpose.withEndpoint(endpoint.toString());
            }
            return [autoOffEnabledExpose, autoOffTimeExpose];
        };
        const fromZigbee = [
            {
                cluster: "boschEnergyDevice",
                type: ["attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const result = {};
                    const data = msg.data;
                    if (data.autoOffEnabled !== undefined) {
                        const property = utils.postfixWithEndpointName("auto_off_enabled", msg, model, meta);
                        result[property] = utils.getFromLookupByValue(data.autoOffEnabled, offOnLookup);
                    }
                    if (data.autoOffTime !== undefined) {
                        const property = utils.postfixWithEndpointName("auto_off_time", msg, model, meta);
                        result[property] = data.autoOffTime / 60;
                    }
                    return result;
                },
            },
        ];
        const toZigbee = [
            {
                key: ["auto_off_enabled", "auto_off_time"],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "auto_off_enabled") {
                        const selectedState = utils.getFromLookup(value, offOnLookup);
                        await entity.write("boschEnergyDevice", {
                            autoOffEnabled: utils.toNumber(selectedState),
                        });
                        return { state: { auto_off_enabled: value } };
                    }
                    if (key === "auto_off_time") {
                        await entity.write("boschEnergyDevice", {
                            autoOffTime: (0, utils_1.toNumber)(value) * 60,
                        });
                        return { state: { auto_off_time: value } };
                    }
                },
                convertGet: async (entity, key, meta) => {
                    if (key === "auto_off_enabled") {
                        await entity.read("boschEnergyDevice", ["autoOffEnabled"]);
                    }
                    if (key === "auto_off_time") {
                        await entity.read("boschEnergyDevice", ["autoOffTime"]);
                    }
                },
            },
        ];
        const configure = [
            m.setupConfigureForBinding("boschEnergyDevice", "input", endpoint ? [endpoint.toString()] : null),
            m.setupConfigureForReading("boschEnergyDevice", ["autoOffEnabled", "autoOffTime"], endpoint ? [endpoint.toString()] : null),
        ];
        return {
            exposes: [expose],
            fromZigbee,
            toZigbee,
            configure,
            isModernExtend: true,
        };
    },
};
exports.boschBmctExtend = {
    switchMode: (args) => {
        const { endpoint, deviceModeLookup, switchModeLookup, switchTypeLookup } = args;
        const expose = (device, options) => {
            if (utils.isDummyDevice(device)) {
                return [];
            }
            const switchTypeKey = device.getEndpoint(1).getClusterAttributeValue("boschEnergyDevice", "switchType") ?? 0x00;
            const selectedSwitchType = utils.getFromLookupByValue(switchTypeKey, switchTypeLookup);
            if (selectedSwitchType === "none") {
                return [];
            }
            let supportedSwitchModes = Object.keys(switchModeLookup);
            if (device.modelID === "RBSH-MMS-ZB-EU") {
                const deviceModeKey = device.getEndpoint(1).getClusterAttributeValue("boschEnergyDevice", "deviceMode");
                const deviceMode = utils.getFromLookupByValue(deviceModeKey, deviceModeLookup);
                if (deviceMode === "light") {
                    if (selectedSwitchType.includes("rocker_switch")) {
                        supportedSwitchModes = supportedSwitchModes.filter((switchMode) => switchMode === "coupled" || switchMode === "decoupled");
                    }
                }
                if (deviceMode === "shutter") {
                    if (selectedSwitchType.includes("button")) {
                        supportedSwitchModes = supportedSwitchModes.filter((switchMode) => switchMode === "coupled" || switchMode === "only_long_press_decoupled");
                    }
                    else if (selectedSwitchType.includes("rocker_switch")) {
                        supportedSwitchModes = supportedSwitchModes.filter((switchMode) => switchMode === "coupled");
                    }
                }
            }
            const switchModeExpose = e
                .enum("switch_mode", ea.ALL, supportedSwitchModes)
                .withDescription("Decouple the switch from the corresponding output to use it for other purposes. Please keep in mind that the available options may depend on the used switch type.")
                .withCategory("config");
            if (endpoint !== undefined) {
                switchModeExpose.withEndpoint(endpoint.toString());
            }
            return [switchModeExpose];
        };
        const fromZigbee = [
            {
                cluster: "boschEnergyDevice",
                type: ["attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const result = {};
                    const data = msg.data;
                    if (data.switchMode !== undefined) {
                        const property = utils.postfixWithEndpointName("switch_mode", msg, model, meta);
                        result[property] = utils.getFromLookupByValue(data.switchMode, switchModeLookup);
                    }
                    return result;
                },
            },
        ];
        const toZigbee = [
            {
                key: ["switch_mode"],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "switch_mode") {
                        const index = utils.getFromLookup(value, switchModeLookup);
                        await entity.write("boschEnergyDevice", { switchMode: index });
                        return { state: { switch_mode: value } };
                    }
                },
                convertGet: async (entity, key, meta) => {
                    if (key === "switch_mode") {
                        await entity.read("boschEnergyDevice", ["switchMode"]);
                    }
                },
            },
        ];
        const configure = [
            async (device, coordinatorEndpoint, definition) => {
                const desiredEndpoint = device.getEndpoint(endpoint ?? 1);
                await desiredEndpoint.read("boschEnergyDevice", ["switchMode"]);
            },
        ];
        return {
            exposes: [expose],
            fromZigbee,
            toZigbee,
            configure,
            isModernExtend: true,
        };
    },
    childLock: (args) => {
        const { endpoint } = args ?? {};
        const childLockLookup = {
            UNLOCKED: 0x00,
            LOCKED: 0x01,
        };
        const expose = (device, options) => {
            if (utils.isDummyDevice(device)) {
                return [];
            }
            const currentSwitchType = device.getEndpoint(1).getClusterAttributeValue("boschEnergyDevice", "switchType") ?? 0x00;
            if (currentSwitchType === 0) {
                return [];
            }
            const childLockExpose = e
                .binary("child_lock", ea.ALL, utils.getFromLookupByValue(0x01, childLockLookup), utils.getFromLookupByValue(0x00, childLockLookup))
                .withDescription("Enables/disables physical input on the switch")
                .withCategory("config");
            if (endpoint !== undefined) {
                childLockExpose.withEndpoint(endpoint.toString());
            }
            return [childLockExpose];
        };
        const fromZigbee = [
            {
                cluster: "boschEnergyDevice",
                type: ["attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const result = {};
                    const data = msg.data;
                    if (data.childLock !== undefined) {
                        const property = utils.postfixWithEndpointName("child_lock", msg, model, meta);
                        result[property] = data.childLock;
                    }
                    return result;
                },
            },
        ];
        const toZigbee = [
            {
                key: ["child_lock"],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "child_lock") {
                        const selectedMode = utils.getFromLookup(value, childLockLookup);
                        await entity.write("boschEnergyDevice", { childLock: selectedMode });
                        return { state: { child_lock: value } };
                    }
                },
                convertGet: async (entity, key, meta) => {
                    if (key === "child_lock") {
                        await entity.read("boschEnergyDevice", ["childLock"]);
                    }
                },
            },
        ];
        const configure = [
            async (device, coordinatorEndpoint, definition) => {
                const desiredEndpoint = device.getEndpoint(endpoint ?? 1);
                await desiredEndpoint.read("boschEnergyDevice", ["childLock"]);
            },
        ];
        return {
            exposes: [expose],
            fromZigbee,
            toZigbee,
            configure,
            isModernExtend: true,
        };
    },
    actuatorType: () => m.enumLookup({
        name: "actuator_type",
        cluster: "boschEnergyDevice",
        attribute: "actuatorType",
        description: "Select the appropriate actuator type so that the connected device can be controlled correctly.",
        lookup: {
            normally_closed: 0x00,
            normally_open: 0x01,
        },
        entityCategory: "config",
    }),
    dimmerType: () => m.enumLookup({
        name: "dimmer_type",
        cluster: "boschEnergyDevice",
        attribute: "dimmerType",
        description: "Select the appropriate dimmer type for your lamps. Make sure that you are only using dimmable lamps.",
        lookup: {
            leading_edge_phase_cut: 0x00,
            trailing_edge_phase_cut: 0x01,
        },
        entityCategory: "config",
    }),
    brightnessRange: () => {
        const expose = (device, options) => {
            if (utils.isDummyDevice(device)) {
                return [];
            }
            const minimumBrightnessExpose = e
                .numeric("minimum_brightness", ea.ALL)
                .withLabel("Raise minimum brightness")
                .withDescription("This raises the minimum brightness level of the connected light")
                .withValueMin(0)
                .withValueMax(255)
                .withCategory("config");
            const maximumBrightnessExpose = e
                .numeric("maximum_brightness", ea.ALL)
                .withLabel("Lower maximum brightness")
                .withDescription("This lowers the maximum brightness level of the connected light")
                .withValueMin(0)
                .withValueMax(255)
                .withCategory("config");
            return [minimumBrightnessExpose, maximumBrightnessExpose];
        };
        const fromZigbee = [
            {
                cluster: "boschEnergyDevice",
                type: ["attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const result = {};
                    const data = msg.data;
                    if (data.minimumBrightness !== undefined) {
                        result.minimum_brightness = data.minimumBrightness;
                    }
                    if (data.maximumBrightness !== undefined) {
                        result.maximum_brightness = data.maximumBrightness;
                    }
                    return result;
                },
            },
        ];
        const toZigbee = [
            {
                key: ["minimum_brightness", "maximum_brightness"],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "minimum_brightness") {
                        const newMinimumBrightness = (0, utils_1.toNumber)(value);
                        const currentState = await entity.read("boschEnergyDevice", ["maximumBrightness"]);
                        if (newMinimumBrightness >= currentState.maximumBrightness) {
                            throw new Error("The minimum brightness must be lower than the maximum brightness!");
                        }
                        await entity.write("boschEnergyDevice", {
                            minimumBrightness: newMinimumBrightness,
                        });
                        return { state: { minimum_brightness: value } };
                    }
                    if (key === "maximum_brightness") {
                        const newMaximumBrightness = (0, utils_1.toNumber)(value);
                        const currentState = await entity.read("boschEnergyDevice", ["minimumBrightness"]);
                        if (newMaximumBrightness <= currentState.minimumBrightness) {
                            throw new Error("The maximum brightness must be higher than the minimum brightness!");
                        }
                        await entity.write("boschEnergyDevice", {
                            maximumBrightness: newMaximumBrightness,
                        });
                        return { state: { maximum_brightness: value } };
                    }
                },
                convertGet: async (entity, key, meta) => {
                    if (key === "minimum_brightness") {
                        await entity.read("boschEnergyDevice", ["minimumBrightness"]);
                    }
                    if (key === "maximum_brightness") {
                        await entity.read("boschEnergyDevice", ["maximumBrightness"]);
                    }
                },
            },
        ];
        const configure = [
            async (device, coordinatorEndpoint, definition) => {
                const endpoint = device.getEndpoint(1);
                await endpoint.read("boschEnergyDevice", ["minimumBrightness", "maximumBrightness"]);
            },
        ];
        return {
            exposes: [expose],
            fromZigbee,
            toZigbee,
            configure,
            isModernExtend: true,
        };
    },
    rzDeviceModes: (args) => {
        const { deviceModesLookup } = args;
        const expose = (device, options) => {
            if (utils.isDummyDevice(device)) {
                return [];
            }
            const deviceModeExpose = e
                .enum("device_mode", ea.SET, Object.keys(deviceModesLookup))
                .withLabel("Device mode")
                .withDescription("Set the desired mode of the relay")
                .withCategory("config");
            return [deviceModeExpose];
        };
        const toZigbee = [
            {
                key: ["device_mode"],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "device_mode") {
                        const deviceModeChanged = meta.state.device_mode !== value;
                        if (deviceModeChanged) {
                            const newPulseLength = value === utils.getFromLookupByValue(0x00, deviceModesLookup) ? 0 : 10;
                            const endpoint = meta.device.getEndpoint(1);
                            if (newPulseLength > 0) {
                                await endpoint.write("boschEnergyDevice", {
                                    switchType: 0x05,
                                    switchMode: 0x00,
                                    childLock: 0x00,
                                    autoOffEnabled: 0x00,
                                    autoOffTime: 0,
                                });
                                await endpoint.read("boschEnergyDevice", [
                                    "switchType",
                                    "switchMode",
                                    "childLock",
                                    "autoOffEnabled",
                                    "autoOffTime",
                                ]);
                            }
                            else {
                                await endpoint.write("boschEnergyDevice", {
                                    switchType: 0x00,
                                    switchMode: 0x00,
                                    childLock: 0x00,
                                });
                                await endpoint.read("boschEnergyDevice", [
                                    "switchType",
                                    "switchMode",
                                    "childLock",
                                ]);
                            }
                            await endpoint.write("boschEnergyDevice", {
                                pulseLength: newPulseLength,
                            });
                            await endpoint.read("boschEnergyDevice", ["pulseLength"]);
                        }
                        return { state: { device_mode: value } };
                    }
                },
            },
        ];
        return {
            exposes: [expose],
            toZigbee,
            isModernExtend: true,
        };
    },
    pulseLength: (args) => {
        const { updateDeviceMode, deviceModesLookup } = args;
        const expose = (device, options) => {
            if (utils.isDummyDevice(device)) {
                return [];
            }
            if (device.getEndpoint(1).getClusterAttributeValue("boschEnergyDevice", "pulseLength") === 0) {
                return [];
            }
            const pulseLengthExpose = e
                .numeric("pulse_length", ea.ALL)
                .withLabel("Pulse length")
                .withDescription("Set the desired pulse length for the relay in seconds.")
                .withUnit("s")
                .withValueStep(0.1)
                .withValueMin(0.5)
                .withValueMax(20)
                .withCategory("config");
            return [pulseLengthExpose];
        };
        const fromZigbee = [
            {
                cluster: "boschEnergyDevice",
                type: ["attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const result = {};
                    const data = msg.data;
                    if (data.pulseLength !== undefined) {
                        const currentPulseLength = data.pulseLength / 10;
                        const oldPulseLength = meta.device.meta.pulseLength ?? 0;
                        const pulsedModeActivated = currentPulseLength > 0 && oldPulseLength === 0;
                        const pulsedModeDeactivated = currentPulseLength === 0 && oldPulseLength > 0;
                        if (pulsedModeActivated || pulsedModeDeactivated) {
                            meta.device.meta.pulseLength = currentPulseLength;
                            meta.deviceExposesChanged();
                        }
                        if (updateDeviceMode) {
                            result.device_mode =
                                currentPulseLength === 0
                                    ? utils.getFromLookupByValue(0x00, deviceModesLookup)
                                    : utils.getFromLookupByValue(0x01, deviceModesLookup);
                        }
                        result.pulse_length = currentPulseLength;
                    }
                    return result;
                },
            },
        ];
        const toZigbee = [
            {
                key: ["pulse_length"],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "pulse_length") {
                        const selectedPulseLength = (0, utils_1.toNumber)(value) * 10;
                        await entity.write("boschEnergyDevice", {
                            pulseLength: selectedPulseLength,
                        });
                        return { state: { pulse_length: value } };
                    }
                },
                convertGet: async (entity, key, meta) => {
                    if (key === "pulse_length") {
                        await entity.read("boschEnergyDevice", ["pulseLength"]);
                    }
                },
            },
        ];
        const configure = [
            async (device, coordinatorEndpoint, definition) => {
                const endpoint = device.getEndpoint(1);
                await endpoint.read("boschEnergyDevice", ["pulseLength"]);
            },
        ];
        return {
            exposes: [expose],
            fromZigbee,
            toZigbee,
            configure,
            isModernExtend: true,
        };
    },
    switchType: (args) => {
        const { switchTypeLookup } = args;
        const expose = (device, options) => {
            if (utils.isDummyDevice(device)) {
                return [];
            }
            let supportedSwitchTypes = Object.keys(switchTypeLookup);
            if (device.modelID === "RBSH-MMR-ZB-EU") {
                const pulseModeActive = device.getEndpoint(1).getClusterAttributeValue("boschEnergyDevice", "pulseLength") > 0;
                if (pulseModeActive) {
                    supportedSwitchTypes = Object.keys(switchTypeLookup).filter((switchType) => switchType !== utils.getFromLookup("rocker_switch", switchTypeLookup));
                }
            }
            const switchTypeExpose = e
                .enum("switch_type", ea.ALL, supportedSwitchTypes)
                .withLabel("Connected switch type")
                .withDescription("Select which switch type is connected to the module. Please keep in mind that the available options may depend on the selected device mode.")
                .withCategory("config");
            return [switchTypeExpose];
        };
        const fromZigbee = [
            {
                cluster: "boschEnergyDevice",
                type: ["attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const result = {};
                    const data = msg.data;
                    if (data.switchType !== undefined) {
                        const switchType = data.switchType;
                        result.switch_type = utils.getFromLookupByValue(switchType, switchTypeLookup);
                        if (switchType !== meta.device.meta.switchType) {
                            meta.device.meta.switchType = switchType;
                            meta.deviceExposesChanged();
                        }
                    }
                    return result;
                },
            },
        ];
        const toZigbee = [
            {
                key: ["switch_type"],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "switch_type") {
                        const selectedSwitchType = utils.getFromLookup(value, switchTypeLookup);
                        if (meta.device.meta.switchType !== selectedSwitchType) {
                            const endpoints = meta.device.endpoints.filter((e) => e.supportsInputCluster("boschEnergyDevice"));
                            for (const endpoint of endpoints) {
                                await endpoint.write("boschEnergyDevice", {
                                    switchMode: 0x00,
                                    childLock: 0x00,
                                });
                                await endpoint.read("boschEnergyDevice", ["switchMode", "childLock"]);
                            }
                        }
                        await entity.write("boschEnergyDevice", {
                            switchType: selectedSwitchType,
                        });
                        await entity.read("boschEnergyDevice", ["switchType"]);
                        return { state: { switch_type: value } };
                    }
                },
                convertGet: async (entity, key, meta) => {
                    if (key === "switch_type") {
                        await entity.read("boschEnergyDevice", ["switchType"]);
                    }
                },
            },
        ];
        const configure = [
            async (device, coordinatorEndpoint, definition) => {
                const endpoint = device.getEndpoint(1);
                await endpoint.read("boschEnergyDevice", ["switchType"]);
            },
        ];
        return {
            exposes: [expose],
            fromZigbee,
            toZigbee,
            configure,
            isModernExtend: true,
        };
    },
    reportSwitchAction: (args) => {
        const { switchTypeLookup, hasDualSwitchInputs } = args;
        const expose = (device, options) => {
            const exposeList = [];
            if (utils.isDummyDevice(device)) {
                return exposeList;
            }
            const switchTypeKey = device.getEndpoint(1).getClusterAttributeValue("boschEnergyDevice", "switchType") ?? 0x00;
            const selectedSwitchType = utils.getFromLookupByValue(switchTypeKey, switchTypeLookup);
            let supportedActionTypes;
            if (selectedSwitchType.includes("button")) {
                if (hasDualSwitchInputs) {
                    supportedActionTypes = [
                        "press_released_left",
                        "press_released_right",
                        "hold_left",
                        "hold_right",
                        "hold_released_left",
                        "hold_released_right",
                    ];
                }
                else {
                    supportedActionTypes = ["press_released", "hold", "hold_released"];
                }
                exposeList.push(e.action(supportedActionTypes), e.action_duration());
            }
            else if (selectedSwitchType.includes("rocker_switch")) {
                if (hasDualSwitchInputs) {
                    supportedActionTypes = ["opened_left", "opened_right", "closed_left", "closed_right"];
                }
                else {
                    supportedActionTypes = ["opened", "closed"];
                }
                exposeList.push(e.action(supportedActionTypes));
            }
            return exposeList;
        };
        const fromZigbee = [
            {
                cluster: "boschEnergyDevice",
                type: ["raw"],
                convert: (model, msg, publish, options, meta) => {
                    const command = msg.data[4];
                    if (command !== 0x03 && command !== 0x04) {
                        return;
                    }
                    let state;
                    const status = msg.data[5];
                    const duration = msg.data[6] / 10;
                    switch (status) {
                        case 0:
                            state = "press_released";
                            break;
                        case 1:
                            state = duration !== 0 ? "hold" : "hold_released";
                            break;
                        case 2:
                            state = "closed";
                            break;
                        case 3:
                            state = "opened";
                            break;
                    }
                    let action;
                    if (hasDualSwitchInputs) {
                        const triggeredSide = command === 0x03 ? "left" : "right";
                        action = `${state}_${triggeredSide}`;
                    }
                    else {
                        action = state;
                    }
                    return { action: action, action_duration: duration };
                },
            },
        ];
        return {
            exposes: [expose],
            fromZigbee,
            isModernExtend: true,
        };
    },
    slzExtends: () => {
        const stateDeviceMode = {
            light: 0x04,
            shutter: 0x01,
            disabled: 0x00,
        };
        const stateMotor = {
            stopped: 0x00,
            opening: 0x01,
            closing: 0x02,
            unknownOne: 0x03,
            unknownTwo: 0x04,
        };
        const stateSwitchType = {
            button: 0x01,
            button_key_change: 0x02,
            rocker_switch: 0x03,
            rocker_switch_key_change: 0x04,
            none: 0x00,
        };
        const stateSwitchMode = {
            coupled: 0x00,
            decoupled: 0x01,
            only_short_press_decoupled: 0x02,
            only_long_press_decoupled: 0x03,
        };
        const stateOffOn = {
            OFF: 0x00,
            ON: 0x01,
        };
        const fromZigbee = [
            fz.on_off_force_multiendpoint,
            fz.power_on_behavior,
            fz.cover_position_tilt,
            {
                cluster: "boschEnergyDevice",
                type: ["attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const result = {};
                    const data = msg.data;
                    if (data.deviceMode !== undefined) {
                        result.device_mode = Object.keys(stateDeviceMode).find((key) => stateDeviceMode[key] === msg.data.deviceMode);
                        const deviceMode = msg.data.deviceMode;
                        if (deviceMode !== meta.device.meta.deviceMode) {
                            meta.device.meta.deviceMode = deviceMode;
                            meta.deviceExposesChanged();
                        }
                    }
                    if (data.switchType !== undefined) {
                        const switchType = msg.data.switchType;
                        result.switch_type = Object.keys(stateSwitchType).find((key) => stateSwitchType[key] === switchType);
                        if (switchType !== meta.device.meta.switchType) {
                            meta.device.meta.switchType = switchType;
                            meta.deviceExposesChanged();
                        }
                    }
                    if (data.switchMode !== undefined) {
                        const property = utils.postfixWithEndpointName("switch_mode", msg, model, meta);
                        result[property] = Object.keys(stateSwitchMode).find((key) => stateSwitchMode[key] === msg.data.switchMode);
                    }
                    if (data.calibrationOpeningTime !== undefined) {
                        result.calibration_opening_time = msg.data.calibrationOpeningTime / 10;
                    }
                    if (data.calibrationClosingTime !== undefined) {
                        result.calibration_closing_time = msg.data.calibrationClosingTime / 10;
                    }
                    if (data.calibrationButtonHoldTime !== undefined) {
                        result.calibration_button_hold_time = msg.data.calibrationButtonHoldTime / 10;
                    }
                    if (data.calibrationMotorStartDelay !== undefined) {
                        result.calibration_motor_start_delay = msg.data.calibrationMotorStartDelay / 10;
                    }
                    if (data.childLock !== undefined) {
                        const property = utils.postfixWithEndpointName("child_lock", msg, model, meta);
                        result[property] = msg.data.childLock === 1 ? "ON" : "OFF";
                    }
                    if (data.motorState !== undefined) {
                        result.motor_state = Object.keys(stateMotor).find((key) => stateMotor[key] === msg.data.motorState);
                    }
                    if (data.autoOffEnabled !== undefined) {
                        const property = utils.postfixWithEndpointName("auto_off_enabled", msg, model, meta);
                        result[property] = msg.data.autoOffEnabled === 1 ? "ON" : "OFF";
                    }
                    if (data.autoOffTime !== undefined) {
                        const property = utils.postfixWithEndpointName("auto_off_time", msg, model, meta);
                        result[property] = msg.data.autoOffTime / 60;
                    }
                    return result;
                },
            },
        ];
        const toZigbee = [
            tz.power_on_behavior,
            tz.cover_position_tilt,
            {
                key: [
                    "device_mode",
                    "switch_type",
                    "switch_mode",
                    "child_lock",
                    "state",
                    "on_time",
                    "off_wait_time",
                    "auto_off_enabled",
                    "auto_off_time",
                ],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "state") {
                        if ("ID" in entity && entity.ID === 1) {
                            await tz.cover_state.convertSet(entity, key, value, meta);
                        }
                        else {
                            await tz.on_off.convertSet(entity, key, value, meta);
                        }
                    }
                    if (key === "on_time" || key === "on_wait_time") {
                        if ("ID" in entity && entity.ID !== 1) {
                            await tz.on_off.convertSet(entity, key, value, meta);
                        }
                    }
                    if (key === "device_mode") {
                        const index = utils.getFromLookup(value, stateDeviceMode);
                        await entity.write("boschEnergyDevice", { deviceMode: index });
                        await entity.read("boschEnergyDevice", ["deviceMode"]);
                        return { state: { device_mode: value } };
                    }
                    if (key === "switch_type") {
                        const applyDefaultForSwitchModeAndChildLock = async (endpoint) => {
                            const switchModeDefault = utils.getFromLookup("coupled", stateSwitchMode);
                            const childLockDefault = utils.getFromLookup("OFF", stateOffOn);
                            await endpoint.write("boschEnergyDevice", {
                                switchMode: switchModeDefault,
                                childLock: childLockDefault,
                            });
                            await endpoint.read("boschEnergyDevice", ["switchMode", "childLock"]);
                        };
                        const switchType = utils.getFromLookup(value, stateSwitchType);
                        await entity.write("boschEnergyDevice", { switchType: switchType });
                        await entity.read("boschEnergyDevice", ["switchType"]);
                        await applyDefaultForSwitchModeAndChildLock(entity);
                        const leftEndpoint = meta.device.getEndpoint(2);
                        await applyDefaultForSwitchModeAndChildLock(leftEndpoint);
                        const rightEndpoint = meta.device.getEndpoint(3);
                        await applyDefaultForSwitchModeAndChildLock(rightEndpoint);
                        return { state: { switch_type: value } };
                    }
                    if (key === "switch_mode") {
                        const index = utils.getFromLookup(value, stateSwitchMode);
                        await entity.write("boschEnergyDevice", { switchMode: index });
                        return { state: { switch_mode: value } };
                    }
                    if (key === "child_lock") {
                        const index = utils.getFromLookup(value, stateOffOn);
                        await entity.write("boschEnergyDevice", { childLock: index });
                        return { state: { child_lock: value } };
                    }
                    if (key === "auto_off_enabled") {
                        const index = utils.getFromLookup(value, stateOffOn);
                        await entity.write("boschEnergyDevice", { autoOffEnabled: index });
                        return { state: { auto_off_enabled: value } };
                    }
                    if (key === "auto_off_time" && typeof value === "number") {
                        await entity.write("boschEnergyDevice", { autoOffTime: value * 60 });
                        return { state: { auto_off_time: value } };
                    }
                },
                convertGet: async (entity, key, meta) => {
                    switch (key) {
                        case "state":
                        case "on_time":
                        case "off_wait_time":
                            if ("ID" in entity && entity.ID !== 1) {
                                await entity.read("genOnOff", ["onOff"]);
                            }
                            break;
                        case "device_mode":
                            await entity.read("boschEnergyDevice", ["deviceMode"]);
                            break;
                        case "switch_type":
                            await entity.read("boschEnergyDevice", ["switchType"]);
                            break;
                        case "switch_mode":
                            await entity.read("boschEnergyDevice", ["switchMode"]);
                            break;
                        case "child_lock":
                            await entity.read("boschEnergyDevice", ["childLock"]);
                            break;
                        case "auto_off_enabled":
                            await entity.read("boschEnergyDevice", ["autoOffEnabled"]);
                            break;
                        case "auto_off_time":
                            await entity.read("boschEnergyDevice", ["autoOffTime"]);
                            break;
                        default:
                            throw new Error(`Unhandled key boschExtend.bmct.toZigbee.convertGet ${key}`);
                    }
                },
            },
            {
                key: ["calibration_closing_time", "calibration_opening_time", "calibration_button_hold_time", "calibration_motor_start_delay"],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "calibration_opening_time") {
                        const number = utils.toNumber(value, "calibration_opening_time");
                        const index = number * 10;
                        await entity.write("boschEnergyDevice", { calibrationOpeningTime: index });
                        return { state: { calibration_opening_time: number } };
                    }
                    if (key === "calibration_closing_time") {
                        const number = utils.toNumber(value, "calibration_closing_time");
                        const index = number * 10;
                        await entity.write("boschEnergyDevice", { calibrationClosingTime: index });
                        return { state: { calibration_closing_time: number } };
                    }
                    if (key === "calibration_button_hold_time") {
                        const number = utils.toNumber(value, "calibration_button_hold_time");
                        const index = number * 10;
                        await entity.write("boschEnergyDevice", {
                            calibrationButtonHoldTime: index,
                        });
                        return { state: { calibration_button_hold_time: number } };
                    }
                    if (key === "calibration_motor_start_delay") {
                        const number = utils.toNumber(value, "calibration_motor_start_delay");
                        const index = number * 10;
                        await entity.write("boschEnergyDevice", {
                            calibrationMotorStartDelay: index,
                        });
                        return { state: { calibration_motor_start_delay: number } };
                    }
                },
                convertGet: async (entity, key, meta) => {
                    switch (key) {
                        case "calibration_opening_time":
                            await entity.read("boschEnergyDevice", ["calibrationOpeningTime"]);
                            break;
                        case "calibration_closing_time":
                            await entity.read("boschEnergyDevice", ["calibrationClosingTime"]);
                            break;
                        case "calibration_button_hold_time":
                            await entity.read("boschEnergyDevice", ["calibrationButtonHoldTime"]);
                            break;
                        case "calibration_motor_start_delay":
                            await entity.read("boschEnergyDevice", ["calibrationMotorStartDelay"]);
                            break;
                        default:
                            throw new Error(`Unhandled key boschExtend.bmct.toZigbee.convertGet ${key}`);
                    }
                },
            },
        ];
        return {
            fromZigbee,
            toZigbee,
            isModernExtend: true,
        };
    },
};
exports.boschBsirExtend = {
    customPowerCfgCluster: () => m.deviceAddCustomCluster("genPowerCfg", {
        ID: zigbee_herdsman_1.Zcl.Clusters.genPowerCfg.ID,
        attributes: {
            solarPanelVoltage: { ID: 0xa000, type: zigbee_herdsman_1.Zcl.DataType.UINT16, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            unknownAttribute: { ID: 0xa001, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            primaryPowerSource: { ID: 0xa002, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
        },
        commands: {},
        commandsResponse: {},
    }),
    customIasZoneCluster: () => m.deviceAddCustomCluster("ssIasZone", {
        ID: zigbee_herdsman_1.Zcl.Clusters.ssIasZone.ID,
        attributes: {
            currentPowerSource: { ID: 0xa001, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
        },
        commands: {
            acknowledgeStatusChange: {
                ID: 0xf3,
                parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.DataType.UINT8 }],
            },
        },
        commandsResponse: {},
    }),
    customIasWdCluster: () => m.deviceAddCustomCluster("ssIasWd", {
        ID: zigbee_herdsman_1.Zcl.Clusters.ssIasWd.ID,
        attributes: {
            sirenDuration: { ID: 0xa000, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            alarmMode: { ID: 0xa001, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            sirenVolume: { ID: 0xa002, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            sirenDelay: { ID: 0xa003, type: zigbee_herdsman_1.Zcl.DataType.UINT16, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            lightDelay: { ID: 0xa004, type: zigbee_herdsman_1.Zcl.DataType.UINT16, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            lightDuration: { ID: 0xa005, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            deviceState: { ID: 0xa006, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
        },
        commands: {
            alarmControl: {
                ID: 0xf0,
                parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.DataType.UINT8 }],
            },
        },
        commandsResponse: {},
    }),
    alarmControl: () => {
        const exposes = [
            e
                .enum("trigger_alarm", ea.SET, ["trigger"])
                .withLabel("Trigger alarm")
                .withDescription("Trigger an alarm on the device")
                .withCategory("config"),
            e
                .enum("stop_alarm", ea.SET, ["stop"])
                .withLabel("Stop alarm")
                .withDescription("Stop an active alarm on the device. Please keep in mind that the alarm stops automatically after the configured duration for the light and siren is expired.")
                .withCategory("config"),
        ];
        const toZigbee = [
            {
                key: ["trigger_alarm", "stop_alarm"],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "trigger_alarm") {
                        await entity.command("ssIasWd", "alarmControl", { data: 0x07 }, exports.manufacturerOptions);
                    }
                    if (key === "stop_alarm") {
                        await entity.command("ssIasWd", "alarmControl", { data: 0x00 }, exports.manufacturerOptions);
                    }
                },
            },
        ];
        const configure = [
            async (device, coordinatorEndpoint, definition) => {
                const endpoint = device.getEndpoint(1);
                await endpoint.bind("ssIasWd", coordinatorEndpoint);
            },
        ];
        return {
            exposes,
            toZigbee,
            configure,
            isModernExtend: true,
        };
    },
    deviceState: () => m.enumLookup({
        name: "device_state",
        cluster: "ssIasWd",
        attribute: "deviceState",
        description: "Current state of the siren and light. Please keep in mind that these activate after the specified delay time (except when using an external alarm trigger).",
        lookup: {
            siren_active_from_external_trigger: 0x05,
            light_active_from_external_trigger: 0x06,
            siren_and_light_active_from_external_trigger: 0x07,
            siren_active: 0x09,
            light_active: 0x0a,
            siren_and_light_active: 0x0b,
            idle: 0x00,
        },
        access: "STATE_GET",
    }),
    battery: () => m.battery({
        percentage: true,
        percentageReportingConfig: {
            min: "MIN",
            max: "MAX",
            change: 1,
        },
        lowStatus: true,
        lowStatusReportingConfig: {
            min: "MIN",
            max: "MAX",
            change: 0,
        },
    }),
    lightDelay: () => m.numeric({
        name: "light_delay",
        cluster: "ssIasWd",
        attribute: "lightDelay",
        description: "Delay of the light activation after an alarm is being triggered",
        valueMin: 0,
        valueMax: 180,
        valueStep: 1,
        unit: "sec",
        entityCategory: "config",
    }),
    sirenDelay: () => m.numeric({
        name: "siren_delay",
        cluster: "ssIasWd",
        attribute: "sirenDelay",
        description: "Delay of the siren activation after an alarm is being triggered",
        valueMin: 0,
        valueMax: 180,
        valueStep: 1,
        unit: "sec",
        entityCategory: "config",
    }),
    sirenDuration: () => m.numeric({
        name: "siren_duration",
        cluster: "ssIasWd",
        attribute: "sirenDuration",
        description: "Duration of the alarm siren",
        valueMin: 1,
        valueMax: 15,
        valueStep: 1,
        unit: "min",
        entityCategory: "config",
    }),
    lightDuration: () => m.numeric({
        name: "light_duration",
        cluster: "ssIasWd",
        attribute: "lightDuration",
        description: "Duration of the alarm light",
        valueMin: 1,
        valueMax: 15,
        valueStep: 1,
        unit: "min",
        entityCategory: "config",
    }),
    sirenVolume: () => m.enumLookup({
        name: "siren_volume",
        cluster: "ssIasWd",
        attribute: "sirenVolume",
        description: "Volume of the siren",
        lookup: {
            reduced: 0x01,
            medium: 0x02,
            loud: 0x03,
        },
        entityCategory: "config",
    }),
    alarmMode: () => m.enumLookup({
        name: "alarm_mode",
        cluster: "ssIasWd",
        attribute: "alarmMode",
        description: "Select if you only want a visual warning, an acoustic warning or both",
        lookup: {
            only_light: 0x00,
            only_siren: 0x01,
            siren_and_light: 0x02,
        },
        entityCategory: "config",
    }),
    primaryPowerSource: () => m.enumLookup({
        name: "primary_power_source",
        cluster: "genPowerCfg",
        attribute: "primaryPowerSource",
        description: "Select which power source you want to use. Note: The battery is always being used as backup source.",
        lookup: {
            solar_panel: 0x00,
            ac_power_supply: 0x01,
            dc_power_supply: 0x02,
        },
        reporting: { min: "MIN", max: "MAX", change: 1 },
        entityCategory: "config",
    }),
    iasZoneStatus: () => {
        const powerOutageLookup = {
            outage_detected: true,
            power_ok: false,
        };
        const exposes = [
            e
                .binary("external_trigger", ea.STATE, true, false)
                .withLabel("External trigger state")
                .withDescription("Indicates whether an external alarm via the 'TRIGGER_IN' connectors on the back of the device is being received. Please keep in mind that the device automatically activates/deactivates an alarm in that case."),
            e
                .binary("tamper", ea.STATE, true, false)
                .withLabel("Tamper state")
                .withDescription("Indicates whether the device is tampered")
                .withCategory("diagnostic"),
            e
                .binary("power_outage", ea.STATE, utils.getFromLookupByValue(true, powerOutageLookup), utils.getFromLookupByValue(false, powerOutageLookup))
                .withLabel("Power outage state")
                .withDescription("Indicates the configured primary power source experiences a power outage. This only works when using ac or dc power.")
                .withCategory("diagnostic"),
        ];
        const fromZigbee = [
            {
                cluster: "ssIasZone",
                type: ["commandStatusChangeNotification"],
                convert: (model, msg, publish, options, meta) => {
                    if (utils.hasAlreadyProcessedMessage(msg, model)) {
                        return;
                    }
                    const zoneStatus = msg.data.zonestatus;
                    const alarmOneStatus = (zoneStatus & 1) > 0;
                    const tamperStatus = (zoneStatus & (1 << 2)) > 0;
                    const alarmTwoStatus = (zoneStatus & (1 << 1)) > 0;
                    if (tamperStatus) {
                        meta.device
                            .getEndpoint(1)
                            .command("ssIasZone", "acknowledgeStatusChange", { data: 0x02 }, exports.manufacturerOptions)
                            .catch((e) => {
                            logger_1.logger.warning(`Acknowledgement of tamper status on device '${meta.device.ieeeAddr}' failed: ${e}`, NS);
                        });
                    }
                    if (alarmTwoStatus) {
                        meta.device
                            .getEndpoint(1)
                            .command("ssIasZone", "acknowledgeStatusChange", { data: 0x04 }, exports.manufacturerOptions)
                            .catch((e) => {
                            logger_1.logger.warning(`Acknowledgement of alarm 2 status on device '${meta.device.ieeeAddr}' failed: ${e}`, NS);
                        });
                    }
                    return {
                        external_trigger: alarmOneStatus,
                        tamper: tamperStatus,
                        power_outage: utils.getFromLookupByValue(alarmTwoStatus, powerOutageLookup),
                    };
                },
            },
        ];
        const configure = [
            async (device, coordinatorEndpoint, definition) => {
                const endpoint = device.getEndpoint(1);
                await endpoint.read("ssIasZone", ["zoneStatus"]);
            },
        ];
        return {
            exposes,
            fromZigbee,
            configure,
            isModernExtend: true,
        };
    },
    currentPowerSource: () => m.enumLookup({
        name: "current_power_source",
        cluster: "ssIasZone",
        attribute: "currentPowerSource",
        description: "Currently used power source for device operation",
        lookup: {
            battery: 0x00,
            solar_panel: 0x01,
            ac_power: 0x02,
            dc_power: 0x03,
        },
        reporting: { min: "MIN", max: "MAX", change: 1 },
        access: "STATE_GET",
        entityCategory: "diagnostic",
    }),
    solarPanelVoltage: () => {
        const exposes = [
            e
                .numeric("solar_panel_voltage", ea.STATE)
                .withDescription("Current voltage level received from the integrated solar panel")
                .withUnit("volt")
                .withCategory("diagnostic"),
        ];
        const fromZigbee = [
            {
                cluster: "genPowerCfg",
                type: ["attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    if (utils.hasAlreadyProcessedMessage(msg, model)) {
                        return;
                    }
                    const data = msg.data;
                    const containsSolarPanelVoltage = data.solarPanelVoltage !== undefined;
                    if (containsSolarPanelVoltage) {
                        const currentSolarPanelVoltage = data.solarPanelVoltage / 10;
                        return { solar_panel_voltage: currentSolarPanelVoltage };
                    }
                },
            },
        ];
        const configure = [
            async (device, coordinatorEndpoint, definition) => {
                const endpoint = device.getEndpoint(1);
                const solarPanelVoltageReportingPayload = (0, reporting_1.payload)("solarPanelVoltage", constants_1.repInterval.MINUTES_5, constants_1.repInterval.MAX, 1);
                await endpoint.configureReporting("genPowerCfg", solarPanelVoltageReportingPayload);
            },
        ];
        return { exposes, fromZigbee, configure, isModernExtend: true };
    },
};
exports.boschDoorWindowContactExtend = {
    doorWindowContactCluster: () => m.deviceAddCustomCluster("boschDoorWindowContactCluster", {
        ID: 0xfcad,
        attributes: {
            breakFunctionEnabled: { ID: 0x0000, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            breakFunctionState: { ID: 0x0001, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            breakFunctionTimeout: { ID: 0x0002, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            vibrationDetectionEnabled: { ID: 0x0004, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            vibrationDetectionSensitivity: { ID: 0x0005, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            unknownOne: { ID: 0x0007, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            unknownTwo: { ID: 0x0008, type: zigbee_herdsman_1.Zcl.DataType.UINT16, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            unknownThree: { ID: 0x0009, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
            unknownFour: { ID: 0x000a, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: exports.manufacturerOptions.manufacturerCode },
        },
        commands: {},
        commandsResponse: {},
    }),
    battery: () => m.battery({
        percentage: true,
        lowStatus: true,
        lowStatusReportingConfig: { min: "MIN", max: "MAX", change: 0 },
    }),
    reportContactState: () => m.iasZoneAlarm({
        zoneType: "contact",
        zoneAttributes: ["alarm_1"],
        description: "Indicates whether the device detected an open or closed door/window",
    }),
    reportButtonActions: (args) => {
        const { doublePressSupported } = args ?? { doublePressSupported: false };
        let buttonActionsLookup = {
            long_press: 0x02,
            single_press: 0x01,
            none: 0x00,
        };
        if (doublePressSupported) {
            buttonActionsLookup = { ...{ double_press: 0x08 }, ...buttonActionsLookup };
        }
        const exposes = [
            e
                .enum("action", ea.STATE, Object.keys(buttonActionsLookup))
                .withDescription("Indicates button presses on the device")
                .withCategory("diagnostic"),
        ];
        const fromZigbee = [
            {
                cluster: "ssIasZone",
                type: ["commandStatusChangeNotification", "attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const zoneStatus = "zonestatus" in msg.data ? msg.data.zonestatus : msg.data.zoneStatus;
                    if (zoneStatus !== undefined) {
                        const buttonPayload = zoneStatus >> 11;
                        const buttonState = utils.getFromLookupByValue(buttonPayload, buttonActionsLookup);
                        const result = {
                            action: buttonState,
                        };
                        return result;
                    }
                },
            },
        ];
        const configure = [m.setupConfigureForBinding("ssIasZone", "input"), m.setupConfigureForReading("ssIasZone", ["zoneStatus"])];
        return {
            exposes,
            fromZigbee,
            configure,
            isModernExtend: true,
        };
    },
    breakFunctionality: () => {
        const breakFunctionEnabledLookup = {
            ON: 0x01,
            OFF: 0x00,
        };
        const breakFunctionStatusLookup = {
            break_active: 0x01,
            idle: 0x00,
        };
        const exposes = [
            e
                .binary("break_function_enabled", ea.ALL, utils.getFromLookupByValue(0x01, breakFunctionEnabledLookup), utils.getFromLookupByValue(0x00, breakFunctionEnabledLookup))
                .withLabel("Break function")
                .withDescription("Activate the break function by pressing the operating button on the door/window contact twice. This means that the device temporarily stops reading the sensors.")
                .withCategory("config"),
            e
                .numeric("break_function_timeout", ea.ALL)
                .withLabel("Automatic time limit for breaks")
                .withDescription("Here you can define how long the break function is activated for the door/window contact. Once the time limit has expired, the break ends automatically. The LED on the device will flash orange as long as the break is activated when this setting is being used.")
                .withValueMin(1)
                .withValueMax(15)
                .withUnit("minutes")
                .withPreset("disable", null, "Disable automatic time limit")
                .withCategory("config"),
            e
                .enum("break_function_state", ea.STATE_GET, Object.keys(breakFunctionStatusLookup))
                .withLabel("Break function state")
                .withDescription("Indicates whether the device is in break mode or not"),
        ];
        const fromZigbee = [
            {
                cluster: "boschDoorWindowContactCluster",
                type: ["attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const result = {};
                    const data = msg.data;
                    if (data.breakFunctionEnabled !== undefined) {
                        result.break_function_enabled = utils.getFromLookupByValue(data.breakFunctionEnabled, breakFunctionEnabledLookup);
                    }
                    if (data.breakFunctionTimeout !== undefined) {
                        result.break_function_timeout = data.breakFunctionTimeout === 0xff ? null : data.breakFunctionTimeout;
                    }
                    if (data.breakFunctionState !== undefined) {
                        result.break_function_state = utils.getFromLookupByValue(data.breakFunctionState, breakFunctionStatusLookup);
                    }
                    return result;
                },
            },
        ];
        const toZigbee = [
            {
                key: ["break_function_enabled", "break_function_timeout", "break_function_state"],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "break_function_enabled") {
                        await entity.write("boschDoorWindowContactCluster", {
                            breakFunctionEnabled: utils.getFromLookup(value, breakFunctionEnabledLookup),
                        });
                        return { state: { break_function_enabled: value } };
                    }
                    if (key === "break_function_timeout") {
                        const index = value === null ? 0xff : utils.toNumber(value);
                        await entity.write("boschDoorWindowContactCluster", {
                            breakFunctionTimeout: index,
                        });
                        return { state: { break_function_timeout: value } };
                    }
                },
                convertGet: async (entity, key, meta) => {
                    if (key === "break_function_enabled") {
                        await entity.read("boschDoorWindowContactCluster", [
                            "breakFunctionEnabled",
                        ]);
                    }
                    if (key === "break_function_timeout") {
                        await entity.read("boschDoorWindowContactCluster", [
                            "breakFunctionTimeout",
                        ]);
                    }
                    if (key === "break_function_state") {
                        await entity.read("boschDoorWindowContactCluster", [
                            "breakFunctionState",
                        ]);
                    }
                },
            },
        ];
        const configure = [
            m.setupConfigureForReading("boschDoorWindowContactCluster", [
                "breakFunctionEnabled",
                "breakFunctionTimeout",
                "breakFunctionState",
            ]),
        ];
        return {
            exposes,
            fromZigbee,
            toZigbee,
            configure,
            isModernExtend: true,
        };
    },
    vibrationDetection: () => {
        const vibrationDetectionEnabledLookup = {
            ON: 0x01,
            OFF: 0x00,
        };
        const vibrationDetectionSensitivityLookup = {
            very_high: 0x05,
            high: 0x04,
            medium: 0x03,
            moderate: 0x02,
            low: 0x01,
        };
        const exposes = [
            e
                .binary("vibration_detection_enabled", ea.ALL, utils.getFromLookupByValue(0x01, vibrationDetectionEnabledLookup), utils.getFromLookupByValue(0x00, vibrationDetectionEnabledLookup))
                .withLabel("Vibration detection")
                .withDescription("Activate the vibration detection to detect vibrations at the window or door via the integrated sensor as well")
                .withCategory("config"),
            e
                .enum("vibration_detection_sensitivity", ea.ALL, Object.keys(vibrationDetectionSensitivityLookup))
                .withLabel("Vibration detection sensitivity")
                .withDescription("Set the sensitivity of the vibration detection sensor")
                .withCategory("config"),
            e.binary("vibration", ea.STATE_GET, true, false).withDescription("Indicates whether the device detected vibration"),
        ];
        const fromZigbee = [
            {
                cluster: "boschDoorWindowContactCluster",
                type: ["attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const result = {};
                    const data = msg.data;
                    if (data.vibrationDetectionEnabled !== undefined) {
                        result.vibration_detection_enabled = utils.getFromLookupByValue(data.vibrationDetectionEnabled, vibrationDetectionEnabledLookup);
                    }
                    if (data.vibrationDetectionSensitivity !== undefined) {
                        result.vibration_detection_sensitivity = utils.getFromLookupByValue(data.vibrationDetectionSensitivity, vibrationDetectionSensitivityLookup);
                    }
                    return result;
                },
            },
            {
                cluster: "ssIasZone",
                type: ["commandStatusChangeNotification", "attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const zoneStatus = "zonestatus" in msg.data ? msg.data.zonestatus : msg.data.zoneStatus;
                    if (zoneStatus !== undefined) {
                        const alarm2Payload = (zoneStatus & (1 << 1)) > 0;
                        return {
                            vibration: alarm2Payload,
                        };
                    }
                },
            },
        ];
        const toZigbee = [
            {
                key: ["vibration_detection_enabled", "vibration_detection_sensitivity", "vibration"],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "vibration_detection_enabled") {
                        await entity.write("boschDoorWindowContactCluster", {
                            vibrationDetectionEnabled: utils.getFromLookup(value, vibrationDetectionEnabledLookup),
                        });
                        return { state: { vibration_detection_enabled: value } };
                    }
                    if (key === "vibration_detection_sensitivity") {
                        await entity.write("boschDoorWindowContactCluster", {
                            vibrationDetectionSensitivity: utils.getFromLookup(value, vibrationDetectionSensitivityLookup),
                        });
                        return { state: { vibration_detection_sensitivity: value } };
                    }
                },
                convertGet: async (entity, key, meta) => {
                    if (key === "vibration_detection_enabled") {
                        await entity.read("boschDoorWindowContactCluster", [
                            "vibrationDetectionEnabled",
                        ]);
                    }
                    if (key === "vibration_detection_sensitivity") {
                        await entity.read("boschDoorWindowContactCluster", [
                            "vibrationDetectionSensitivity",
                        ]);
                    }
                    if (key === "vibration") {
                        await entity.read("ssIasZone", ["zoneStatus"]);
                    }
                },
            },
        ];
        const configure = [
            m.setupConfigureForBinding("ssIasZone", "input"),
            m.setupConfigureForReading("ssIasZone", ["zoneStatus"]),
            async (device, coordinatorEndpoint, definition) => {
                const endpoint = device.getEndpoint(1);
                // The write request is made when using the proprietary
                // Bosch Smart Home Controller II as of 19-09-2025. Looks like
                // the default value was too high, and they didn't want to
                // push a firmware update. We mimic it here to avoid complaints.
                await endpoint.write("boschDoorWindowContactCluster", {
                    vibrationDetectionSensitivity: vibrationDetectionSensitivityLookup.medium,
                });
                // The write request is made when using the proprietary
                // Bosch Smart Home Controller II as of 19-09-2025. I have
                // no idea what it does, but we mimic it here in case it
                // fixes any issues.
                await endpoint.write("boschDoorWindowContactCluster", {
                    unknownOne: 0x00,
                });
            },
            m.setupConfigureForReading("boschDoorWindowContactCluster", [
                "vibrationDetectionEnabled",
                "vibrationDetectionSensitivity",
            ]),
        ];
        return {
            exposes,
            fromZigbee,
            toZigbee,
            configure,
            isModernExtend: true,
        };
    },
};
exports.boschBsenExtend = {
    customIasZoneCluster: () => m.deviceAddCustomCluster("ssIasZone", {
        ID: zigbee_herdsman_1.Zcl.Clusters.ssIasZone.ID,
        attributes: {},
        commands: {
            initCustomTestMode: {
                ID: 0x02,
                parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.LIST_UINT8 }],
            },
        },
        commandsResponse: {},
    }),
    battery: () => m.battery({
        percentage: false,
        percentageReporting: false,
        voltage: true,
        voltageReporting: true,
        voltageToPercentage: { min: 2500, max: 3000 },
        lowStatus: true,
        lowStatusReportingConfig: { min: "MIN", max: "MAX", change: 0 },
    }),
    illuminance: () => m.illuminance({ reporting: { min: "1_SECOND", max: 600, change: 3522 } }),
    // The temperature sensor isn't used at all by Bosch on the BSEN-M.
    // Therefore, I decided to be a bit conservative with the reporting
    // intervals to not drain the battery too much.
    temperature: () => m.temperature({ reporting: { min: "5_MINUTES", max: "MAX", change: 100 } }),
    tamperAndOccupancyAlarm: () => {
        const exposes = [
            e
                .binary("tamper", ea.STATE, true, false)
                .withLabel("Tamper state")
                .withDescription("Indicates whether the device is tampered")
                .withCategory("diagnostic"),
            e
                .binary("occupancy", ea.STATE, true, false)
                .withLabel("Occupancy state")
                .withDescription("Indicates whether the device detected any motion in the surroundings"),
        ];
        const fromZigbee = [
            {
                cluster: "ssIasZone",
                type: ["commandStatusChangeNotification", "attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const zoneStatus = "zonestatus" in msg.data ? msg.data.zonestatus : msg.data.zoneStatus;
                    if (zoneStatus === undefined) {
                        return;
                    }
                    let payload = {};
                    const tamperStatus = (zoneStatus & (1 << 2)) > 0;
                    payload = { tamper: tamperStatus, ...payload };
                    const occupancyLockActive = meta.device.meta.occupancyLockTimeout ? meta.device.meta.occupancyLockTimeout > Date.now() : false;
                    if (!occupancyLockActive) {
                        const alarmOneStatus = (zoneStatus & 1) > 0;
                        payload = { occupancy: alarmOneStatus, ...payload };
                        const isChangeMessage = msg.type === "commandStatusChangeNotification";
                        const newOccupancyStatusDetected = alarmOneStatus === true;
                        if (isChangeMessage && newOccupancyStatusDetected) {
                            // After a detection, the device turns off the motion detection for 3 minutes.
                            // Unfortunately, the alarm is already turned off after 4 seconds for reasons
                            // only known to Bosch. Therefore, we have to manually defer the turn-off by
                            // 4 seconds + 3 minutes to avoid any confusion.
                            const timeoutDelay = 184 * 1000;
                            setTimeout(() => publish({ occupancy: false }), timeoutDelay);
                            meta.device.meta.occupancyLockTimeout = Date.now() + timeoutDelay;
                        }
                    }
                    return payload;
                },
            },
        ];
        const configure = [m.setupConfigureForBinding("ssIasZone", "input"), m.setupConfigureForReading("ssIasZone", ["zoneStatus"])];
        const onEvent = [
            async (event) => {
                if (event.type !== "start") {
                    return;
                }
                const occupancyLockTimeout = event.data.device.meta.occupancyLockTimeout;
                if (occupancyLockTimeout === undefined) {
                    return;
                }
                const currentTime = Date.now();
                const endpoint = event.data.device.getEndpoint(1);
                if (occupancyLockTimeout > currentTime) {
                    const timeoutDelay = occupancyLockTimeout - currentTime;
                    setTimeout(() => {
                        endpoint.read("ssIasZone", ["zoneStatus"]).catch((exception) => {
                            logger_1.logger.warning(`Error during reading the zoneStatus on device '${event.data.device.ieeeAddr}': ${exception}`, NS);
                        });
                    }, timeoutDelay);
                }
                else {
                    await endpoint.read("ssIasZone", ["zoneStatus"]);
                }
            },
        ];
        return {
            exposes,
            fromZigbee,
            configure,
            onEvent,
            isModernExtend: true,
        };
    },
    sensitivityLevel: () => {
        const sensitivityLevelLookup = {
            pet_immunity: 0xb8,
            sneak_by_guard: 0xb0,
            unknown: 0x00,
        };
        const exposes = [
            e
                .enum("sensitivity_level", ea.STATE_GET, Object.keys(sensitivityLevelLookup))
                .withDescription("Specifies the selected sensitivity level on the back of the device (either 'pet immunity' or 'sneak-by guard').")
                .withCategory("diagnostic"),
        ];
        const fromZigbee = [
            {
                cluster: "ssIasZone",
                type: ["attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const result = {};
                    const data = msg.data;
                    if (data.currentZoneSensitivityLevel !== undefined) {
                        result.sensitivity_level = utils.getFromLookupByValue(data.currentZoneSensitivityLevel, sensitivityLevelLookup, "unknown");
                    }
                    return result;
                },
            },
        ];
        const toZigbee = [
            {
                key: ["sensitivity_level"],
                convertGet: async (entity, key, meta) => {
                    await entity.read("ssIasZone", ["currentZoneSensitivityLevel"]);
                },
            },
        ];
        const configure = [
            m.setupConfigureForBinding("ssIasZone", "input"),
            m.setupConfigureForReading("ssIasZone", ["numZoneSensitivityLevelsSupported", "currentZoneSensitivityLevel"]),
            async (device, coordinatorEndpoint, definition) => {
                const endpoint = device.getEndpoint(1);
                // The write request is made when using the proprietary
                // Bosch Smart Home Controller II as of 15-09-2025. Looks like
                // the default value was too low, and they didn't want to
                // push a firmware update. We mimic it here to avoid complaints.
                await endpoint.write("ssIasZone", { currentZoneSensitivityLevel: 176 });
            },
        ];
        return {
            exposes,
            fromZigbee,
            toZigbee,
            configure,
            isModernExtend: true,
        };
    },
    changedCheckinInterval: () => {
        const configure = [
            m.setupConfigureForReading("genPollCtrl", ["checkinInterval", "longPollInterval", "shortPollInterval"]),
            async (device, coordinatorEndpoint, definition) => {
                const endpoint = device.getEndpoint(1);
                // The write request is made when using the proprietary
                // Bosch Smart Home Controller II as of 15-09-2025.
                // The reason is unclear to me, but we mimic it here
                // to avoid possible complaints in case it fixed any issues.
                await endpoint.write("genPollCtrl", { checkinInterval: 2160 });
            },
        ];
        return {
            configure,
            isModernExtend: true,
        };
    },
    testMode: () => {
        const testModeLookup = {
            ON: true,
            OFF: false,
        };
        const enableTestMode = async (endpoint) => {
            await endpoint.command("ssIasZone", "initCustomTestMode", {
                data: [0x00, 0x80],
            });
        };
        const disableTestMode = async (endpoint) => {
            await endpoint.command("ssIasZone", "initNormalOpMode", {});
        };
        const exposes = [
            e
                .binary("test_mode", ea.ALL, utils.getFromLookupByValue(true, testModeLookup), utils.getFromLookupByValue(false, testModeLookup))
                .withDescription("Activate the test mode. In this mode, the device blinks on every detected motion without any wait time in between to verify the installation. Please keep in mind that it can take up to 45 seconds for the test mode to be activated.")
                .withCategory("config"),
        ];
        const fromZigbee = [
            {
                cluster: "ssIasZone",
                type: ["commandStatusChangeNotification", "attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const zoneStatus = "zonestatus" in msg.data ? msg.data.zonestatus : msg.data.zoneStatus;
                    if (zoneStatus === undefined) {
                        return;
                    }
                    const result = {};
                    const testModeEnabled = (zoneStatus & (1 << 8)) > 0;
                    result.test_mode = utils.getFromLookupByValue(testModeEnabled, testModeLookup);
                    return result;
                },
            },
        ];
        const toZigbee = [
            {
                key: ["test_mode"],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "test_mode") {
                        if (value === utils.getFromLookupByValue(true, testModeLookup)) {
                            await enableTestMode(entity);
                        }
                        else {
                            await disableTestMode(entity);
                        }
                    }
                },
                convertGet: async (entity, key, meta) => {
                    await entity.read("ssIasZone", ["zoneStatus"]);
                },
            },
        ];
        const configure = [m.setupConfigureForBinding("ssIasZone", "input"), m.setupConfigureForReading("ssIasZone", ["zoneStatus"])];
        return {
            exposes,
            fromZigbee,
            toZigbee,
            configure,
            isModernExtend: true,
        };
    },
};
exports.boschSmartPlugExtend = {
    smartPlugCluster: () => m.deviceAddCustomCluster("boschEnergyDevice", {
        ID: 0xfca0,
        manufacturerCode: exports.manufacturerOptions.manufacturerCode,
        attributes: {
            autoOffEnabled: { ID: 0x0006, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN },
            autoOffTime: { ID: 0x0007, type: zigbee_herdsman_1.Zcl.DataType.UINT16 },
            ledBrightness: { ID: 0x002c, type: zigbee_herdsman_1.Zcl.DataType.UINT8 },
            energySavingModeEnabled: { ID: 0x002d, type: zigbee_herdsman_1.Zcl.DataType.BOOLEAN },
            energySavingModeThreshold: { ID: 0x002e, type: zigbee_herdsman_1.Zcl.DataType.UINT16 },
            energySavingModeTimer: { ID: 0x002f, type: zigbee_herdsman_1.Zcl.DataType.UINT32 },
        },
        commands: {},
        commandsResponse: {},
    }),
    onOff: () => m.onOff({ powerOnBehavior: true, configureReporting: true }),
    ledBrightness: () => m.numeric({
        name: "led_brightness",
        cluster: "boschEnergyDevice",
        attribute: "ledBrightness",
        label: "LED brightness",
        description: "Here you can adjust the LED brightness",
        valueMin: 0,
        valueMax: 100,
        valueStep: 1,
        unit: "%",
        entityCategory: "config",
    }),
    energySavingMode: () => {
        const energySavingModeEnabledLookup = {
            ON: 0x01,
            OFF: 0x00,
        };
        const exposes = [
            e
                .binary("energy_saving_mode_enabled", ea.ALL, utils.getFromLookupByValue(0x01, energySavingModeEnabledLookup), utils.getFromLookupByValue(0x00, energySavingModeEnabledLookup))
                .withLabel("Enable energy-saving mode")
                .withDescription("Here you can enable/disable the energy-saving mode")
                .withCategory("config"),
            e
                .numeric("energy_saving_mode_threshold", ea.ALL)
                .withLabel("Energy-saving threshold")
                .withDescription("Here you can set the threshold for the energy-saving mode. If the consumption falls below the set value (and the timer has been met), the smart plug will be turned off.")
                .withUnit("watt")
                .withValueMin(1)
                .withValueMax(50)
                .withValueStep(1)
                .withCategory("config"),
            e
                .numeric("energy_saving_mode_timer", ea.ALL)
                .withLabel("Energy-saving timer")
                .withDescription("Here you can set the time the threshold has to be met before the smart plug is turned off")
                .withUnit("seconds")
                .withValueMin(1)
                .withValueMax(1800)
                .withValueStep(1)
                .withCategory("config"),
        ];
        const fromZigbee = [
            {
                cluster: "boschEnergyDevice",
                type: ["attributeReport", "readResponse"],
                convert: (model, msg, publish, options, meta) => {
                    const result = {};
                    const data = msg.data;
                    if (data.energySavingModeEnabled !== undefined) {
                        result.energy_saving_mode_enabled = utils.getFromLookupByValue(data.energySavingModeEnabled, energySavingModeEnabledLookup);
                    }
                    if (data.energySavingModeThreshold !== undefined) {
                        result.energy_saving_mode_threshold = utils.toNumber(data.energySavingModeThreshold) / 10;
                    }
                    if (data.energySavingModeTimer !== undefined) {
                        result.energy_saving_mode_timer = utils.toNumber(data.energySavingModeTimer);
                    }
                    return result;
                },
            },
        ];
        const toZigbee = [
            {
                key: ["energy_saving_mode_enabled", "energy_saving_mode_threshold", "energy_saving_mode_timer"],
                convertSet: async (entity, key, value, meta) => {
                    if (key === "energy_saving_mode_enabled") {
                        await entity.write("boschEnergyDevice", {
                            energySavingModeEnabled: utils.getFromLookup(value, energySavingModeEnabledLookup),
                        });
                        return { state: { energy_saving_mode_enabled: value } };
                    }
                    if (key === "energy_saving_mode_threshold") {
                        await entity.write("boschEnergyDevice", {
                            energySavingModeThreshold: utils.toNumber(value) * 10,
                        });
                        return { state: { energy_saving_mode_threshold: value } };
                    }
                    if (key === "energy_saving_mode_timer") {
                        await entity.write("boschEnergyDevice", {
                            energySavingModeTimer: utils.toNumber(value),
                        });
                        return { state: { energy_saving_mode_timer: value } };
                    }
                },
                convertGet: async (entity, key, meta) => {
                    if (key === "energy_saving_mode_enabled") {
                        await entity.read("boschEnergyDevice", ["energySavingModeEnabled"]);
                    }
                    if (key === "energy_saving_mode_threshold") {
                        await entity.read("boschEnergyDevice", ["energySavingModeThreshold"]);
                    }
                    if (key === "energy_saving_mode_timer") {
                        await entity.read("boschEnergyDevice", ["energySavingModeTimer"]);
                    }
                },
            },
        ];
        const configure = [
            m.setupConfigureForBinding("boschEnergyDevice", "input"),
            m.setupConfigureForReading("boschEnergyDevice", [
                "energySavingModeEnabled",
                "energySavingModeThreshold",
                "energySavingModeTimer",
            ]),
        ];
        return {
            exposes,
            fromZigbee,
            toZigbee,
            configure,
            isModernExtend: true,
        };
    },
    electricityMeter: (args) => m.electricityMeter({
        voltage: false,
        current: false,
        power: { change: 1 },
        energy: { change: 1 },
        ...args,
    }),
};
//endregion
//# sourceMappingURL=bosch.js.map