UNPKG

zwave-js

Version:

Z-Wave driver written entirely in JavaScript/TypeScript

187 lines (186 loc) 7.58 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var VirtualEndpoint_exports = {}; __export(VirtualEndpoint_exports, { VirtualEndpoint: () => VirtualEndpoint }); module.exports = __toCommonJS(VirtualEndpoint_exports); var import_cc = require("@zwave-js/cc"); var import_core = require("@zwave-js/core"); var import_shared = require("@zwave-js/shared"); var import_arrays = require("alcalzone-shared/arrays"); var import_MultiCCAPIWrapper = require("./MultiCCAPIWrapper.js"); var import_VirtualNode = require("./VirtualNode.js"); class VirtualEndpoint { static { __name(this, "VirtualEndpoint"); } driver; index; constructor(node, driver, index) { this.driver = driver; this.index = index; if (node) this._node = node; } /** Required by {@link IZWaveEndpoint} */ virtual = true; /** The virtual node this endpoint belongs to */ _node; get node() { return this._node; } setNode(node) { this._node = node; } get nodeId() { if (this.node.id != void 0) return this.node.id; const ret = this.node.physicalNodes.map((n) => n.id); if (ret.length === 1) return ret[0]; return ret; } /** Tests if this endpoint supports the given CommandClass */ supportsCC(cc) { return this.node.physicalNodes.some((n) => { const endpoint = n.getEndpoint(this.index); return endpoint?.supportsCC(cc); }); } /** * Retrieves the minimum non-zero version of the given CommandClass the physical endpoints implement * Returns 0 if the CC is not supported at all. */ getCCVersion(cc) { const nonZeroVersions = this.node.physicalNodes.map((n) => n.getEndpoint(this.index)?.getCCVersion(cc)).filter((v) => v != void 0 && v > 0); if (!nonZeroVersions.length) return 0; return Math.min(...nonZeroVersions); } /** * @internal * Creates an API instance for a given command class. Throws if no API is defined. * @param ccId The command class to create an API instance for */ createAPI(ccId) { const createCCAPI = /* @__PURE__ */ __name((endpoint, secClass) => { if ((0, import_core.securityClassIsS2)(secClass) && endpoint.node.physicalNodes.length > 1) { const secMan = this.driver.getSecurityManager2(endpoint.node.physicalNodes[0].id); return import_cc.CCAPI.create(ccId, this.driver, endpoint).withOptions({ s2MulticastGroupId: secMan?.createMulticastGroup(endpoint.node.physicalNodes.map((n) => n.id), secClass) }); } else { return import_cc.CCAPI.create(ccId, this.driver, endpoint); } }, "createCCAPI"); if (this.node.hasMixedCommunicationProfiles) { const apiInstances = [ ...this.node.nodesByCommunicationProfile.entries() ].map(([profile, nodes]) => { const node = new import_VirtualNode.VirtualNode(this.node.id, this.driver, nodes); const endpoint = node.getEndpoint(this.index) ?? node; const secClass = (0, import_VirtualNode.getSecurityClassFromCommunicationProfile)(profile); return createCCAPI(endpoint, secClass); }); return (0, import_MultiCCAPIWrapper.createMultiCCAPIWrapper)(apiInstances); } else { const profile = [...this.node.nodesByCommunicationProfile.keys()][0]; const securityClass = (0, import_VirtualNode.getSecurityClassFromCommunicationProfile)(profile); return createCCAPI(this, securityClass); } } _commandClassAPIs = /* @__PURE__ */ new Map(); _commandClassAPIsProxy = new Proxy(this._commandClassAPIs, { get: /* @__PURE__ */ __name((target, ccNameOrId) => { if (process.env.NODE_ENV === "test" && typeof ccNameOrId === "string" && (ccNameOrId === "$$typeof" || ccNameOrId === "constructor" || ccNameOrId.includes("@@__IMMUTABLE"))) { return void 0; } if (typeof ccNameOrId === "symbol") { if (ccNameOrId === Symbol.iterator) { return this.commandClassesIterator; } else if (ccNameOrId === Symbol.toStringTag) { return "[object Object]"; } return void 0; } else { const ccId = (0, import_cc.normalizeCCNameOrId)(ccNameOrId); if (ccId == void 0) { throw new import_core.ZWaveError(`Command Class ${ccNameOrId} is not implemented!`, import_core.ZWaveErrorCodes.CC_NotImplemented); } if (!target.has(ccId)) { const api = this.createAPI(ccId); target.set(ccId, api); } return target.get(ccId); } }, "get") }); /** * Used to iterate over the commandClasses API without throwing errors by accessing unsupported CCs */ commandClassesIterator = function* () { const allCCs = (0, import_arrays.distinct)(this._node.physicalNodes.map((n) => n.getEndpoint(this.index)).filter((e) => !!e).flatMap((e) => [...e.implementedCommandClasses.keys()])); for (const cc of allCCs) { if (this.supportsCC(cc)) { const APIConstructor = (0, import_cc.getAPI)(cc); if ((0, import_shared.staticExtends)(APIConstructor, import_cc.PhysicalCCAPI)) continue; yield this.commandClasses[cc]; } } }.bind(this); /** * Provides access to simplified APIs that are tailored to specific CCs. * Make sure to check support of each API using `API.isSupported()` since * all other API calls will throw if the API is not supported */ get commandClasses() { return this._commandClassAPIsProxy; } /** Allows checking whether a CC API is supported before calling it with {@link VirtualEndpoint.invokeCCAPI} */ supportsCCAPI(cc) { return this.commandClasses[cc].isSupported(); } /** * Allows dynamically calling any CC API method on this virtual endpoint by CC ID and method name. * Use {@link VirtualEndpoint.supportsCCAPI} to check support first. * * **Warning:** Get-type commands are not supported, even if auto-completion indicates that they are. */ invokeCCAPI(cc, method, ...args) { const CCAPI2 = this.commandClasses[cc]; const ccId = (0, import_cc.normalizeCCNameOrId)(cc); const ccName = (0, import_core.getCCName)(ccId); if (!CCAPI2) { throw new import_core.ZWaveError(`The API for the ${ccName} CC does not exist or is not implemented!`, import_core.ZWaveErrorCodes.CC_NoAPI); } const apiMethod = CCAPI2[method]; if (typeof apiMethod !== "function") { throw new import_core.ZWaveError(`Method "${method}" does not exist on the API for the ${ccName} CC!`, import_core.ZWaveErrorCodes.CC_NotImplemented); } return apiMethod.apply(CCAPI2, args); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { VirtualEndpoint }); //# sourceMappingURL=VirtualEndpoint.js.map