UNPKG

zigbee-herdsman-converters

Version:

Collection of device converters to be used with zigbee-herdsman

453 lines • 20.6 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 exposes = __importStar(require("../lib/exposes")); const m = __importStar(require("../lib/modernExtend")); const ea = exposes.access; const VSMART_MANUFACTURER_CODE = 0x1379; const COMMAND_DELAY_MS = 100; const HOUR_TO_PERIOD_MULTIPLIER = 4; const MAX_PERCENTAGE = 100; const MAX_HOUR = 23; const MIN_HOUR = 0; const createLedIntensityConverter = (fieldName, endpointIndex, periodName) => ({ key: [fieldName], convertSet: async (entity, key, value) => { const percentage = Number(value); if (Number.isNaN(percentage) || percentage < 0 || percentage > MAX_PERCENTAGE) { throw new Error(`Invalid ${periodName} LED intensity. Expected: 0-${MAX_PERCENTAGE}%`); } const intensity = Math.round((percentage * 255) / MAX_PERCENTAGE); const payload = { data: [intensity, endpointIndex, 0] }; await entity.command("vsmartSwitchControl", "setLedIntensity", payload, { manufacturerCode: VSMART_MANUFACTURER_CODE, disableDefaultResponse: true, }); return { state: { [key]: percentage, }, }; }, }); const mLocal = { customCluster: () => m.deviceAddCustomCluster("vsmartSwitchControl", { name: "vsmartSwitchControl", ID: 0x0000, manufacturerCode: VSMART_MANUFACTURER_CODE, attributes: {}, commands: { setLedColor: { name: "setLedColor", ID: 0xf3, parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.LIST_UINT8 }], }, setVibrationIntensity: { name: "setVibrationIntensity", ID: 0xf0, parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.LIST_UINT8 }], }, setLedBrightnessLevel: { name: "setLedBrightnessLevel", ID: 0xf4, parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.LIST_UINT8 }], }, setLedIntensity: { name: "setLedIntensity", ID: 0xf2, parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.LIST_UINT8 }], }, setTimePeriod: { name: "setTimePeriod", ID: 0xf5, parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.LIST_UINT8 }], }, }, commandsResponse: { setLedColor: { name: "setLedColor", ID: 0xf3, parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.LIST_UINT8 }], }, setVibrationIntensity: { name: "setVibrationIntensity", ID: 0xf0, parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.LIST_UINT8 }], }, setLedBrightnessLevel: { name: "setLedBrightnessLevel", ID: 0xf4, parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.LIST_UINT8 }], }, setLedIntensity: { name: "setLedIntensity", ID: 0xf2, parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.LIST_UINT8 }], }, setTimePeriod: { name: "setTimePeriod", ID: 0xf5, parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.LIST_UINT8 }], }, }, }), ledColorControl: () => { const exposes_list = [ exposes .text("led_indicator_color_on", ea.SET) .withDescription("LED indicator color when switch is ON (hex format: #RRGGBB, e.g., #ff0000 for red)"), exposes .text("led_indicator_color_off", ea.SET) .withDescription("LED indicator color when switch is OFF (hex format: #RRGGBB, e.g., #ffffff for white)"), ]; const toZigbee = [ { key: ["led_indicator_color_on", "led_indicator_color_off"], convertSet: async (entity, key, value) => { const hexColor = String(value).trim(); const hexMatch = hexColor.match(/^#?([0-9a-fA-F]{6})$/); if (!hexMatch) { throw new Error("Invalid color format. Expected hex format: #RRGGBB (e.g., #ff0000)"); } const hex = hexMatch[1]; const r = Number.parseInt(hex.substring(0, 2), 16); const g = Number.parseInt(hex.substring(2, 4), 16); const b = Number.parseInt(hex.substring(4, 6), 16); const state = key === "led_indicator_color_on" ? 0x01 : 0x00; const payload = { data: [r, g, b, state], }; await entity.command("vsmartSwitchControl", "setLedColor", payload, { manufacturerCode: VSMART_MANUFACTURER_CODE, disableDefaultResponse: true, }); return { state: { [key]: `#${hex.toLowerCase()}`, }, }; }, }, ]; return { exposes: exposes_list, toZigbee, isModernExtend: true }; }, vibrationIntensityControl: () => { const exposes_list = [ exposes .numeric("vibration_intensity", ea.SET) .withValueMin(0) .withValueMax(MAX_PERCENTAGE) .withValueStep(1) .withUnit("%") .withDescription("Button vibration intensity (0-100%)"), ]; const toZigbee = [ { key: ["vibration_intensity"], convertSet: async (entity, key, value) => { const intensity = Number(value); if (typeof value === "undefined" || Number.isNaN(intensity) || intensity < 0 || intensity > MAX_PERCENTAGE) { throw new Error(`Invalid vibration intensity. Expected: 0-${MAX_PERCENTAGE}`); } const byteValue = Math.round((intensity / MAX_PERCENTAGE) * 255); const payload = { data: [byteValue] }; await entity.command("vsmartSwitchControl", "setVibrationIntensity", payload, { manufacturerCode: VSMART_MANUFACTURER_CODE, disableDefaultResponse: true, }); return { state: { [key]: intensity } }; }, }, ]; return { exposes: exposes_list, toZigbee, isModernExtend: true }; }, timePeriodControl: () => { const exposes_list = [ exposes .composite("time_periods", "time_periods", ea.SET) .withFeature(exposes .numeric("morning_start_hour", ea.SET) .withValueMin(MIN_HOUR) .withValueMax(MAX_HOUR) .withValueStep(1) .withUnit("h") .withDescription("Morning period start hour (0-23)")) .withFeature(exposes .numeric("evening_start_hour", ea.SET) .withValueMin(MIN_HOUR) .withValueMax(MAX_HOUR) .withValueStep(1) .withUnit("h") .withDescription("Evening period start hour (0-23)")) .withFeature(exposes .numeric("night_start_hour", ea.SET) .withValueMin(MIN_HOUR) .withValueMax(MAX_HOUR) .withValueStep(1) .withUnit("h") .withDescription("Night period start hour (0-23)")) .withDescription("Time period settings for switch behavior. Morning must start before evening, evening must start before night."), ]; const toZigbee = [ { key: ["time_periods"], convertSet: async (entity, key, value) => { const periods = value; const morningHour = Number(periods.morning_start_hour); const eveningHour = Number(periods.evening_start_hour); const nightHour = Number(periods.night_start_hour); if (Number.isNaN(morningHour) || morningHour < MIN_HOUR || morningHour > MAX_HOUR) { throw new Error(`Invalid morning start hour. Expected: ${MIN_HOUR}-${MAX_HOUR}`); } if (Number.isNaN(eveningHour) || eveningHour < MIN_HOUR || eveningHour > MAX_HOUR) { throw new Error(`Invalid evening start hour. Expected: ${MIN_HOUR}-${MAX_HOUR}`); } if (Number.isNaN(nightHour) || nightHour < MIN_HOUR || nightHour > MAX_HOUR) { throw new Error(`Invalid night start hour. Expected: ${MIN_HOUR}-${MAX_HOUR}`); } if (morningHour >= eveningHour) { throw new Error(`Morning period (${morningHour}:00) must start before evening period (${eveningHour}:00)`); } if (eveningHour >= nightHour) { throw new Error(`Evening period (${eveningHour}:00) must start before night period (${nightHour}:00)`); } // Convert all hours to period values (hour * HOUR_TO_PERIOD_MULTIPLIER) const periodValues = [ morningHour * HOUR_TO_PERIOD_MULTIPLIER, eveningHour * HOUR_TO_PERIOD_MULTIPLIER, nightHour * HOUR_TO_PERIOD_MULTIPLIER, ]; const payload = { data: periodValues }; await entity.command("vsmartSwitchControl", "setTimePeriod", payload, { manufacturerCode: VSMART_MANUFACTURER_CODE, disableDefaultResponse: true, }); return { state: { [key]: periods, }, }; }, }, ]; return { exposes: exposes_list, toZigbee, isModernExtend: true }; }, ledIntensityControl: () => { const exposes_list = [ exposes .numeric("morning_led_intensity", ea.SET) .withValueMin(0) .withValueMax(MAX_PERCENTAGE) .withValueStep(1) .withUnit("%") .withDescription("LED intensity for morning period (0-100%)"), exposes .numeric("evening_led_intensity", ea.SET) .withValueMin(0) .withValueMax(MAX_PERCENTAGE) .withValueStep(1) .withUnit("%") .withDescription("LED intensity for evening period (0-100%)"), exposes .numeric("night_led_intensity", ea.SET) .withValueMin(0) .withValueMax(MAX_PERCENTAGE) .withValueStep(1) .withUnit("%") .withDescription("LED intensity for night period (0-100%)"), ]; const toZigbee = [ createLedIntensityConverter("morning_led_intensity", 0, "morning"), createLedIntensityConverter("evening_led_intensity", 1, "evening"), createLedIntensityConverter("night_led_intensity", 2, "night"), ]; return { exposes: exposes_list, toZigbee, isModernExtend: true }; }, ledBrightnessLevelsControl: () => { const exposes_list = [ exposes .composite("led_brightness_levels", "led_brightness_levels", ea.SET) .withFeature(exposes .numeric("low_brightness_percent", ea.SET) .withValueMin(0) .withValueMax(MAX_PERCENTAGE) .withValueStep(1) .withUnit("%") .withDescription("Low brightness level percentage (0-100%)")) .withFeature(exposes .numeric("medium_brightness_percent", ea.SET) .withValueMin(0) .withValueMax(MAX_PERCENTAGE) .withValueStep(1) .withUnit("%") .withDescription("Medium brightness level percentage (0-100%)")) .withFeature(exposes .numeric("high_brightness_percent", ea.SET) .withValueMin(0) .withValueMax(MAX_PERCENTAGE) .withValueStep(1) .withUnit("%") .withDescription("High brightness level percentage (0-100%)")) .withDescription("LED brightness levels for different intensity settings. Low must be lower than medium, Medium must be lower than high."), ]; const toZigbee = [ { key: ["led_brightness_levels"], convertSet: async (entity, key, value) => { const levels = value; const lowPercent = Number(levels.low_brightness_percent); const mediumPercent = Number(levels.medium_brightness_percent); const highPercent = Number(levels.high_brightness_percent); if (Number.isNaN(lowPercent) || lowPercent < 0 || lowPercent > MAX_PERCENTAGE) { throw new Error(`Invalid low brightness percentage. Expected: 0-${MAX_PERCENTAGE}`); } if (Number.isNaN(mediumPercent) || mediumPercent < 0 || mediumPercent > MAX_PERCENTAGE) { throw new Error(`Invalid medium brightness percentage. Expected: 0-${MAX_PERCENTAGE}`); } if (Number.isNaN(highPercent) || highPercent < 0 || highPercent > MAX_PERCENTAGE) { throw new Error(`Invalid high brightness percentage. Expected: 0-${MAX_PERCENTAGE}`); } if (lowPercent >= mediumPercent) { throw new Error(`Low brightness (${lowPercent}%) must be lower than medium brightness (${mediumPercent}%)`); } if (mediumPercent >= highPercent) { throw new Error(`Medium brightness (${mediumPercent}%) must be lower than high brightness (${highPercent}%)`); } const lowBrightness = Math.round((lowPercent * 255) / MAX_PERCENTAGE); const mediumBrightness = Math.round((mediumPercent * 255) / MAX_PERCENTAGE); const highBrightness = Math.round((highPercent * 255) / MAX_PERCENTAGE); const commands = [{ data: [0, highBrightness] }, { data: [1, mediumBrightness] }, { data: [2, lowBrightness] }]; for (let i = 0; i < commands.length; i++) { await entity.command("vsmartSwitchControl", "setLedBrightnessLevel", commands[i], { manufacturerCode: VSMART_MANUFACTURER_CODE, disableDefaultResponse: true, }); if (i < commands.length - 1) { await new Promise((resolve) => setTimeout(resolve, COMMAND_DELAY_MS)); } } return { state: { [key]: levels, }, }; }, }, ]; return { exposes: exposes_list, toZigbee, isModernExtend: true }; }, }; exports.definitions = [ { zigbeeModel: ["HS-SWL100ZB-VNM", "HS-SWN100ZB-VNM", "HS-SWB100ZB-VNM", "HS-SRW100ZB-VNM"], model: "HS-SW100ZB-VNM", vendor: "VSmart", description: "Wall switch 1 gang", extend: [ m.onOff({ powerOnBehavior: false }), mLocal.customCluster(), mLocal.ledColorControl(), mLocal.vibrationIntensityControl(), mLocal.timePeriodControl(), mLocal.ledIntensityControl(), mLocal.ledBrightnessLevelsControl(), ], }, { zigbeeModel: ["HS-SWL200ZB-VNM", "HS-SWN200ZB-VNM", "HS-SWB200ZB-VNM", "HS-SRW200ZB-VNM"], model: "HS-SW200ZB-VNM", vendor: "VSmart", description: "Wall switch 2 gang", extend: [ m.deviceEndpoints({ endpoints: { 1: 1, 2: 2 } }), m.onOff({ powerOnBehavior: false, endpointNames: ["1", "2"] }), mLocal.customCluster(), mLocal.ledColorControl(), mLocal.vibrationIntensityControl(), mLocal.timePeriodControl(), mLocal.ledIntensityControl(), mLocal.ledBrightnessLevelsControl(), ], }, { zigbeeModel: ["HS-SWL300ZB-VNM"], model: "HS-SW300ZB-VNM", vendor: "VSmart", description: "Wall switch 3 gang", extend: [ m.deviceEndpoints({ endpoints: { 1: 1, 2: 2, 3: 3 } }), m.onOff({ powerOnBehavior: false, endpointNames: ["1", "2", "3"] }), mLocal.customCluster(), mLocal.ledColorControl(), mLocal.vibrationIntensityControl(), mLocal.timePeriodControl(), mLocal.ledIntensityControl(), mLocal.ledBrightnessLevelsControl(), ], }, { zigbeeModel: ["HS-SWL400ZB-VNM"], model: "HS-SW400ZB-VNM", vendor: "VSmart", description: "Wall switch 4 gang", extend: [ m.deviceEndpoints({ endpoints: { 1: 1, 2: 2, 3: 3, 4: 4 } }), m.onOff({ powerOnBehavior: false, endpointNames: ["1", "2", "3", "4"] }), mLocal.customCluster(), mLocal.ledColorControl(), mLocal.vibrationIntensityControl(), mLocal.timePeriodControl(), mLocal.ledIntensityControl(), mLocal.ledBrightnessLevelsControl(), ], }, { zigbeeModel: ["HS-SEDR00ZB-VNM"], model: "HS-SEDR00ZB-VNM", vendor: "VSmart", description: "Door/window sensor", extend: [m.iasZoneAlarm({ zoneType: "contact", zoneAttributes: ["alarm_1", "battery_low", "tamper"], invertAlarm: true })], }, { zigbeeModel: ["HS-SEOC00ZB-VNM"], model: "HS-SEOC00ZB-VNM", vendor: "VSmart", description: "Occupancy sensor", extend: [m.battery(), m.occupancy()], }, ]; //# sourceMappingURL=vsmart.js.map