UNPKG

zigbee-herdsman-converters

Version:

Collection of device converters to be used with zigbee-herdsman

1,062 lines (1,061 loc) 152 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 logger_1 = require("../lib/logger"); const m = __importStar(require("../lib/modernExtend")); const reporting = __importStar(require("../lib/reporting")); const globalStore = __importStar(require("../lib/store")); const utils = __importStar(require("../lib/utils")); const utils_1 = require("../lib/utils"); const stelpro = __importStar(require("./stelpro")); const e = exposes.presets; const ea = exposes.access; const NS = "zhc:schneider_electric"; 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 evlinkIndicatorMode() { return m.enumLookup({ name: "indicator_mode", lookup: { default: 1, temporary: 5, }, 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", { name: "visaConfiguration", ID: 0xfc04, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, attributes: { indicatorLuminanceLevel: { name: "indicatorLuminanceLevel", ID: 0x0000, type: enumDataType, write: true }, indicatorColor: { name: "indicatorColor", ID: 0x0001, type: enumDataType, write: true }, indicatorMode: { name: "indicatorMode", ID: 0x0002, type: enumDataType, write: true }, motorTypeChannel1: { name: "motorTypeChannel1", ID: 0x0003, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, motorTypeChannel2: { name: "motorTypeChannel2", ID: 0x0004, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, curtainStatusChannel1: { name: "curtainStatusChannel1", ID: 0x0005, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, curtainStatusChannel2: { name: "curtainStatusChannel2", ID: 0x0006, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, key1EventNotification: { name: "key1EventNotification", ID: 0x0020, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, key2EventNotification: { name: "key2EventNotification", ID: 0x0021, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, key3EventNotification: { name: "key3EventNotification", ID: 0x0022, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, key4EventNotification: { name: "key4EventNotification", ID: 0x0023, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, }, 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) => { // TODO: was defaulting `motorTypeChannel` which is not part of the custom cluster 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) => { // TODO: was defaulting `motorTypeChannel` which is not part of the custom cluster 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, optionsMask: 0, optionsOverride: 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", { optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity)); } }, }, ], exposes: [ ...endpointNames.map((endpointName) => e.cover_position().withDescription("State 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) => { for (const key of ["1", "2", "3", "4"]) { const zigbeeKey = `key${key}EventNotification`; if (Object.hasOwn(msg.data, zigbeeKey)) { return { action: `scene_${key}` }; } } }, }, ], }; }, 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", { name: "occupancyConfiguration", ID: 0xff19, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, attributes: { ambienceLightThreshold: { name: "ambienceLightThreshold", ID: 0x0000, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 0xffff }, occupancyActions: { name: "occupancyActions", ID: 0x0001, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff }, unoccupiedLevelDflt: { name: "unoccupiedLevelDflt", ID: 0x0002, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, unoccupiedLevel: { name: "unoccupiedLevel", ID: 0x0003, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, }, 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; }, thermostatWithPower: (options) => { const extend = m.thermostat(options); const climateExpose = extend.exposes.find((exp) => typeof exp !== "function" && "type" in exp && exp.type === "climate"); if (climateExpose) { climateExpose.withRunningState(["idle", "heat"]); const runningStateFeature = climateExpose.features.find((f) => typeof f !== "function" && "name" in f && f.name === "running_state"); if (runningStateFeature) { runningStateFeature.withDescription("Running state based on power draw (>10W)"); } } extend.fromZigbee.push({ cluster: "seMetering", type: ["attributeReport", "readResponse"], convert: (model, msg, publish, options, meta) => { if ("instantaneousDemand" in msg.data) { const w = Math.max(0, Number(msg.data.instantaneousDemand)); return { running_state: w > 10 ? "heat" : "idle" }; } }, }); return extend; }, addHeatingCoolingOutputClusterServer: () => m.deviceAddCustomCluster("heatingCoolingOutputClusterServer", { name: "heatingCoolingOutputClusterServer", ID: 0xff23, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, attributes: { measuredTemperature: { name: "measuredTemperature", ID: 0x0000, type: zigbee_herdsman_1.Zcl.DataType.INT16, max: 0x7fff }, absMinHeatTemperatureLimit: { name: "absMinHeatTemperatureLimit", ID: 0x0003, type: zigbee_herdsman_1.Zcl.DataType.INT16, max: 0x7fff }, absMaxHeatTemperatureLimit: { name: "absMaxHeatTemperatureLimit", ID: 0x0004, type: zigbee_herdsman_1.Zcl.DataType.INT16, max: 0x7fff }, absMinCoolTemperatureLimit: { name: "absMinCoolTemperatureLimit", ID: 0x0005, type: zigbee_herdsman_1.Zcl.DataType.INT16, max: 0x7fff }, absMaxCoolTemperatureLimit: { name: "absMaxCoolTemperatureLimit", ID: 0x0006, type: zigbee_herdsman_1.Zcl.DataType.INT16, max: 0x7fff }, minHeatTemperatureLimit: { name: "minHeatTemperatureLimit", ID: 0x0015, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff }, maxHeatTemperatureLimit: { name: "maxHeatTemperatureLimit", ID: 0x0016, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff }, minCoolTemperatureLimit: { name: "minCoolTemperatureLimit", ID: 0x0017, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff }, maxCoolTemperatureLimit: { name: "maxCoolTemperatureLimit", ID: 0x0018, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff }, heatTemperatureHighLimit: { name: "heatTemperatureHighLimit", ID: 0x0020, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff }, heatTemperatureLowLimit: { name: "heatTemperatureLowLimit", ID: 0x0021, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff }, coolTemperatureHighLimit: { name: "coolTemperatureHighLimit", ID: 0x0022, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff }, coolTemperatureLowLimit: { name: "coolTemperatureLowLimit", ID: 0x0023, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, max: 0x7fff }, coolingOutputMode: { name: "coolingOutputMode", ID: 0x0030, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true }, heatingOutputMode: { name: "heatingOutputMode", ID: 0x0031, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true }, maximumIdleTime: { name: "maximumIdleTime", ID: 0x0041, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 8784 }, antiIdleExerciseTime: { name: "antiIdleExerciseTime", ID: 0x0042, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 3600 }, preferredExerciseTime: { name: "preferredExerciseTime", ID: 0x0043, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 1439 }, minOffTime: { name: "minOffTime", ID: 0x0044, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true }, minOnTime: { name: "minOnTime", ID: 0x0045, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true }, maxOverallDutyCycle: { name: "maxOverallDutyCycle", ID: 0xe207, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, min: 900, max: 3600 }, overallDutyCyclePeriod: { name: "overallDutyCyclePeriod", ID: 0xe208, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 1440 }, clusterRevision: { name: "clusterRevision", ID: 0xfffd, type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xfffe }, }, commands: {}, commandsResponse: {}, }), heatingOutputMode: (args) => m.enumLookup({ name: "heating_output_mode", cluster: "heatingCoolingOutputClusterServer", attribute: "heatingOutputMode", description: "On devices with alternate heating output types, this selects which should be used to control the heating unit. This attribute is (mistakenly) also called pilot_mode on some devices.", entityCategory: "config", access: "ALL", lookup: { Disabled: 0, Relay: 1, OpenTherm: 2, "Fil Pilote": 3, "Relay NC": 4, }, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, ...args, }), pilotMode: (args) => m.enumLookup({ name: "schneider_pilot_mode", cluster: "heatingCoolingOutputClusterServer", attribute: "heatingOutputMode", description: "Controls piloting mode (from 'old description'). According to SE the attribute is called 'Heating output mode', and the corresponding custom cluster is heatingCoolingOutputClusterServer.", entityCategory: "config", access: "ALL", lookup: { contactor: 1, pilot: 3, }, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, ...args, }), addHvacUserInterfaceCfgCustomAttributes: () => m.deviceAddCustomCluster("hvacUserInterfaceCfg", { name: "hvacUserInterfaceCfg", ID: zigbee_herdsman_1.Zcl.Clusters.hvacUserInterfaceCfg.ID, attributes: { displayBrightnessActive: { name: "displayBrightnessActive", ID: 0xe000, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, min: 0, max: 100, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, displayBrightnessInactive: { name: "displayBrightnessInactive", ID: 0xe001, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, min: 0, max: 100, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, displayActiveTimeout: { name: "displayActiveTimeout", ID: 0xe002, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, min: 5, max: 600, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, }, commands: {}, commandsResponse: {}, }), displayBrightnessActive: (args) => m.numeric({ name: "display_brightness_active", cluster: "hvacUserInterfaceCfg", attribute: "displayBrightnessActive", description: "Sets brightness of the temperature display during active state", entityCategory: "config", unit: "%", valueMin: 0, valueMax: 100, valueStep: 1, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, ...args, }), displayBrightnessInactive: (args) => m.numeric({ name: "display_brightness_inactive", cluster: "hvacUserInterfaceCfg", attribute: "displayBrightnessInactive", description: "Sets brightness of the temperature display during inactive state", entityCategory: "config", unit: "%", valueMin: 0, valueMax: 100, valueStep: 1, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, ...args, }), displayActiveTimeout: (args) => m.numeric({ name: "display_active_timeout", cluster: "hvacUserInterfaceCfg", attribute: "displayActiveTimeout", description: "Sets timeout of the temperature display active state", entityCategory: "config", unit: "seconds", valueMin: 5, valueMax: 600, valueStep: 5, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, ...args, }), customTemperatureMeasurementCluster: () => m.deviceAddCustomCluster("msTemperatureMeasurement", { name: "msTemperatureMeasurement", ID: zigbee_herdsman_1.Zcl.Clusters.msTemperatureMeasurement.ID, attributes: { sensorCorrection: { name: "sensorCorrection", ID: 0xe020, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, min: -900, max: 900, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, temperatureSensorType: { name: "temperatureSensorType", ID: 0xe021, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, }, commands: {}, commandsResponse: {}, }), sensorCorrection: (args) => m.numeric({ name: "temperature_sensor_correction", cluster: "msTemperatureMeasurement", attribute: "sensorCorrection", description: "This is a user correction, possibly negative, to be added to the temperature measured by the sensor.", unit: "°C", scale: 100, valueMin: -9, valueMax: 9, valueStep: 0.01, access: "ALL", entityCategory: "config", zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, ...args, }), temperatureSensorType: (args) => m.enumLookup({ name: "temperature_sensor_type", cluster: "msTemperatureMeasurement", attribute: "temperatureSensorType", description: "This is used to specify the type of temperature sensor connected to this input", entityCategory: "config", access: "ALL", lookup: { "2kΩ sensor from HRT/Alre": 1, "10kΩ sensor from B+J": 2, "12kΩ sensor from OJ": 3, "15kΩ sensor from DEVI": 4, "33kΩ sensor from EBERLE": 5, "47kΩ sensor from CTM": 6, "No sensor": 0xff, }, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, ...args, }), customMeteringCluster: () => m.deviceAddCustomCluster("seMetering", { name: "seMetering", ID: zigbee_herdsman_1.Zcl.Clusters.seMetering.ID, attributes: { fixedLoadDemand: { name: "fixedLoadDemand", ID: 0x4510, type: zigbee_herdsman_1.Zcl.DataType.UINT24, write: true, max: 0x7fffff, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, }, commands: {}, commandsResponse: {}, }), fixedLoadDemand: (args) => m.numeric({ name: "fixed_load_demand", cluster: "seMetering", attribute: "fixedLoadDemand", description: "This attribute specifies the demand of a switched load when it is energised", entityCategory: "config", unit: "W", valueMin: 1, valueMax: 3600, valueStep: 1, ...args, }), customThermostatCluster: () => m.deviceAddCustomCluster("hvacThermostat", { name: "hvacThermostat", ID: zigbee_herdsman_1.Zcl.Clusters.hvacThermostat.ID, attributes: { schneiderWiserSpecific: { name: "schneiderWiserSpecific", ID: 0xe110, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, controlStatus: { name: "controlStatus", ID: 0xe211, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, localTemperatureSourceSelect: { name: "localTemperatureSourceSelect", ID: 0xe212, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xfe, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, controlType: { name: "controlType", ID: 0xe213, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, thermostatApplication: { name: "thermostatApplication", ID: 0xe216, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, heatingFuel: { name: "heatingFuel", ID: 0xe217, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, heatTransferMedium: { name: "heatTransferMedium", ID: 0xe218, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, heatingEmitter: { name: "heatingEmitter", ID: 0xe21a, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, wiserSmartZoneMode: { name: "wiserSmartZoneMode", ID: 0xe010, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, wiserSmartHactConfig: { name: "wiserSmartHactConfig", ID: 0xe011, type: zigbee_herdsman_1.Zcl.DataType.BITMAP8, write: true, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, wiserSmartCurrentFilPiloteMode: { name: "wiserSmartCurrentFilPiloteMode", ID: 0xe020, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, wiserSmartValvePosition: { name: "wiserSmartValvePosition", ID: 0xe030, type: zigbee_herdsman_1.Zcl.DataType.UINT8, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, wiserSmartValveCalibrationStatus: { name: "wiserSmartValveCalibrationStatus", ID: 0xe031, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }, }, commands: { schneiderWiserThermostatBoost: { name: "schneiderWiserThermostatBoost", ID: 0x80, parameters: [ { name: "command", type: zigbee_herdsman_1.Zcl.DataType.ENUM8, max: 0xff }, { name: "enable", type: zigbee_herdsman_1.Zcl.DataType.ENUM8, max: 0xff }, { name: "temperature", type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xffff }, { name: "duration", type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xffff }, ], }, wiserSmartSetSetpoint: { name: "wiserSmartSetSetpoint", ID: 0xe0, parameters: [ { name: "operatingmode", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff }, { name: "zonemode", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff }, { name: "setpoint", type: zigbee_herdsman_1.Zcl.DataType.INT16, min: -32768, max: 32767 }, { name: "reserved", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff }, ], }, wiserSmartSetFipMode: { name: "wiserSmartSetFipMode", ID: 0xe1, parameters: [ { name: "zonemode", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff }, { name: "fipmode", type: zigbee_herdsman_1.Zcl.DataType.ENUM8, max: 0xff }, { name: "reserved", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff }, ], }, wiserSmartCalibrateValve: { name: "wiserSmartCalibrateValve", ID: 0xe2, parameters: [] }, }, commandsResponse: {}, }), controlStatus: (args) => m.enumLookup({ name: "control_status", cluster: "hvacThermostat", attribute: "controlStatus", description: "This indicates the status of the thermostat and allows reporting of abnormal and fault conditions.", entityCategory: "diagnostic", access: "STATE", lookup: { "Normal Operation": 0x00, "No Temperature": 0x20, "Remote Demand Override": 0x40, "Window Open": 0x41, "Local Force On": 0x61, Maintenance: 0x82, "Output Temporal Limit": 0x83, "Sensor Fault": 0x84, }, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, ...args, }), localTemperatureSourceSelect: () => m.enumLookup({ name: "local_temperature_source_select", cluster: "hvacThermostat", attribute: "localTemperatureSourceSelect", description: "On devices with more than one temperature input, this selects which should be used for LocalTemperature.", entityCategory: "config", lookup: { Ambient: 2, External: 3 }, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, }), controlType: () => m.enumLookup({ name: "control_type", cluster: "hvacThermostat", attribute: "controlType", description: "'On/Off', 'PI' and 'None' supported. This specifies the type of control algorithm to be used to regulate temperature.", entityCategory: "config", lookup: { "On/Off": 0, PI: 1, None: 0xff }, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, }), thermostatApplication: () => m.enumLookup({ name: "thermostat_application", cluster: "hvacThermostat", attribute: "thermostatApplication", description: "This is used to specify what the Thermostat is regulating. 'Occupied Space' - heating where the room temperature is used as the control value, 'Floor' - Floor warming applications where the temperature of the floor itself is regulated.", entityCategory: "config", lookup: { "Occupied Space": 0, Floor: 1, "Not known": 0xff }, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, }), heatingFuel: () => m.enumLookup({ name: "heating_fuel", cluster: "hvacThermostat", attribute: "heatingFuel", description: "Type of fuel used for heating.", entityCategory: "config", lookup: { electricity: 0x00, gas: 0x01, oil: 0x02, solid_fuel: 0x03, solar: 0x04, community_heating: 0x05, heat_pump: 0x06, not_specified: 0xff, }, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, }), heatTransferMedium: () => m.enumLookup({ name: "heat_transfer_medium", cluster: "hvacThermostat", attribute: "heatTransferMedium", description: "Medium used to transfer heat.", entityCategory: "config", lookup: { nothing: 0x00, hydronic: 0x01, air: 0x02 }, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, }), heatingEmitter: () => m.enumLookup({ name: "heating_emitter", cluster: "hvacThermostat", attribute: "heatingEmitter", description: "This is used to specify the heat emitter.", entityCategory: "config", lookup: { None: 0, Radiator: 1, "Fan Assisted Radiator": 2, "Radiant Panel": 3, Floor: 4, "Not specified": 0xff }, zigbeeCommandOptions: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }, }), addWiserDeviceInfoCluster: () => m.deviceAddCustomCluster("wiserDeviceInfo", { name: "wiserDeviceInfo", ID: 0xfe03, attributes: { deviceInfo: { name: "deviceInfo", ID: 0x0020, type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR, write: true }, }, commands: {}, commandsResponse: {}, }), addSchneiderLightSwitchConfigurationCluster: () => m.deviceAddCustomCluster("manuSpecificSchneiderLightSwitchConfiguration", { name: "manuSpecificSchneiderLightSwitchConfiguration", ID: 0xff17, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, attributes: { ledIndication: { name: "ledIndication", ID: 0x0000, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff }, upSceneID: { name: "upSceneID", ID: 0x0010, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, upGroupID: { name: "upGroupID", ID: 0x0011, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 0xffff }, downSceneID: { name: "downSceneID", ID: 0x0020, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, downGroupID: { name: "downGroupID", ID: 0x0021, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 0xffff }, switchActions: { name: "switchActions", ID: 0x0001, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff }, }, commands: {}, commandsResponse: {}, }), addSchneiderFanSwitchConfigurationCluster: () => m.deviceAddCustomCluster("manuSpecificSchneiderFanSwitchConfiguration", { name: "manuSpecificSchneiderFanSwitchConfiguration", ID: 0xfc04, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, attributes: { ledIndication: { name: "ledIndication", ID: 0x0002, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, ledOrientation: { name: "ledOrientation", ID: 0x0060, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff }, }, commands: {}, commandsResponse: {}, }), addSchneiderLightingBallastCfgCluster: () => m.deviceAddCustomCluster("lightingBallastCfg", { name: "lightingBallastCfg", ID: zigbee_herdsman_1.Zcl.Clusters.lightingBallastCfg.ID, attributes: { wiserControlMode: { name: "wiserControlMode", ID: 0xe000, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, write: true, max: 0xff, }, }, commands: {}, commandsResponse: {}, }), }; 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); if (value.toLowerCase() === "on") value = "low"; return await tz.fan_mode.convertSet(entity, key, value, meta); }, }, wiser_dimmer_mode: { key: ["dimmer_mode"], convertSet: async (entity, key, value, meta) => { await entity.write("lightingBallastCfg", { wiserControlMode: utils.getKey(constants.wiserDimmerControlMode, value, value, Number) }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC }); return { state: { dimmer_mode: value } }; }, convertGet: async (entity, key, meta) => { await entity.read("lightingBallastCfg", ["wiserControlMode"], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC, }); }, }, wiser_fip_setting: { key: ["fip_setting"], convertSet: async (entity, key, value, meta) => { utils.assertString(value, key); const zoneLookup = { manual: 1, schedule: 2, energy_saver: 3, holiday: 6 }; const zonemodeNum = utils.getFromLookup(meta.state.zone_mode, zoneLookup); const fipLookup = { comfort: 0, "comfort_-1": 1, "comfort_-2": 2, energy_saving: 3, frost_protection: 4, off: 5 }; value = value.toLowerCase(); utils.validateValue(value, Object.keys(fipLookup)); const fipmodeNum = utils.getFromLookup(value, fipLookup); const payload = { zonemode: zonemodeNum, fipmode: fipmodeNum, reserved: 0xff, }; await entity.command("hvacThermostat", "wiserSmartSetFipMode", payload, { srcEndpoint: 11, disableDefaultResponse: true }); return { state: { fip_setting: value } }; }, convertGet: async (entity, key, meta) => { await entity.read("hvacThermostat", ["wiserSmartCurrentFilPiloteMode"]); }, }, wiser_hact_config: { key: ["hact_config"], convertSet: async (entity, key, value, meta) => { utils.assertString(value, key); const lookup = { unconfigured: 0x00, setpoint_switch: 0x80, setpoint_fip: 0x82, fip_fip: 0x83 }; value = value.toLowerCase(); const mode = utils.getFromLookup(value, lookup); await entity.write("hvacThermostat", { 57361: { value: mode, type: 0x18 } }); return { state: { hact_config: value } }; }, convertGet: async (entity, key, meta) => { await entity.read("hvacThermostat", ["wiserSmartHactConfig"]); }, }, wiser_zone_mode: { key: ["zone_mode"], convertSet: async (entity, key, value, meta) => { const lookup = { manual: 1, schedule: 2, energy_saver: 3, holiday: 6 }; const zonemodeNum = utils.getFromLookup(value, lookup); await entity.write("hvacThermostat", { 57360: { value: zonemodeNum, type: 0x30 } }); return { state: { zone_mode: value } }; }, convertGet: async (entity, key, meta) => { await entity.read("hvacThermostat", ["wiserSmartZoneMode"]); }, }, wiser_vact_calibrate_valve: { key: ["calibrate_valve"], convertSet: async (entity, key, value, meta) => { await entity.command("hvacThermostat", "wiserSmartCalibrateValve", {}, { srcEndpoint: 11, disableDefaultResponse: true }); return { state: { calibrate_valve: value } }; }, }, }; const fzLocal = { schneider_ui_action: { cluster: "wiserDeviceInfo", type: "attributeReport", convert: (model, msg, publish, options, meta) => { if (utils.hasAlreadyProcessedMessage(msg, model)) return; const data = msg.data.deviceInfo.split(","); if (data[0] === "UI" && data[1]) { const result = { action: utils.toSnakeCase(data[1]) }; let screenAwake = globalStore.getValue(msg.endpoint, "screenAwake"); screenAwake = screenAwake !== undefined ? screenAwake : false; const keypadLockedNumber = Number(msg.endpoint.getClusterAttributeValue("hvacUserInterfaceCfg", "keypadLockout")); const keypadLocked = keypadLockedNumber !== undefined ? keypadLockedNumber !== 0 : false; // Emulate UI temperature update if (data[1] === "ScreenWake") { globalStore.putValue(msg.endpoint, "screenAwake", true); } else if (data[1] === "ScreenSleep") { globalStore.putValue(msg.endpoint, "screenAwake", false); } else if (screenAwake && !keypadLocked) { let occupiedHeatingSetpoint = Number(msg.endpoint.getClusterAttributeValue("hvacThermostat", "occupiedHeatingSetpoint")); occupiedHeatingSetpoint = occupiedHeatingSetpoint != null ? occupiedHeatingSetpoint : 400; if (data[1] === "ButtonPressMinusDown") { occupiedHeatingSetpoint -= 50; } else if (data[1] === "ButtonPressPlusDown") { occupiedHeatingSetpoint += 50; } msg.endpoint.saveClusterAttributeKeyValue("hvacThermostat", { occupiedHeatingSetpoint: occupiedHeatingSetpoint }); result.occupied_heating_setpoint = occupiedHeatingSetpoint / 100; } return result; } }, }, 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) {