UNPKG

zigbee-herdsman-converters

Version:

Collection of device converters to be used with zigbee-herdsman

198 lines 10.9 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 exposes = __importStar(require("../lib/exposes")); const tuya = __importStar(require("../lib/tuya")); const e = exposes.presets; const ea = exposes.access; // DAEWOO WKE502Z — Zigbee keypad with RFID badge reader (TS0601 / _TZE200_rt5dklro) // // Key discovery: dp:101 "hub mode" flag — MUST be written true after every power cycle // for dp:27 (arm_away) and dp:28 (arm_home) to fire. Without it the keypad processes // arm actions locally but sends no Zigbee frame. Resets to false on every power cycle. // // ACK protocol: after dp:27/dp:28, the keypad retries until the hub writes dp:23=true. // This converter handles both the hub mode re-arm (deviceAnnounce) and the ACK automatically. // // Confirmed DP map via serial (MCU UART) + Zigbee capture: // DP 3 (u32) — battery % // DP 23 (bool) — arm state; hub must write true to ACK arm_away/arm_home // DP 24 (bool) — tamper // DP 25 (enum) — arm mode at STARTUP ONLY: 0=disarmed, 2=armed // DP 26 — disarm action // DP 27 — arm_away action (requires dp:101=true; retries until ACK dp:23=true) // DP 28 — arm_home action (requires dp:101=true; retries until ACK dp:23=true) // DP 29 — sos action (unconditional) // DP 101(bool) — hub mode flag // DP 103 — arm delay time (0–180 s) // DP 104 — beep on key press (volatile) // DP 105 — quick arm home (volatile) // DP 106 — quick disarm (volatile) // DP 107 — quick arm away (volatile) // DP 108 — admin code // DP 109 — last added user code // DP 110 — quick SOS (volatile) // DP 111 — arm delay beep // DP 112 (u32) — user_id: RFID badge slot or PIN user index function localISOString() { const now = new Date(); const off = -now.getTimezoneOffset(); const sign = off >= 0 ? "+" : "-"; const pad = (n) => String(Math.abs(n)).padStart(2, "0"); return new Date(now.getTime() - now.getTimezoneOffset() * 60000) .toISOString() .replace("Z", `${sign}${pad(Math.floor(Math.abs(off) / 60))}:${pad(Math.abs(off) % 60)}`); } // ACK arm_away (dp:27) and arm_home (dp:28) with dp:23=true so the keypad stops retrying. // Code validation is done by the keypad hardware before sending these DPs. const fzAck = { cluster: "manuSpecificTuya", type: ["commandDataResponse", "commandDataReport", "commandActiveStatusReport", "commandActiveStatusReportAlt"], convert: async (_model, msg, _publish, _options, meta) => { if (msg.data.dpValues.some((d) => d.dp === 27 || d.dp === 28)) { const endpoint = meta.device.getEndpoint(1); if (endpoint) { await tuya.sendDataPointBool(endpoint, 23, true, "dataRequest", 1); } } }, }; exports.definitions = [ { fingerprint: tuya.fingerprint("TS0601", ["_TZE200_rt5dklro"]), model: "WKE502Z", vendor: "DAEWOO", description: "Smart Zigbee keypad with RFID badge reader", extend: [tuya.modernExtend.tuyaBase({ dp: true })], fromZigbee: [fzAck], exposes: [ e.action(["disarm", "arm_away", "arm_home", "sos"]), e.numeric("arm_mode", ea.STATE).withDescription("Arm mode reported at startup only: 0=disarmed, 2=armed. NOT updated in real-time."), e .binary("armed", ea.STATE_SET, true, false) .withDescription("Arm state — write true to manually confirm arm_away/arm_home to the keypad"), e.binary("sos_alarm", ea.STATE, true, false).withDescription("SOS alarm active — set true by SOS keypress, cleared false by disarm"), e.battery(), e.tamper(), e.text("user_id", ea.STATE).withDescription("User ID (RFID badge slot or PIN index) that triggered the last action"), e.text("user_last_seen", ea.STATE).withDescription("ISO timestamp of last user authentication — updates on every badge/code event"), e.text("last_added_user_code", ea.STATE).withDescription("Last code entered by a user"), e.text("admin_code", ea.STATE_SET).withDescription("Admin code (change with caution)"), e .numeric("arm_delay_time", ea.STATE_SET) .withValueMin(0) .withValueMax(180) .withUnit("s") .withDescription("Delay before arming (0-180 s)"), e.binary("beep_sound_enabled", ea.STATE_SET, "ON", "OFF").withDescription("Enable keypad beep on key press"), e.binary("arm_delay_beep_sound", ea.STATE_SET, "ON", "OFF").withDescription("Beep during arm delay countdown"), e.binary("quick_home_enabled", ea.STATE_SET, "ON", "OFF").withDescription("Allow arm-home without entering a code"), e.binary("quick_arm_enabled", ea.STATE_SET, "ON", "OFF").withDescription("Allow arm-away without entering a code"), e.binary("quick_disarm_enabled", ea.STATE_SET, "ON", "OFF").withDescription("Allow disarm without entering a code"), e.binary("quick_sos_enabled", ea.STATE_SET, "ON", "OFF").withDescription("Allow SOS without entering a code"), ], meta: { tuyaDatapoints: [ // dp:23 from: null key → Object.assign (armed state only, no action — avoids // spurious 'arm' events when the hub ACK or SOS follow-up dp:23=true arrive) [23, null, { from: (v) => ({ armed: v === true || v === 1 }) }], // dp:23 to: write armed=true/false → sends dp:23=1/0 (hub ACK for arm_away/arm_home) [23, "armed", { to: (v) => (v ? 1 : 0) }], [3, "battery", tuya.valueConverter.raw], [ 24, "tamper", { from: (v) => v === true || v === 1, to: (v) => (v ? 1 : 0), }, ], [25, "arm_mode", tuya.valueConverter.raw], // Action DPs: include user_last_seen so it always refreshes even when dp:112 // does not accompany the action frame (observed for arm_away / arm_home) [26, null, { from: () => ({ action: "disarm", sos_alarm: false, user_last_seen: localISOString() }) }], [27, null, { from: () => ({ action: "arm_away", armed: true, user_last_seen: localISOString() }) }], [28, null, { from: () => ({ action: "arm_home", armed: true, user_last_seen: localISOString() }) }], [29, null, { from: () => ({ action: "sos", sos_alarm: true, user_last_seen: localISOString() }) }], [103, "arm_delay_time", tuya.valueConverter.raw], [104, "beep_sound_enabled", tuya.valueConverter.onOff], [105, "quick_home_enabled", { from: tuya.valueConverter.onOff.from, to: (v) => v === "ON" }], [106, "quick_disarm_enabled", tuya.valueConverter.onOff], [107, "quick_arm_enabled", tuya.valueConverter.onOff], [108, "admin_code", tuya.valueConverter.raw], [109, "last_added_user_code", tuya.valueConverter.raw], [110, "quick_sos_enabled", { from: tuya.valueConverter.onOff.from, to: (v) => v === "ON" }], [111, "arm_delay_beep_sound", tuya.valueConverter.onOff], // dp:112: overrides user_last_seen with a fresher timestamp when user_id is present [112, null, { from: (v) => ({ user_id: String(v), user_last_seen: localISOString() }) }], [101, null, { from: () => undefined }], // hub mode echo — suppress "not defined" warning ], }, configure: async (device, coordinatorEndpoint) => { await tuya.configureMagicPacket(device, coordinatorEndpoint); const endpoint = device.getEndpoint(1); if (endpoint) { // Enable hub mode so arm_away (dp:27) and arm_home (dp:28) fire over Zigbee await tuya.sendDataPointBool(endpoint, 101, true, "dataRequest", 1); } }, onEvent: (async (event) => { if (event.type === "deviceAnnounce") { const endpoint = event.data.device.getEndpoint(1); if (endpoint) { // Re-enable hub mode after every power cycle await tuya.sendDataPointBool(endpoint, 101, true, "dataRequest", 1); // DP 104/105/106/107/110 are volatile: reset to firmware defaults on power cycle. // Restore from Z2M cached state so user settings survive reboots. const s = event.data.state; const volatileBoolDps = [ [104, "beep_sound_enabled"], [105, "quick_home_enabled"], [106, "quick_disarm_enabled"], [107, "quick_arm_enabled"], [110, "quick_sos_enabled"], ]; for (const [dp, key] of volatileBoolDps) { if (s[key] !== undefined) { await tuya.sendDataPointBool(endpoint, dp, s[key] === "ON" || s[key] === true, "dataRequest", 1); } } } } }), }, ]; //# sourceMappingURL=daewoo.js.map