UNPKG

zigbee-herdsman-converters

Version:

Collection of device converters to be used with zigbee-herdsman

282 lines • 12.2 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.fzLegrand = exports.tzLegrand = exports.readInitialBatteryState = exports.eLegrand = exports.legrandOptions = void 0; const zigbee_herdsman_1 = require("zigbee-herdsman"); const utils = __importStar(require("../lib/utils")); const exposes = __importStar(require("./exposes")); const logger_1 = require("./logger"); const NS = "zhc:legrand"; const e = exposes.presets; const ea = exposes.access; const shutterCalibrationModes = { 0: { description: "classic_nllv", onlyNLLV: true, supportsTilt: false }, 1: { description: "specific_nllv", onlyNLLV: true, supportsTilt: false }, 2: { description: "up_down_stop", onlyNLLV: false, supportsTilt: false }, 3: { description: "temporal", onlyNLLV: false, supportsTilt: false }, 4: { description: "venetian_bso", onlyNLLV: false, supportsTilt: true }, }; const ledModes = { 1: "led_in_dark", 2: "led_if_on", }; const ledEffects = { 0: "blink 3", 1: "fixed", 2: "blink green", 3: "blink blue", }; const ledColors = { 0: "default", 1: "red", 2: "green", 3: "blue", 4: "lightblue", 5: "yellow", 6: "pink", 7: "white", }; const optsLegrand = { identityEffect: () => { return e .composite("Identity effect", "identity_effect", ea.SET) .withDescription("Defines the identification effect to simplify the device identification.") .withFeature(e.enum("effect", ea.SET, Object.values(ledEffects)).withLabel("Effect")) .withFeature(e.enum("color", ea.SET, Object.values(ledColors)).withLabel("Color")); }, }; const getApplicableCalibrationModes = (isNLLVSwitch) => { return Object.fromEntries(Object.entries(shutterCalibrationModes) .filter((e) => (isNLLVSwitch ? true : e[1].onlyNLLV === false)) .map((e) => [e[0], e[1].description])); }; exports.legrandOptions = { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.LEGRAND_GROUP, disableDefaultResponse: true }; exports.eLegrand = { identify: () => { return e .enum("identify", ea.SET, ["identify"]) .withDescription("Blinks the built-in LED to make it easier to identify the device") .withCategory("config"); }, ledInDark: () => { return e .binary("led_in_dark", ea.ALL, "ON", "OFF") .withDescription("Enables the built-in LED allowing to see the switch in the dark") .withCategory("config"); }, ledIfOn: () => { return e.binary("led_if_on", ea.ALL, "ON", "OFF").withDescription("Enables the LED on activity").withCategory("config"); }, getCover: (device) => { const c = e.cover_position(); const calMode = Number(device?.getEndpoint(1)?.clusters?.closuresWindowCovering?.attributes?.calibrationMode); const showTilt = calMode ? shutterCalibrationModes[calMode]?.supportsTilt === true : false; if (showTilt) { c.addFeature(new exposes.Numeric("tilt", ea.ALL) .withValueMin(0) .withValueMax(100) .withValueStep(25) .withPreset("Closed", 0, "Vertical") .withPreset("25 %", 25, "25%") .withPreset("50 %", 50, "50%") .withPreset("75 %", 75, "75%") .withPreset("Open", 100, "Horizontal") .withUnit("%") .withDescription("Tilt percentage of that cover")); } return c; }, getCalibrationModes: (isNLLVSwitch) => { const modes = getApplicableCalibrationModes(isNLLVSwitch); return e .enum("calibration_mode", ea.ALL, Object.values(modes)) .withDescription("Defines the calibration mode of the switch. (Caution: Changing modes requires a recalibration of the shutter switch!)") .withCategory("config"); }, }; const readInitialBatteryState = async (type, data, device, options) => { if (["deviceAnnounce"].includes(type)) { const endpoint = device.getEndpoint(1); await endpoint.read("genPowerCfg", ["batteryVoltage"], exports.legrandOptions); } }; exports.readInitialBatteryState = readInitialBatteryState; exports.tzLegrand = { auto_mode: { key: ["auto_mode"], convertSet: async (entity, key, value, meta) => { const mode = utils.getFromLookup(value, { off: 0x00, auto: 0x02, on_override: 0x03 }); const payload = { data: Buffer.from([mode]) }; await entity.command("manuSpecificLegrandDevices3", "command0", payload); return { state: { auto_mode: value } }; }, }, calibration_mode: (isNLLVSwitch) => { return { key: ["calibration_mode"], convertSet: async (entity, key, value, meta) => { const applicableModes = getApplicableCalibrationModes(isNLLVSwitch); utils.validateValue(value, Object.values(applicableModes)); const idx = utils.getKey(applicableModes, value); await entity.write("closuresWindowCovering", { calibrationMode: idx }, exports.legrandOptions); }, convertGet: async (entity, key, meta) => { await entity.read("closuresWindowCovering", ["calibrationMode"], exports.legrandOptions); }, }; }, led_mode: { key: ["led_in_dark", "led_if_on"], convertSet: async (entity, key, value, meta) => { utils.validateValue(key, Object.values(ledModes)); const idx = utils.getKey(ledModes, key); const state = value === "ON" || (value === "OFF" ? false : !!value); const payload = { [idx]: { value: state, type: 16 } }; await entity.write("manuSpecificLegrandDevices", payload, exports.legrandOptions); return { state: { [key]: value } }; }, convertGet: async (entity, key, meta) => { utils.validateValue(key, Object.values(ledModes)); const idx = utils.getKey(ledModes, key); await entity.read("manuSpecificLegrandDevices", [Number(idx)], exports.legrandOptions); }, }, identify: { key: ["identify"], options: [optsLegrand.identityEffect()], convertSet: async (entity, key, value, meta) => { const identityEffect = meta.options.identity_effect; const selEffect = identityEffect?.effect ?? ledEffects[0]; const selColor = identityEffect?.color ?? ledColors[0]; const effectID = utils.getFromLookupByValue(selEffect, ledEffects, "0"); const effectVariant = utils.getFromLookupByValue(selColor, ledColors, "0"); // Trigger an effect const payload = { effectid: effectID, effectvariant: effectVariant }; await entity.command("genIdentify", "triggerEffect", payload, {}); // Trigger the identification await entity.command("genIdentify", "identify", { identifytime: 10 }, {}); }, }, }; exports.fzLegrand = { calibration_mode: (isNLLVSwitch) => { return { cluster: "closuresWindowCovering", type: ["attributeReport", "readResponse"], convert: (model, msg, publish, options, meta) => { const attr = "calibrationMode"; if (msg.data[attr] !== undefined) { const applicableModes = getApplicableCalibrationModes(isNLLVSwitch); const idx = msg.data[attr]; utils.validateValue(String(idx), Object.keys(applicableModes)); const calMode = applicableModes[idx]; return { calibration_mode: calMode }; } }, }; }, cluster_fc01: { cluster: "manuSpecificLegrandDevices", type: ["readResponse"], convert: (model, msg, publish, options, meta) => { const payload = {}; if (msg.data["0"] !== undefined) { const option0 = msg.data["0"]; if (option0 === 0x0001) payload.device_mode = "pilot_off"; else if (option0 === 0x0002) payload.device_mode = "pilot_on"; else if (option0 === 0x0003) payload.device_mode = "switch"; else if (option0 === 0x0004) payload.device_mode = "auto"; else if (option0 === 0x0100) payload.device_mode = "dimmer_off"; else if (option0 === 0x0101) payload.device_mode = "dimmer_on"; else { logger_1.logger.warning(`Device_mode ${option0} not recognized, please fix me!`, NS); payload.device_mode = "unknown"; } } if (msg.data["1"] !== undefined) payload.led_in_dark = msg.data["1"] === 0x00 ? "OFF" : "ON"; if (msg.data["2"] !== undefined) payload.led_if_on = msg.data["2"] === 0x00 ? "OFF" : "ON"; return payload; }, }, command_cover: { cluster: "closuresWindowCovering", type: ["attributeReport", "readResponse"], convert: (model, msg, publish, options, meta) => { const payload = {}; if (msg.data.tuyaMovingState !== undefined) { if (utils.hasAlreadyProcessedMessage(msg, model)) return; if (msg.data.tuyaMovingState === 0) { // return { // action: 'open', // }; payload.action = utils.postfixWithEndpointName("OPEN", msg, model, meta); utils.addActionGroup(payload, msg, model); } if (msg.data.tuyaMovingState === 100) { // return { // action: 'closed', // }; payload.action = utils.postfixWithEndpointName("CLOSE", msg, model, meta); utils.addActionGroup(payload, msg, model); } if (msg.data.tuyaMovingState >= 1 && msg.data.tuyaMovingState < 100) { // return { // action: 'stop', // }; payload.action = utils.postfixWithEndpointName("STOP", msg, model, meta); utils.addActionGroup(payload, msg, model); } } return payload; }, }, identify: { cluster: "genIdentify", type: ["attributeReport", "readResponse"], convert: (model, msg, publish, options, meta) => { return {}; }, }, }; //# sourceMappingURL=legrand.js.map