UNPKG

zigbee-herdsman-converters

Version:

Collection of device converters to be used with zigbee-herdsman

1,133 lines • 99.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.definitions = void 0; const zigbee_herdsman_1 = require("zigbee-herdsman"); const fz = __importStar(require("../converters/fromZigbee")); const tz = __importStar(require("../converters/toZigbee")); const constants = __importStar(require("../lib/constants")); const exposes = __importStar(require("../lib/exposes")); const m = __importStar(require("../lib/modernExtend")); const reporting = __importStar(require("../lib/reporting")); const utils = __importStar(require("../lib/utils")); const utils_1 = require("../lib/utils"); const e = exposes.presets; const ea = exposes.access; function indicatorMode(endpoint) { let description = "Set Indicator Mode."; if (endpoint) { description = `Set Indicator Mode for ${endpoint} switch.`; } return m.enumLookup({ name: "indicator_mode", lookup: { reverse_with_load: 2, consistent_with_load: 0, always_off: 3, always_on: 1, }, cluster: "manuSpecificSchneiderLightSwitchConfiguration", attribute: "ledIndication", description: description, endpointName: endpoint, }); } function socketIndicatorMode() { return m.enumLookup({ name: "indicator_mode", lookup: { reverse_with_load: 0, consistent_with_load: 1, always_off: 2, always_on: 3, }, cluster: "manuSpecificSchneiderFanSwitchConfiguration", attribute: "ledIndication", description: "Set indicator mode", }); } function fanIndicatorMode() { const description = "Set Indicator Mode."; return m.enumLookup({ name: "indicator_mode", lookup: { always_on: 3, on_with_timeout_but_as_locator: 4, on_with_timeout: 5, }, cluster: "manuSpecificSchneiderFanSwitchConfiguration", attribute: "ledIndication", description: description, }); } function fanIndicatorOrientation() { const description = "Set Indicator Orientation."; return m.enumLookup({ name: "indicator_orientation", lookup: { horizontal_left: 2, horizontal_right: 0, vertical_top: 3, vertical_bottom: 1, }, cluster: "manuSpecificSchneiderFanSwitchConfiguration", attribute: "ledOrientation", description: description, }); } function switchActions(endpoint) { let description = "Set Switch Action."; if (endpoint) { description = `Set Switch Action for ${endpoint} Button.`; } return m.enumLookup({ name: "switch_actions", lookup: { light: 0, light_opposite: 254, dimmer: 1, dimmer_opposite: 253, standard_shutter: 2, standard_shutter_opposite: 252, schneider_shutter: 3, schneider_shutter_opposite: 251, scene: 4, toggle_light: 5, toggle_dimmer: 6, alternate_light: 7, alternate_dimmer: 8, not_used: 127, }, cluster: "manuSpecificSchneiderLightSwitchConfiguration", attribute: "switchActions", description: description, endpointName: endpoint, }); } const schneiderElectricExtend = { addVisaConfigurationCluster: (enumDataType) => m.deviceAddCustomCluster("visaConfiguration", { ID: 0xfc04, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, attributes: { indicatorLuminanceLevel: { ID: 0x0000, type: enumDataType }, indicatorColor: { ID: 0x0001, type: enumDataType }, indicatorMode: { ID: 0x0002, type: enumDataType }, motorTypeChannel1: { ID: 0x0003, type: zigbee_herdsman_1.Zcl.DataType.UINT8 }, motorTypeChannel2: { ID: 0x0004, type: zigbee_herdsman_1.Zcl.DataType.UINT8 }, curtainStatusChannel1: { ID: 0x0005, type: zigbee_herdsman_1.Zcl.DataType.UINT8 }, curtainStatusChannel2: { ID: 0x0006, type: zigbee_herdsman_1.Zcl.DataType.UINT8 }, key1EventNotification: { ID: 0x0020, type: zigbee_herdsman_1.Zcl.DataType.UINT8 }, key2EventNotification: { ID: 0x0021, type: zigbee_herdsman_1.Zcl.DataType.UINT8 }, key3EventNotification: { ID: 0x0022, type: zigbee_herdsman_1.Zcl.DataType.UINT8 }, key4EventNotification: { ID: 0x0023, type: zigbee_herdsman_1.Zcl.DataType.UINT8 }, }, commands: {}, commandsResponse: {}, }), visaConfigIndicatorLuminanceLevel: () => { return m.enumLookup({ name: "indicator_luminance_level", lookup: { "100": 0, "80": 1, "60": 2, "40": 3, "20": 4, "0": 5, }, cluster: "visaConfiguration", attribute: "indicatorLuminanceLevel", description: "Set indicator luminance Level", }); }, visaConfigIndicatorColor: () => { return m.enumLookup({ name: "indicator_color", lookup: { white: 0, blue: 1, }, cluster: "visaConfiguration", attribute: "indicatorColor", description: "Set indicator color", }); }, visaIndicatorMode: ([reverseWithLoad, consistentWithLoad, alwaysOff, alwaysOn]) => { return m.enumLookup({ name: "indicator_mode", lookup: { reverse_with_load: reverseWithLoad, consistent_with_load: consistentWithLoad, always_off: alwaysOff, always_on: alwaysOn, }, cluster: "visaConfiguration", attribute: "indicatorMode", description: "Set indicator mode for switch", }); }, visaConfigMotorType: (channel) => { const attribute = `motorTypeChannel${channel || ""}`; const description = `Set motor type for channel ${channel || ""}`; return m.enumLookup({ name: `motor_type${channel ? `_${channel}` : ""}`, lookup: { ac_motor: 0, pulse_motor: 1, }, cluster: "visaConfiguration", attribute: attribute, description: description, }); }, visaConfigCurtainStatus: (channel) => { const attribute = `curtainStatusChannel${channel || ""}`; const description = `Set curtain status for channel ${channel}`; return m.enumLookup({ access: "STATE", name: `curtain_status${channel ? `_${channel}` : ""}`, lookup: { stop: 0, opening: 1, closing: 2, }, cluster: "visaConfiguration", attribute: attribute, description: description, }); }, visaWiserCurtain: (endpointNames) => { return { isModernExtend: true, fromZigbee: [ { cluster: "genLevelCtrl", type: ["attributeReport", "readResponse"], convert: (model, msg, publish, options, meta) => { const onOffTransitionTime = Number(msg.data.onOffTransitionTime) / 10; const currentLevel = utils.mapNumberRange(Number(msg.data.currentLevel), 0, 255, 0, 100); const transition = (0, utils_1.postfixWithEndpointName)("transition", msg, model, meta); const position = (0, utils_1.postfixWithEndpointName)("position", msg, model, meta); return { [transition]: onOffTransitionTime, [position]: currentLevel, }; }, }, ], toZigbee: [ { key: ["transition", "position"], convertGet: async (entity, key, meta) => { await entity.read("genLevelCtrl", ["onOffTransitionTime", "currentLevel"]); }, convertSet: async (entity, key, value, meta) => { if (key === "transition") { await entity.write("genLevelCtrl", { onOffTransitionTime: +value * 10 }, utils.getOptions(meta.mapped, entity)); } else if (key === "position") { await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: utils.mapNumberRange(Number(value), 0, 100, 0, 255), transtime: 0 }, utils.getOptions(meta.mapped, entity)); } }, }, { key: ["state"], convertSet: async (entity, key, value, meta) => { if (value === "OPEN") { await entity.command("genOnOff", "on", {}, utils.getOptions(meta.mapped, entity)); } else if (value === "CLOSE") { await entity.command("genOnOff", "off", {}, utils.getOptions(meta.mapped, entity)); } else if (value === "STOP") { await entity.command("genLevelCtrl", "stop", {}, utils.getOptions(meta.mapped, entity)); } }, }, ], exposes: [ ...endpointNames.map((endpointName) => e.enum("state", ea.SET, ["OPEN", "CLOSE", "STOP"]).withDescription("State of the curtain").withEndpoint(endpointName)), ...endpointNames.map((endpointName) => e .numeric("position", ea.ALL) .withValueMin(0) .withValueMax(100) .withUnit("%") .withDescription("Position of the curtain") .withEndpoint(endpointName)), ...endpointNames.map((endpointName) => e .numeric("transition", ea.ALL) .withValueMin(0) .withValueMax(300) .withUnit("s") .withDescription("Transition time in seconds") .withEndpoint(endpointName)), ], }; }, visaKeyEventNotification: (key) => { return { isModernExtend: true, fromZigbee: [ { cluster: "visaConfiguration", type: ["attributeReport"], convert: (model, msg, publish, options, meta) => { return { [`key${key}_event_notification`]: msg.data[`key${key}EventNotification`], }; }, }, ], }; }, dimmingMode: () => { const extend = m.enumLookup({ name: "dimmer_mode", lookup: { Auto: 0, "RL-LED": 3, }, cluster: "lightingBallastCfg", attribute: "wiserControlMode", description: "Auto detects the correct mode for the ballast. RL-LED may have improved dimming quality for LEDs.", entityCategory: "config", }); extend.configure.push(m.setupConfigureForReading("lightingBallastCfg", ["wiserControlMode"])); return extend; }, addOccupancyConfigurationCluster: () => m.deviceAddCustomCluster("occupancyConfiguration", { ID: 0xff19, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, attributes: { ambienceLightThreshold: { ID: 0x0000, type: zigbee_herdsman_1.Zcl.DataType.UINT16 }, occupancyActions: { ID: 0x0001, type: zigbee_herdsman_1.Zcl.DataType.ENUM8 }, unoccupiedLevelDflt: { ID: 0x0002, type: zigbee_herdsman_1.Zcl.DataType.UINT8 }, unoccupiedLevel: { ID: 0x0003, type: zigbee_herdsman_1.Zcl.DataType.UINT8 }, }, commands: {}, commandsResponse: {}, }), occupancyConfiguration: () => { const extend = m.enumLookup({ name: "occupancy_sensitivity", lookup: { Low: 50, Medium: 75, High: 100, }, cluster: "msOccupancySensing", attribute: { ID: 0xe003, type: zigbee_herdsman_1.Zcl.DataType.UINT8 }, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, description: "Sensitivity of the occupancy sensor", entityCategory: "config", }); const luxScale = (value, type) => { if (type === "from") { return Math.round(10 ** ((value - 1) / 10000)); } return Math.round(10000 * Math.log10(value) + 1); }; const luxThresholdExtend = m.numeric({ name: "ambience_light_threshold", cluster: "occupancyConfiguration", attribute: "ambienceLightThreshold", reporting: { min: "10_SECONDS", max: "1_HOUR", change: 5 }, description: "Threshold above which occupancy will not trigger the light switch.", unit: "lx", scale: luxScale, entityCategory: "config", valueMin: 1, valueMax: 2000, }); extend.fromZigbee.push(...luxThresholdExtend.fromZigbee); extend.toZigbee.push(...luxThresholdExtend.toZigbee); extend.exposes.push(...luxThresholdExtend.exposes); extend.configure.push(m.setupConfigureForReading("occupancyConfiguration", ["ambienceLightThreshold"])); return extend; }, }; const tzLocal = { lift_duration: { key: ["lift_duration"], convertSet: async (entity, key, value, meta) => { await entity.write(0x0102, { 57344: { value, type: 0x21 } }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }); return { state: { lift_duration: value } }; }, }, fan_mode: { ...tz.fan_mode, convertSet: async (entity, key, value, meta) => { utils.assertString(value); // biome-ignore lint/style/noParameterAssign: ignored using `--suppress` if (value.toLowerCase() === "on") value = "low"; return await tz.fan_mode.convertSet(entity, key, value, meta); }, }, }; const fzLocal = { schneider_powertag: { cluster: "greenPower", type: ["commandNotification", "commandCommissioningNotification"], convert: async (model, msg, publish, options, meta) => { if (msg.type !== "commandNotification") { return; } const commandID = msg.data.commandID; if (utils.hasAlreadyProcessedMessage(msg, model, msg.data.frameCounter, `${msg.device.ieeeAddr}_${commandID}`)) return; const rxAfterTx = msg.data.options & (1 << 11); const ret = {}; switch (commandID) { case 0xa1: { const attr = msg.data.commandFrame.attributes; const clusterID = msg.data.commandFrame.clusterID; switch (clusterID) { case 2820: { // haElectricalMeasurement const acCurrentDivisor = attr.acCurrentDivisor; const acVoltageDivisor = attr.acVoltageDivisor; const acFrequencyDivisor = attr.acFrequencyDivisor; const powerDivisor = attr.powerDivisor; if (attr.rmsVoltage !== undefined) { ret.voltage_phase_a = attr.rmsVoltage / acVoltageDivisor; } if (attr.rmsVoltagePhB !== undefined) { ret.voltage_phase_b = attr.rmsVoltagePhB / acVoltageDivisor; } if (attr.rmsVoltagePhC !== undefined) { ret.voltage_phase_c = attr.rmsVoltagePhC / acVoltageDivisor; } if (attr["19200"] !== undefined) { ret.voltage_phase_ab = attr["19200"] / acVoltageDivisor; } if (attr["19456"] !== undefined) { ret.voltage_phase_bc = attr["19456"] / acVoltageDivisor; } if (attr["19712"] !== undefined) { ret.voltage_phase_ca = attr["19712"] / acVoltageDivisor; } if (attr.rmsCurrent !== undefined) { ret.current_phase_a = attr.rmsCurrent / acCurrentDivisor; } if (attr.rmsCurrentPhB !== undefined) { ret.current_phase_b = attr.rmsCurrentPhB / acCurrentDivisor; } if (attr.rmsCurrentPhC !== undefined) { ret.current_phase_c = attr.rmsCurrentPhC / acCurrentDivisor; } if (attr.totalActivePower !== undefined) { ret.power = (attr.totalActivePower * 1000) / powerDivisor; } if (attr.totalApparentPower !== undefined) { ret.power_apparent = (attr.totalApparentPower * 1000) / powerDivisor; } if (attr.acFrequency !== undefined) { ret.ac_frequency = attr.acFrequency / acFrequencyDivisor; } if (attr.activePower !== undefined) { ret.power_phase_a = (attr.activePower * 1000) / powerDivisor; } if (attr.activePowerPhB !== undefined) { ret.power_phase_b = (attr.activePowerPhB * 1000) / powerDivisor; } if (attr.activePowerPhC !== undefined) { ret.power_phase_c = (attr.activePowerPhC * 1000) / powerDivisor; } break; } case 1794: { // seMetering const divisor = attr.divisor; if (attr.currentSummDelivered !== undefined) { const val = attr.currentSummDelivered; ret.energy = val / divisor; } if (attr["16652"] !== undefined) { const val = attr["16652"]; ret.energy_phase_a = val / divisor; } if (attr["16908"] !== undefined) { const val = attr["16908"]; ret.energy_phase_b = val / divisor; } if (attr["17164"] !== undefined) { const val = attr["17164"]; ret.energy_phase_c = val / divisor; } if (attr.powerFactor !== undefined) { ret.power_factor = attr.powerFactor; } break; } } break; } case 0xa3: // Should handle this cluster as well break; } if (rxAfterTx) { // Send Schneider specific ACK to make PowerTag happy // @ts-expect-error ignore const networkParameters = await msg.device.constructor.adapter.getNetworkParameters(); const payload = { options: 0b000, tempMaster: msg.data.gppNwkAddr, tempMasterTx: networkParameters.channel - 11, srcID: msg.data.srcID, gpdCmd: 0xfe, gpdPayload: { commandID: 0xfe, buffer: Buffer.alloc(1), // I hope it's zero initialised }, }; await msg.endpoint.commandResponse("greenPower", "response", payload, { srcEndpoint: 242, disableDefaultResponse: true, }); } return ret; }, }, }; exports.definitions = [ { zigbeeModel: ["PUCK/SHUTTER/1"], model: "CCT5015-0001", vendor: "Schneider Electric", description: "Roller shutter module", fromZigbee: [fz.cover_position_tilt], toZigbee: [tz.cover_position_tilt, tz.cover_state, tzLocal.lift_duration], exposes: [ e.cover_position(), e.numeric("lift_duration", ea.STATE_SET).withUnit("s").withValueMin(0).withValueMax(300).withDescription("Duration of lift"), ], meta: { coverInverted: true }, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(5); await reporting.bind(endpoint, coordinatorEndpoint, ["closuresWindowCovering"]); await reporting.currentPositionLiftPercentage(endpoint); }, }, { zigbeeModel: ["NHPB/SHUTTER/1"], model: "S520567", vendor: "Schneider Electric", description: "Roller shutter", fromZigbee: [fz.cover_position_tilt], toZigbee: [tz.cover_position_tilt, tz.cover_state, tzLocal.lift_duration], exposes: [ e.cover_position_tilt(), e.numeric("lift_duration", ea.STATE_SET).withUnit("s").withValueMin(0).withValueMax(300).withDescription("Duration of lift"), ], meta: { coverInverted: true }, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(5); await reporting.bind(endpoint, coordinatorEndpoint, ["closuresWindowCovering"]); await reporting.currentPositionLiftPercentage(endpoint); }, }, { zigbeeModel: ["iTRV"], model: "WV704R0A0902", vendor: "Schneider Electric", description: "Wiser radiator thermostat", fromZigbee: [ fz.ignore_basic_report, fz.ignore_haDiagnostic, fz.ignore_genOta, fz.ignore_zclversion_read, fz.thermostat, fz.battery, fz.hvac_user_interface, fz.wiser_device_info, ], toZigbee: [tz.thermostat_occupied_heating_setpoint, tz.thermostat_keypad_lockout], meta: { battery: { voltageToPercentage: { min: 2500, max: 3200 } } }, exposes: [ e .climate() .withSetpoint("occupied_heating_setpoint", 5, 30, 0.5) .withLocalTemperature(ea.STATE) .withRunningState(["idle", "heat"], ea.STATE) .withPiHeatingDemand(), e.battery(), e.battery_voltage(), e.keypad_lockout().withAccess(ea.ALL), ], configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); const binds = ["genBasic", "genPowerCfg", "hvacThermostat", "haDiagnostic"]; await reporting.bind(endpoint, coordinatorEndpoint, binds); await reporting.batteryVoltage(endpoint); await reporting.thermostatTemperature(endpoint); await reporting.thermostatOccupiedHeatingSetpoint(endpoint); await reporting.thermostatPIHeatingDemand(endpoint); // bind of hvacUserInterfaceCfg fails with 'Table Full', does this have any effect? await endpoint.configureReporting("hvacUserInterfaceCfg", [ { attribute: "keypadLockout", reportableChange: 1, minimumReportInterval: constants.repInterval.MINUTE, maximumReportInterval: constants.repInterval.HOUR, }, ]); }, }, { zigbeeModel: ["U202DST600ZB"], model: "U202DST600ZB", vendor: "Schneider Electric", description: "EZinstall3 2 gang 2x300W dimmer module", extend: [m.deviceEndpoints({ endpoints: { l1: 10, l2: 11 } }), m.light({ endpointNames: ["l1", "l2"], configureReporting: true })], }, { zigbeeModel: ["PUCK/DIMMER/1"], model: "CCT5010-0001", vendor: "Schneider Electric", description: "Micro module dimmer", ota: true, extend: [m.light({ configureReporting: true, levelConfig: {} })], fromZigbee: [fz.wiser_lighting_ballast_configuration], toZigbee: [tz.ballast_config, tz.wiser_dimmer_mode], exposes: [ e .numeric("ballast_minimum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the minimum light output of the ballast"), e .numeric("ballast_maximum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the maximum light output of the ballast"), e .enum("dimmer_mode", ea.ALL, ["auto", "rc", "rl", "rl_led"]) .withDescription("Sets dimming mode to autodetect or fixed RC/RL/RL_LED mode (max load is reduced in RL_LED)"), ], whiteLabel: [ { vendor: "Elko", model: "EKO07090" }, { vendor: "Schneider Electric", model: "550B1012" }, ], }, { zigbeeModel: ["PUCK/SWITCH/1"], model: "CCT5011-0001/CCT5011-0002/MEG5011-0001", vendor: "Schneider Electric", description: "Micro module switch", ota: true, extend: [m.onOff({ powerOnBehavior: false })], whiteLabel: [{ vendor: "Elko", model: "EKO07144" }], }, { zigbeeModel: ["PUCK/UNIDIM/1"], model: "CCT5010-0003", vendor: "Schneider Electric", description: "Micro module dimmer with neutral lead", ota: true, extend: [m.light({ configureReporting: true, levelConfig: {} })], fromZigbee: [fz.wiser_lighting_ballast_configuration], toZigbee: [tz.ballast_config, tz.wiser_dimmer_mode], exposes: [ e .numeric("ballast_minimum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the minimum light output of the ballast"), e .numeric("ballast_maximum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the maximum light output of the ballast"), e .enum("dimmer_mode", ea.ALL, ["auto", "rc", "rl", "rl_led"]) .withDescription("Sets dimming mode to autodetect or fixed RC/RL/RL_LED mode (max load is reduced in RL_LED)"), ], }, { zigbeeModel: ["CCTFR6730"], model: "CCTFR6730", vendor: "Schneider Electric", description: "Wiser power micromodule", whiteLabel: [{ vendor: "Elko", model: "EKO20004" }], extend: [m.onOff({ powerOnBehavior: true }), m.electricityMeter({ cluster: "metering" }), m.identify()], }, { zigbeeModel: ["NHROTARY/DIMMER/1"], model: "WDE002334", vendor: "Schneider Electric", description: "Rotary dimmer", fromZigbee: [fz.on_off, fz.brightness, fz.level_config, fz.wiser_lighting_ballast_configuration], toZigbee: [tz.light_onoff_brightness, tz.level_config, tz.ballast_config, tz.wiser_dimmer_mode], exposes: [ e.light_brightness().withLevelConfig(), e .numeric("ballast_minimum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the minimum light output of the ballast"), e .numeric("ballast_maximum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the maximum light output of the ballast"), e .enum("dimmer_mode", ea.ALL, ["auto", "rc", "rl", "rl_led"]) .withDescription("Sets dimming mode to autodetect or fixed RC/RL/RL_LED mode (max load is reduced in RL_LED)"), ], configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(3); await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff", "genLevelCtrl", "lightingBallastCfg"]); await reporting.onOff(endpoint); await reporting.brightness(endpoint); }, }, { zigbeeModel: ["NHROTARY/UNIDIM/1"], model: "NH3516A", vendor: "Schneider Electric", description: "Rotary dimmer", extend: [ m.light({ effect: false, powerOnBehavior: false, color: false, configureReporting: true, levelConfig: { features: ["on_level", "current_level_startup"] }, }), m.lightingBallast(), schneiderElectricExtend.dimmingMode(), ], whiteLabel: [ { vendor: "Elko", model: "EKO07278" }, { vendor: "Elko", model: "EKO07279" }, { vendor: "Elko", model: "EKO07280" }, { vendor: "Elko", model: "EKO07281" }, { vendor: "Elko", model: "EKO30198" }, { vendor: "Schneider", model: "WDE002961" }, { vendor: "Schneider", model: "WDE003961" }, { vendor: "Schneider", model: "WDE004961" }, ], }, { zigbeeModel: ["NHPB/UNIDIM/1"], model: "WDE002960", vendor: "Schneider Electric", description: "Push button dimmer", fromZigbee: [fz.on_off, fz.brightness, fz.level_config, fz.wiser_lighting_ballast_configuration], toZigbee: [tz.light_onoff_brightness, tz.level_config, tz.ballast_config, tz.wiser_dimmer_mode], exposes: [ e.light_brightness().withLevelConfig(), e .numeric("ballast_minimum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the minimum light output of the ballast"), e .numeric("ballast_maximum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the maximum light output of the ballast"), e .enum("dimmer_mode", ea.ALL, ["auto", "rc", "rl", "rl_led"]) .withDescription("Sets dimming mode to autodetect or fixed RC/RL/RL_LED mode (max load is reduced in RL_LED)"), ], configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(3); await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff", "genLevelCtrl", "lightingBallastCfg"]); await reporting.onOff(endpoint); await reporting.brightness(endpoint); }, }, { zigbeeModel: ["CCT593011_AS"], model: "550B1024", vendor: "Schneider Electric", description: "Temperature & humidity sensor", fromZigbee: [fz.humidity, fz.temperature, fz.battery], toZigbee: [], exposes: [e.battery(), e.temperature(), e.humidity()], configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); const binds = ["msTemperatureMeasurement", "genPowerCfg", "msRelativeHumidity"]; await reporting.bind(endpoint, coordinatorEndpoint, binds); await reporting.batteryPercentageRemaining(endpoint); await reporting.temperature(endpoint); await reporting.humidity(endpoint); }, }, { zigbeeModel: ["NHPB/DIMMER/1"], model: "WDE002386", vendor: "Schneider Electric", description: "Push button dimmer", fromZigbee: [fz.on_off, fz.brightness, fz.level_config, fz.lighting_ballast_configuration], toZigbee: [tz.light_onoff_brightness, tz.level_config, tz.ballast_config], exposes: [ e.light_brightness().withLevelConfig(), e .numeric("ballast_minimum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the minimum light output of the ballast"), e .numeric("ballast_maximum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the maximum light output of the ballast"), ], configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(3); await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff", "genLevelCtrl", "lightingBallastCfg"]); await reporting.onOff(endpoint); await reporting.brightness(endpoint); }, }, { zigbeeModel: ["CH/DIMMER/1"], model: "41EPBDWCLMZ/354PBDMBTZ", vendor: "Schneider Electric", description: "Wiser 40/300-Series Module Dimmer", fromZigbee: [fz.on_off, fz.brightness, fz.level_config, fz.lighting_ballast_configuration], toZigbee: [tz.light_onoff_brightness, tz.level_config, tz.ballast_config], exposes: [ e.light_brightness(), e .numeric("ballast_minimum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the minimum light output of the ballast"), e .numeric("ballast_maximum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the maximum light output of the ballast"), ], ota: true, extend: [indicatorMode("smart")], meta: { multiEndpoint: true }, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(3); await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff", "genLevelCtrl", "lightingBallastCfg"]); await reporting.onOff(endpoint); await reporting.brightness(endpoint); }, endpoint: (device) => { return { smart: 21 }; }, }, { zigbeeModel: ["CH2AX/SWITCH/1"], model: "41E2PBSWMZ/356PB2MBTZ", vendor: "Schneider Electric", description: "Wiser 40/300-Series module switch 2AX", ota: true, extend: [m.onOff({ powerOnBehavior: false }), indicatorMode("smart")], meta: { multiEndpoint: true }, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff"]); await reporting.onOff(endpoint); }, endpoint: (device) => { return { smart: 21 }; }, }, { zigbeeModel: ["CH10AX/SWITCH/1"], model: "41E10PBSWMZ-VW", vendor: "Schneider Electric", description: "Wiser 40/300-Series module switch 10AX with ControlLink", ota: true, extend: [m.onOff({ powerOnBehavior: false }), indicatorMode("smart")], meta: { multiEndpoint: true }, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff"]); await reporting.onOff(endpoint); }, endpoint: (device) => { return { smart: 21 }; }, }, { zigbeeModel: ["CHFAN/SWITCH/1"], model: "41ECSFWMZ-VW", vendor: "Schneider Electric", description: "Wiser 40/300-Series Module AC Fan Controller", fromZigbee: [fz.fan], toZigbee: [tzLocal.fan_mode], exposes: [e.fan().withState("fan_state").withModes(["off", "low", "medium", "high", "on"])], ota: true, extend: [fanIndicatorMode(), fanIndicatorOrientation()], configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(7); await reporting.bind(endpoint, coordinatorEndpoint, ["hvacFanCtrl"]); await reporting.fanMode(endpoint); }, }, { zigbeeModel: ["SMARTPLUG/1"], model: "CCT711119", vendor: "Schneider Electric", description: "Wiser smart plug", fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.power_on_behavior], toZigbee: [tz.on_off, tz.power_on_behavior, tz.electrical_measurement_power], exposes: [ e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.enum("power_on_behavior", ea.ALL, ["off", "previous", "on"]).withDescription("Controls the behaviour when the device is powered on"), ], configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff", "haElectricalMeasurement", "seMetering"]); await reporting.onOff(endpoint); // only activePower seems to be support, although compliance document states otherwise await endpoint.read("haElectricalMeasurement", ["acPowerMultiplier", "acPowerDivisor"]); await reporting.activePower(endpoint); await reporting.readMeteringMultiplierDivisor(endpoint); await reporting.currentSummDelivered(endpoint, { min: 60, change: 1 }); }, }, { zigbeeModel: ["U201DST600ZB"], model: "U201DST600ZB", vendor: "Schneider Electric", description: "EZinstall3 1 gang 550W dimmer module", extend: [m.light({ configureReporting: true })], }, { zigbeeModel: ["U201SRY2KWZB"], model: "U201SRY2KWZB", vendor: "Schneider Electric", description: "Ulti 240V 9.1 A 1 gang relay switch impress switch module, amber LED", extend: [m.onOff()], }, { zigbeeModel: ["CCTFR6100"], model: "CCTFR6100Z3", vendor: "Schneider Electric", description: "Wiser radiator thermostat", fromZigbee: [ fz.ignore_basic_report, fz.ignore_haDiagnostic, fz.ignore_genOta, fz.ignore_zclversion_read, fz.thermostat, fz.battery, fz.hvac_user_interface, fz.wiser_device_info, ], toZigbee: [tz.thermostat_occupied_heating_setpoint, tz.thermostat_keypad_lockout], exposes: [ e .climate() .withSetpoint("occupied_heating_setpoint", 7, 30, 1) .withLocalTemperature(ea.STATE) .withRunningState(["idle", "heat"], ea.STATE) .withPiHeatingDemand(), ], configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1); const binds = ["genBasic", "genPowerCfg", "hvacThermostat", "haDiagnostic"]; await reporting.bind(endpoint, coordinatorEndpoint, binds); await reporting.batteryVoltage(endpoint); await reporting.thermostatTemperature(endpoint); await reporting.thermostatOccupiedHeatingSetpoint(endpoint); await reporting.thermostatPIHeatingDemand(endpoint); // bind of hvacUserInterfaceCfg fails with 'Table Full', does this have any effect? await endpoint.configureReporting("hvacUserInterfaceCfg", [ { attribute: "keypadLockout", reportableChange: 1, minimumReportInterval: constants.repInterval.MINUTE, maximumReportInterval: constants.repInterval.HOUR, }, ]); }, }, { zigbeeModel: ["NHPB/SWITCH/1"], model: "S520530W", vendor: "Schneider Electric", description: "Odace connectable relay switch 10A", extend: [m.onOff({ powerOnBehavior: false })], }, { zigbeeModel: ["U202SRY2KWZB"], model: "U202SRY2KWZB", vendor: "Schneider Electric", description: "Ulti 240V 9.1 A 2 gangs relay switch impress switch module, amber LED", extend: [m.deviceEndpoints({ endpoints: { l1: 10, l2: 11 } }), m.onOff({ endpointNames: ["l1", "l2"] })], }, { zigbeeModel: ["1GANG/SHUTTER/1"], model: "MEG5113-0300/MEG5165-0000", vendor: "Schneider Electric", description: "Merten MEG5165 PlusLink Shutter insert with Merten Wiser System M Push Button (1fold)", fromZigbee: [fz.cover_position_tilt, fz.command_cover_close, fz.command_cover_open, fz.command_cover_stop], toZigbee: [tz.cover_position_tilt, tz.cover_state, tzLocal.lift_duration], exposes: [ e.cover_position_tilt(), e.numeric("lift_duration", ea.STATE_SET).withUnit("s").withValueMin(0).withValueMax(300).withDescription("Duration of lift"), ], meta: { coverInverted: true }, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(1) || device.getEndpoint(5); await reporting.bind(endpoint, coordinatorEndpoint, ["closuresWindowCovering"]); await reporting.currentPositionLiftPercentage(endpoint); }, }, { zigbeeModel: ["1GANG/DIMMER/1", "1GANG/DALI/1"], model: "MEG5116-0300/MEG5171-0000", vendor: "Schneider Electric", description: "Merten MEG5171 PlusLink Dimmer insert with Merten Wiser System M Push Button (1fold)", fromZigbee: [fz.on_off, fz.brightness, fz.level_config, fz.wiser_lighting_ballast_configuration], toZigbee: [tz.light_onoff_brightness, tz.level_config, tz.ballast_config, tz.wiser_dimmer_mode], exposes: [ e.light_brightness().withLevelConfig(), e .numeric("ballast_minimum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the minimum light output of the ballast"), e .numeric("ballast_maximum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the maximum light output of the ballast"), e .enum("dimmer_mode", ea.ALL, ["auto", "rc", "rl", "rl_led"]) .withDescription("Sets dimming mode to autodetect or fixed RC/RL/RL_LED mode (max load is reduced in RL_LED)"), ], extend: [indicatorMode(), switchActions()], configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(3); await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff", "genLevelCtrl", "lightingBallastCfg"]); await reporting.onOff(endpoint); await reporting.brightness(endpoint); }, }, { zigbeeModel: ["2GANG/DIMMER/1"], model: "MEG5126-0300/MEG5171-0000", vendor: "Schneider Electric", description: "Merten MEG5171 PlusLink Dimmer insert with Merten Wiser System M Push Button (2fold)", fromZigbee: [fz.on_off, fz.brightness, fz.level_config, fz.wiser_lighting_ballast_configuration], toZigbee: [tz.light_onoff_brightness, tz.level_config, tz.ballast_config, tz.wiser_dimmer_mode], exposes: [ e.light_brightness().withLevelConfig(), e .numeric("ballast_minimum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the minimum light output of the ballast"), e .numeric("ballast_maximum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the maximum light output of the ballast"), e .enum("dimmer_mode", ea.ALL, ["auto", "rc", "rl", "rl_led"]) .withDescription("Sets dimming mode to autodetect or fixed RC/RL/RL_LED mode (max load is reduced in RL_LED)"), ], extend: [indicatorMode("right"), indicatorMode("left"), switchActions("right"), switchActions("left")], meta: { multiEndpoint: true }, configure: async (device, coordinatorEndpoint) => { const endpoint = device.getEndpoint(3); await reporting.bind(endpoint, coordinatorEndpoint, ["genOnOff", "genLevelCtrl", "lightingBallastCfg"]); await reporting.onOff(endpoint); await reporting.brightness(endpoint); }, endpoint: (device) => { return { right: 21, left: 22 }; }, }, { zigbeeModel: ["2GANG/DIMMER/2"], model: "MEG5126-0300/MEG5172-0000", vendor: "Schneider Electric", description: "Merten MEG5172 PlusLink Dimmer insert with Merten Wiser System M Push Button (2fold)", fromZigbee: [fz.wiser_lighting_ballast_configuration], toZigbee: [tz.ballast_config, tz.wiser_dimmer_mode], exposes: [ e .numeric("ballast_minimum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the minimum light output of the ballast"), e .numeric("ballast_maximum_level", ea.ALL) .withValueMin(1) .withValueMax(254) .withDescription("Specifies the maximum light output of the ballast"), e .enum("dimmer_mode", ea.ALL, ["auto", "rc", "rl", "rl_led"]) .withDescription("Sets dimming mode to autodetect or fixed RC/RL/RL_LED mode (max load is reduced in RL_LED)"), ], extend: [ m.deviceEndpoints({ endpoints: { left: 4, right: 3, left_btn: 22, right_btn: 21 } }), m.light({ endpointNames: ["left", "right"], configureReporting: true }), switchActions("left_btn"), switchActions("right_btn"), indicatorMode("left_btn"), ], }, { zigbeeModel: ["1GANG/SWITCH/1"], model: "MEG5161-0000", vendor: "Schneider Electric", description: "Merten PlusLink relay insert with Merten Wiser system M push button (1fold)", extend: [m.onOff({ powerOnBehavior: false })], }, { zigbeeModel: ["LK Switch"], model: "545D6514", vendor: "Schneider Electric", description: "LK FUGA wiser wireless double relay", meta: { multiEndpoint: true }, fromZigbee: [fz.on_off, fz.command_on, fz.command_off], toZigbee: [tz.on_off], endpoint: (device) => { return { l1: 1, l2: 2, s1: 21, s2: 22, s3: 23, s4: 24 }; }, exposes: [e.switch().withEndpoint("l1"), e.switch().withEndpoint("l2"), e.action(["on_s*", "off_s*"])], configure: (device, coordinatorEndpoint) => { // biome-ignore lint/complexity/noForEach: ignored using `--sup