UNPKG

zwave-js

Version:

Z-Wave driver written entirely in JavaScript/TypeScript

1,002 lines (1,001 loc) 31.6 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 MPDU_exports = {}; __export(MPDU_exports, { AckLongRangeMPDU: () => AckLongRangeMPDU, AckZWaveMPDU: () => AckZWaveMPDU, BeamStop: () => BeamStop, ExplorerZWaveMPDU: () => ExplorerZWaveMPDU, InclusionRequestExplorerZWaveMPDU: () => InclusionRequestExplorerZWaveMPDU, LongRangeBeamStart: () => LongRangeBeamStart, LongRangeMPDU: () => LongRangeMPDU, MulticastZWaveMPDU: () => MulticastZWaveMPDU, NormalExplorerZWaveMPDU: () => NormalExplorerZWaveMPDU, RoutedZWaveMPDU: () => RoutedZWaveMPDU, SearchResultExplorerZWaveMPDU: () => SearchResultExplorerZWaveMPDU, SinglecastLongRangeMPDU: () => SinglecastLongRangeMPDU, SinglecastZWaveMPDU: () => SinglecastZWaveMPDU, ZWaveBeamStart: () => ZWaveBeamStart, ZWaveMPDU: () => ZWaveMPDU, beamToFrame: () => beamToFrame, mpduToFrame: () => mpduToFrame, mpduToLongRangeFrame: () => mpduToLongRangeFrame, mpduToZWaveFrame: () => mpduToZWaveFrame, parseBeamFrame: () => parseBeamFrame, parseMPDU: () => parseMPDU, znifferDataMessageToCorruptedFrame: () => znifferDataMessageToCorruptedFrame }); module.exports = __toCommonJS(MPDU_exports); var import_core = require("@zwave-js/core"); var import_serial = require("@zwave-js/serial"); var import_serialapi = require("@zwave-js/serial/serialapi"); var import_shared = require("@zwave-js/shared"); var import_Types = require("./_Types.js"); function getChannelConfiguration(region) { switch (region) { case import_core.ZnifferRegion.Japan: case import_core.ZnifferRegion.Korea: return "3"; case import_core.ZnifferRegion["USA (Long Range)"]: case import_core.ZnifferRegion["USA (Long Range, backup)"]: case import_core.ZnifferRegion["USA (Long Range, end device)"]: return "4"; default: return "1/2"; } } __name(getChannelConfiguration, "getChannelConfiguration"); function longRangeBeamPowerToDBm(power) { return [ -6, -2, 2, 6, 10, 13, 16, 19, 21, 23, 25, 26, 27, 28, 29, 30 ][power]; } __name(longRangeBeamPowerToDBm, "longRangeBeamPowerToDBm"); function formatNodeId(nodeId) { return nodeId.toString().padStart(3, "0"); } __name(formatNodeId, "formatNodeId"); function formatRoute(source, repeaters, destination, direction, currentHop, failedHop) { return [ direction === "outbound" ? formatNodeId(source) : formatNodeId(destination), ...repeaters.map(formatNodeId), direction === "outbound" ? formatNodeId(destination) : formatNodeId(source) ].map((id, i) => { if (i === 0) return id; if (i - 1 === failedHop) return " \xD7 " + id; if (i - 1 === currentHop) { return (direction === "outbound" ? " \xBB " : " \xAB ") + id; } return (direction === "outbound" ? " \u203A " : " \u2039 ") + id; }).join(""); } __name(formatRoute, "formatRoute"); function parseMPDU(frame) { switch (frame.channel) { case 0: case 1: case 2: return ZWaveMPDU.from(frame); case 3: case 4: return LongRangeMPDU.from(frame); default: import_core.validatePayload.fail(`Unsupported channel ${frame.channel}. MPDU payload: ${(0, import_shared.buffer2hex)(frame.payload)}`); } } __name(parseMPDU, "parseMPDU"); class LongRangeMPDU { static { __name(this, "LongRangeMPDU"); } constructor(options) { const data = options.data; this.frameInfo = options.frameInfo; if (options.frameInfo.channel !== 3 && options.frameInfo.channel !== 4) { import_core.validatePayload.fail(`Unsupported channel ${options.frameInfo.channel} for LongRangeMPDU`); } this.homeId = data.readUInt32BE(0); const nodeIds = data.readUIntBE(4, 3); this.sourceNodeId = nodeIds >>> 12; this.destinationNodeId = nodeIds & 4095; const frameControl = data[8]; this.ackRequested = !!(frameControl & 128); const hasExtendedHeader = !!(frameControl & 64); this.headerType = frameControl & 7; this.sequenceNumber = data[9]; this.noiseFloor = (0, import_serialapi.parseRSSI)(data, 10); this.txPower = data.readInt8(11); let offset = 12; if (hasExtendedHeader) { const extensionControl = data[offset++]; const extensionLength = extensionControl & 7; offset += extensionLength; } const Constructor = this.headerType === import_core.MPDUHeaderType.Acknowledgement ? AckLongRangeMPDU : this.headerType === import_core.MPDUHeaderType.Singlecast ? SinglecastLongRangeMPDU : void 0; if (!Constructor) { import_core.validatePayload.fail(`Unsupported Long Range MPDU header type ${this.headerType}`); } else if (new.target !== Constructor && !(0, import_shared.staticExtends)(new.target, Constructor)) { return new Constructor(options); } this.payload = data.subarray(offset); } frameInfo; homeId; sourceNodeId; destinationNodeId; ackRequested; headerType; sequenceNumber; noiseFloor; txPower; payload; static from(msg) { return new LongRangeMPDU({ data: msg.payload, frameInfo: (0, import_shared.pick)(msg, [ "channel", "frameType", "region", "protocolDataRate", "rssiRaw" ]) }); } toLogEntry() { const tags = [ formatRoute( this.sourceNodeId, [], this.destinationNodeId, // Singlecast frames do not contain a bit for this, we consider them all "outbound" "outbound", 0 ) ]; if (this.headerType === import_core.MPDUHeaderType.Acknowledgement) { tags.unshift("ACK"); } const message = { "sequence no.": this.sequenceNumber, channel: this.frameInfo.channel, "protocol/data rate": (0, import_core.znifferProtocolDataRateToString)(this.frameInfo.protocolDataRate), "TX power": `${this.txPower} dBm`, RSSI: this.frameInfo.rssi != void 0 ? (0, import_core.rssiToString)(this.frameInfo.rssi) : this.frameInfo.rssiRaw.toString(), "noise floor": (0, import_core.rssiToString)(this.noiseFloor) }; if (this.headerType !== import_core.MPDUHeaderType.Acknowledgement) { message["ack requested"] = this.ackRequested; } if (this.payload.length > 0) { message.payload = (0, import_shared.buffer2hex)(this.payload); } return { tags, message }; } } class SinglecastLongRangeMPDU extends LongRangeMPDU { static { __name(this, "SinglecastLongRangeMPDU"); } toLogEntry() { const { tags, message: original } = super.toLogEntry(); const message = { ...original, payload: (0, import_shared.buffer2hex)(this.payload) }; return { tags, message }; } } class AckLongRangeMPDU extends LongRangeMPDU { static { __name(this, "AckLongRangeMPDU"); } constructor(options) { super(options); this.incomingRSSI = (0, import_serialapi.parseRSSI)(this.payload, 0); this.payload = this.payload.subarray(1); } incomingRSSI; toLogEntry() { const { tags, message: original } = super.toLogEntry(); const message = { ...original, "incoming RSSI": (0, import_core.rssiToString)(this.incomingRSSI) }; if (this.payload.length > 0) { message.payload = (0, import_shared.buffer2hex)(this.payload); } return { tags, message }; } } class ZWaveMPDU { static { __name(this, "ZWaveMPDU"); } constructor(options) { const data = options.data; this.frameInfo = options.frameInfo; let destinationOffset = 8; const frameControl = data.subarray(5, 7); switch (options.frameInfo.channel) { case 0: case 1: { this.routed = !!(frameControl[0] & 128); this.ackRequested = !!(frameControl[0] & 64); this.lowPower = !!(frameControl[0] & 32); this.speedModified = !!(frameControl[0] & 16); this.headerType = frameControl[0] & 15; this.beamingInfo = frameControl[1] & 96; this.sequenceNumber = frameControl[1] & 15; break; } case 2: { this.routed = false; this.ackRequested = !!(frameControl[0] & 128); this.lowPower = !!(frameControl[0] & 64); this.speedModified = false; this.headerType = frameControl[0] & 15; this.beamingInfo = frameControl[1] & 112; this.sequenceNumber = data[destinationOffset]; destinationOffset++; break; } case 3: case 4: { import_core.validatePayload.fail(`Channel ${options.frameInfo.channel} (ZWLR) must be parsed as a LongRangeMPDU!`); } default: { import_core.validatePayload.fail(`Unsupported channel ${options.frameInfo.channel}. MPDU payload: ${(0, import_shared.buffer2hex)(data)}`); } } const Constructor = this.headerType === import_core.MPDUHeaderType.Acknowledgement ? AckZWaveMPDU : this.headerType === import_core.MPDUHeaderType.Routed || this.headerType === import_core.MPDUHeaderType.Singlecast && this.routed ? RoutedZWaveMPDU : this.headerType === import_core.MPDUHeaderType.Singlecast ? SinglecastZWaveMPDU : this.headerType === import_core.MPDUHeaderType.Multicast ? MulticastZWaveMPDU : this.headerType === import_core.MPDUHeaderType.Explorer ? ExplorerZWaveMPDU : void 0; if (!Constructor) { import_core.validatePayload.fail(`Unsupported MPDU header type ${this.headerType}`); } else if (new.target !== Constructor && !(0, import_shared.staticExtends)(new.target, Constructor)) { return new Constructor(options); } this.homeId = data.readUInt32BE(0); this.sourceNodeId = data[4]; const destinationLength = this.headerType === import_core.MPDUHeaderType.Multicast ? 30 : 1; this.destinationBuffer = data.subarray(destinationOffset, destinationOffset + destinationLength); this.payload = data.subarray(destinationOffset + destinationLength); } frameInfo; homeId; sourceNodeId; routed; ackRequested; lowPower; speedModified; headerType; beamingInfo; sequenceNumber; destinationBuffer; payload; static from(msg) { return new ZWaveMPDU({ data: msg.payload, frameInfo: (0, import_shared.pick)(msg, [ "channel", "frameType", "region", "protocolDataRate", "rssiRaw" ]) }); } toLogEntry() { const tags = [formatNodeId(this.sourceNodeId)]; const message = { "sequence no.": this.sequenceNumber, channel: this.frameInfo.channel, "protocol/data rate": (0, import_core.znifferProtocolDataRateToString)(this.frameInfo.protocolDataRate) + (this.speedModified ? " (reduced)" : ""), RSSI: this.frameInfo.rssi != void 0 ? (0, import_core.rssiToString)(this.frameInfo.rssi) : this.frameInfo.rssiRaw.toString() }; return { tags, message }; } } class SinglecastZWaveMPDU extends ZWaveMPDU { static { __name(this, "SinglecastZWaveMPDU"); } constructor(options) { super(options); this.destinationNodeId = this.destinationBuffer[0]; } destinationNodeId; toLogEntry() { const { tags, message: original } = super.toLogEntry(); tags[0] = formatRoute( this.sourceNodeId, [], this.destinationNodeId, // Singlecast frames do not contain a bit for this, we consider them all "outbound" "outbound", 0 ); const message = { ...original, "ack requested": this.ackRequested, payload: (0, import_shared.buffer2hex)(this.payload) }; return { tags, message }; } } class AckZWaveMPDU extends ZWaveMPDU { static { __name(this, "AckZWaveMPDU"); } constructor(options) { super(options); this.destinationNodeId = this.destinationBuffer[0]; } destinationNodeId; toLogEntry() { const { tags, message } = super.toLogEntry(); tags[0] = formatRoute( this.sourceNodeId, [], this.destinationNodeId, // ACK frames do not contain a bit for this, we consider them all "inbound" "inbound", 0 ); tags.unshift("ACK"); return { tags, message }; } } class RoutedZWaveMPDU extends ZWaveMPDU { static { __name(this, "RoutedZWaveMPDU"); } constructor(options) { super(options); const channelConfig = getChannelConfiguration(this.frameInfo.region); this.direction = this.payload[0] & 1 ? "inbound" : "outbound"; this.routedAck = !!(this.payload[0] & 2); this.routedError = !!(this.payload[0] & 4); const hasExtendedHeader = !!(this.payload[0] & 8); if (this.routedError) { this.failedHop = this.payload[0] >>> 4; } else if (channelConfig === "1/2") { this.speedModified = !!(this.payload[0] & 16); } this.hop = this.payload[1] & 15; if (this.direction === "inbound") { this.hop = (this.hop + 1) % 16; } const numRepeaters = this.payload[1] >>> 4; this.repeaters = [...this.payload.subarray(2, 2 + numRepeaters)]; let offset = 2 + numRepeaters; if (channelConfig === "3") { this.destinationWakeup = this.payload[offset++] === 2; } if (hasExtendedHeader) { const headerPreamble = this.payload[offset++]; const headerLength = headerPreamble >>> 4; const headerType = headerPreamble & 15; const header = this.payload.subarray(offset, offset + headerLength); offset += headerLength; if (headerType === 0) { this.destinationWakeupType = header[0] & 64 ? "1000ms" : header[0] & 32 ? "250ms" : void 0; } else if (headerType === 1) { const repeaterRSSI = []; for (let i = 0; i < numRepeaters; i++) { repeaterRSSI.push((0, import_serialapi.parseRSSI)(header, i)); } this.repeaterRSSI = repeaterRSSI; } } this.payload = this.payload.subarray(offset); this.destinationNodeId = this.destinationBuffer[0]; } destinationNodeId; direction; routedAck; routedError; failedHop; hop; repeaters; destinationWakeup; destinationWakeupType; repeaterRSSI; toLogEntry() { const { tags, message: original } = super.toLogEntry(); tags[0] = formatRoute(this.sourceNodeId, this.repeaters, this.destinationNodeId, this.direction, this.hop, this.failedHop); const message = { ...original, "ack requested": this.ackRequested, payload: (0, import_shared.buffer2hex)(this.payload) }; return { tags, message }; } } class MulticastZWaveMPDU extends ZWaveMPDU { static { __name(this, "MulticastZWaveMPDU"); } constructor(options) { super(options); const control = this.destinationBuffer[0]; import_core.validatePayload.withReason("Invalid multicast control byte")(control === 29); this.destinationNodeIds = (0, import_core.parseNodeBitMask)(this.destinationBuffer.subarray(1)); } destinationNodeIds; toLogEntry() { const { tags, message: original } = super.toLogEntry(); tags.push("MULTICAST"); const message = { destinations: this.destinationNodeIds.join(", "), ...original, payload: (0, import_shared.buffer2hex)(this.payload) }; return { tags, message }; } } class ExplorerZWaveMPDU extends ZWaveMPDU { static { __name(this, "ExplorerZWaveMPDU"); } constructor(options) { super(options); this.version = this.payload[0] >>> 5; this.command = this.payload[0] & 31; this.stop = !!(this.payload[1] & 4); this.direction = this.payload[1] & 2 ? "inbound" : "outbound"; this.sourceRouted = !!(this.payload[1] & 1); this.randomTXInterval = this.payload[2]; this.ttl = this.payload[3] >>> 4; const numRepeaters = this.payload[3] & 15; this.repeaters = [...this.payload.subarray(4, 4 + numRepeaters)]; const Constructor = this.command === import_Types.ExplorerFrameCommand.Normal ? NormalExplorerZWaveMPDU : this.command === import_Types.ExplorerFrameCommand.InclusionRequest ? InclusionRequestExplorerZWaveMPDU : this.command === import_Types.ExplorerFrameCommand.SearchResult ? SearchResultExplorerZWaveMPDU : void 0; if (!Constructor) { import_core.validatePayload.fail(`Unsupported Explorer MPDU command ${this.command}`); } else if (new.target !== Constructor && !(0, import_shared.staticExtends)(new.target, Constructor)) { return new Constructor(options); } this.destinationNodeId = this.destinationBuffer[0]; this.payload = this.payload.subarray(8); } destinationNodeId; version; command; stop; sourceRouted; direction; randomTXInterval; ttl; repeaters; } class NormalExplorerZWaveMPDU extends ExplorerZWaveMPDU { static { __name(this, "NormalExplorerZWaveMPDU"); } toLogEntry() { const { tags, message: original } = super.toLogEntry(); tags[0] = formatRoute( this.sourceNodeId, this.repeaters, this.destinationNodeId, // Explorer frames do not contain a bit for the direction, we consider them all "outbound" "outbound", 4 - this.ttl ); tags.unshift("EXPLORER"); const message = { ...original, "ack requested": this.ackRequested, payload: (0, import_shared.buffer2hex)(this.payload) }; return { tags, message }; } } class InclusionRequestExplorerZWaveMPDU extends ExplorerZWaveMPDU { static { __name(this, "InclusionRequestExplorerZWaveMPDU"); } constructor(options) { super(options); this.networkHomeId = this.payload.readUInt32BE(0); this.payload = this.payload.subarray(4); } /** The home ID of the repeating node */ networkHomeId; toLogEntry() { const { tags, message: original } = super.toLogEntry(); tags[0] = formatRoute( this.sourceNodeId, this.repeaters, this.destinationNodeId, // Explorer frames do not contain a bit for the direction, we consider them all "outbound" "outbound", 4 - this.ttl ); tags.unshift("INCL REQUEST"); const message = { ...original, "network home ID": this.networkHomeId.toString(16).padStart(8, "0"), payload: (0, import_shared.buffer2hex)(this.payload) }; return { tags, message }; } } class SearchResultExplorerZWaveMPDU extends ExplorerZWaveMPDU { static { __name(this, "SearchResultExplorerZWaveMPDU"); } constructor(options) { super(options); this.searchingNodeId = this.payload[0]; this.frameHandle = this.payload[1]; this.resultTTL = this.payload[2] >>> 4; const numRepeaters = this.payload[2] & 15; this.resultRepeaters = [ ...this.payload.subarray(3, 3 + numRepeaters) ]; this.payload = new import_shared.Bytes(); } /** The node ID that sent the explorer frame that's being answered here */ searchingNodeId; /** The sequence number of the original explorer frame */ frameHandle; resultTTL; resultRepeaters; toLogEntry() { const { tags, message: original } = super.toLogEntry(); tags[0] = formatRoute( this.sourceNodeId, this.repeaters, this.destinationNodeId, // Explorer frames do not contain a bit for the direction, we consider their responses "inbound" "inbound", 4 - this.ttl ); tags.unshift("EXPLORER RESULT"); const message = { ...original, "frame handle": this.frameHandle, "result TTL": this.resultTTL, "result repeaters": this.resultRepeaters.join(", ") }; return { tags, message }; } } function parseBeamFrame(frame) { if (frame.frameType === import_serial.ZnifferFrameType.BeamStop) { return new BeamStop({ data: frame.payload, frameInfo: frame }); } const channelConfig = getChannelConfiguration(frame.region); switch (channelConfig) { case "1/2": case "3": { return new ZWaveBeamStart({ data: frame.payload, frameInfo: frame }); } case "4": { return new LongRangeBeamStart({ data: frame.payload, frameInfo: frame }); } default: import_core.validatePayload.fail( // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Unsupported channel configuration ${channelConfig}. MPDU payload: ${(0, import_shared.buffer2hex)(frame.payload)}` ); } } __name(parseBeamFrame, "parseBeamFrame"); class ZWaveBeamStart { static { __name(this, "ZWaveBeamStart"); } constructor(options) { const data = options.data; this.frameInfo = options.frameInfo; switch (options.frameInfo.channel) { case 0: case 1: case 2: break; case 3: case 4: { import_core.validatePayload.fail(`Channel ${options.frameInfo.channel} (ZWLR) must be parsed as a LongRangeMPDU!`); } default: { import_core.validatePayload.fail(`Unsupported channel ${options.frameInfo.channel}. MPDU payload: ${(0, import_shared.buffer2hex)(data)}`); } } this.destinationNodeId = data[1]; if (data[2] === 1) { this.homeIdHash = data[3]; } } frameInfo; homeIdHash; destinationNodeId; toLogEntry() { const tags = [ `BEAM \xBB ${formatNodeId(this.destinationNodeId)}` ]; const message = { channel: this.frameInfo.channel, "protocol/data rate": (0, import_core.znifferProtocolDataRateToString)(this.frameInfo.protocolDataRate), RSSI: this.frameInfo.rssi != void 0 ? (0, import_core.rssiToString)(this.frameInfo.rssi) : this.frameInfo.rssiRaw.toString() }; return { tags, message }; } } class LongRangeBeamStart { static { __name(this, "LongRangeBeamStart"); } constructor(options) { const data = options.data; this.frameInfo = options.frameInfo; switch (options.frameInfo.channel) { case 0: case 1: case 2: import_core.validatePayload.fail(`Channel ${options.frameInfo.channel} (Mesh) must be parsed as a ZWaveMPDU!`); case 3: case 4: { break; } default: { import_core.validatePayload.fail(`Unsupported channel ${options.frameInfo.channel}. MPDU payload: ${(0, import_shared.buffer2hex)(data)}`); } } const txPower = data[1] >>> 4; this.txPower = longRangeBeamPowerToDBm(txPower); this.destinationNodeId = data.readUInt16BE(1) & 4095; this.homeIdHash = data[3]; } frameInfo; homeIdHash; destinationNodeId; txPower; toLogEntry() { const tags = [ `BEAM \xBB ${formatNodeId(this.destinationNodeId)}` ]; const message = { channel: this.frameInfo.channel, "protocol/data rate": (0, import_core.znifferProtocolDataRateToString)(this.frameInfo.protocolDataRate), "TX power": `${this.txPower} dBm`, RSSI: this.frameInfo.rssi != void 0 ? (0, import_core.rssiToString)(this.frameInfo.rssi) : this.frameInfo.rssiRaw.toString() }; return { tags, message }; } } class BeamStop { static { __name(this, "BeamStop"); } constructor(options) { this.frameInfo = options.frameInfo; } frameInfo; toLogEntry() { const tags = [ "BEAM STOP" ]; const message = { channel: this.frameInfo.channel }; return { tags, message }; } } function mpduToFrame(mpdu, payloadCC) { if (mpdu instanceof ZWaveMPDU) { return mpduToZWaveFrame(mpdu, payloadCC); } else if (mpdu instanceof LongRangeMPDU) { return mpduToLongRangeFrame(mpdu, payloadCC); } throw new import_core.ZWaveError(`mpduToFrame not supported for ${mpdu.constructor.name}`, import_core.ZWaveErrorCodes.Argument_Invalid); } __name(mpduToFrame, "mpduToFrame"); function mpduToZWaveFrame(mpdu, payloadCC) { const retBase = { protocol: import_core.Protocols.ZWave, channel: mpdu.frameInfo.channel, region: mpdu.frameInfo.region, rssiRaw: mpdu.frameInfo.rssiRaw, rssi: mpdu.frameInfo.rssi, protocolDataRate: mpdu.frameInfo.protocolDataRate, speedModified: mpdu.speedModified, sequenceNumber: mpdu.sequenceNumber, homeId: mpdu.homeId, sourceNodeId: mpdu.sourceNodeId }; if (mpdu instanceof SinglecastZWaveMPDU) { const ret = { ...retBase, ackRequested: mpdu.ackRequested, payload: payloadCC ?? mpdu.payload }; if (mpdu.destinationNodeId === import_core.NODE_ID_BROADCAST) { return { type: import_Types.ZWaveFrameType.Broadcast, destinationNodeId: mpdu.destinationNodeId, ...ret }; } else { return { type: import_Types.ZWaveFrameType.Singlecast, destinationNodeId: mpdu.destinationNodeId, ...ret }; } } else if (mpdu instanceof AckZWaveMPDU) { return { type: import_Types.ZWaveFrameType.AckDirect, ...retBase, destinationNodeId: mpdu.destinationNodeId }; } else if (mpdu instanceof MulticastZWaveMPDU) { return { type: import_Types.ZWaveFrameType.Multicast, ...retBase, destinationNodeIds: [...mpdu.destinationNodeIds], payload: payloadCC ?? mpdu.payload }; } else if (mpdu instanceof RoutedZWaveMPDU) { return { type: import_Types.ZWaveFrameType.Singlecast, ...retBase, destinationNodeId: mpdu.destinationNodeId, ackRequested: mpdu.ackRequested, payload: payloadCC ?? mpdu.payload, direction: mpdu.direction, hop: mpdu.hop, repeaters: [...mpdu.repeaters], repeaterRSSI: mpdu.repeaterRSSI && [...mpdu.repeaterRSSI], routedAck: mpdu.routedAck, routedError: mpdu.routedError, failedHop: mpdu.failedHop }; } else if (mpdu instanceof ExplorerZWaveMPDU) { const explorerBase = { ...retBase, destinationNodeId: mpdu.destinationNodeId, ackRequested: mpdu.ackRequested, direction: mpdu.direction, repeaters: [...mpdu.repeaters], ttl: mpdu.ttl }; if (mpdu instanceof NormalExplorerZWaveMPDU) { return { type: import_Types.ZWaveFrameType.ExplorerNormal, payload: payloadCC ?? mpdu.payload, ...explorerBase }; } else if (mpdu instanceof SearchResultExplorerZWaveMPDU) { return { type: import_Types.ZWaveFrameType.ExplorerSearchResult, ...explorerBase, searchingNodeId: mpdu.searchingNodeId, frameHandle: mpdu.frameHandle, resultTTL: mpdu.resultTTL, resultRepeaters: [...mpdu.resultRepeaters] }; } else if (mpdu instanceof InclusionRequestExplorerZWaveMPDU) { return { type: import_Types.ZWaveFrameType.ExplorerInclusionRequest, payload: payloadCC ?? mpdu.payload, ...explorerBase, networkHomeId: mpdu.networkHomeId }; } } throw new import_core.ZWaveError(`mpduToZWaveFrame not supported for ${mpdu.constructor.name}`, import_core.ZWaveErrorCodes.Argument_Invalid); } __name(mpduToZWaveFrame, "mpduToZWaveFrame"); function mpduToLongRangeFrame(mpdu, payloadCC) { const retBase = { protocol: import_core.Protocols.ZWaveLongRange, channel: mpdu.frameInfo.channel, region: mpdu.frameInfo.region, protocolDataRate: mpdu.frameInfo.protocolDataRate, rssiRaw: mpdu.frameInfo.rssiRaw, rssi: mpdu.frameInfo.rssi, noiseFloor: mpdu.noiseFloor, txPower: mpdu.txPower, sequenceNumber: mpdu.sequenceNumber, homeId: mpdu.homeId, sourceNodeId: mpdu.sourceNodeId, destinationNodeId: mpdu.destinationNodeId }; if (mpdu instanceof SinglecastLongRangeMPDU) { const ret = { ...retBase, ackRequested: mpdu.ackRequested, payload: payloadCC ?? mpdu.payload }; if (mpdu.destinationNodeId === import_core.NODE_ID_BROADCAST_LR) { return { type: import_Types.LongRangeFrameType.Broadcast, ...ret, destinationNodeId: mpdu.destinationNodeId // Make TS happy }; } else { return { type: import_Types.LongRangeFrameType.Singlecast, ...ret }; } } else if (mpdu instanceof AckLongRangeMPDU) { return { type: import_Types.LongRangeFrameType.Ack, ...retBase, incomingRSSI: mpdu.incomingRSSI, payload: mpdu.payload }; } throw new import_core.ZWaveError(`mpduToLongRangeFrame not supported for ${mpdu.constructor.name}`, import_core.ZWaveErrorCodes.Argument_Invalid); } __name(mpduToLongRangeFrame, "mpduToLongRangeFrame"); function beamToFrame(beam) { const retBase = { channel: beam.frameInfo.channel, region: beam.frameInfo.region, rssiRaw: beam.frameInfo.rssiRaw, rssi: beam.frameInfo.rssi, protocolDataRate: beam.frameInfo.protocolDataRate }; if (beam instanceof ZWaveBeamStart) { return { protocol: import_core.Protocols.ZWave, type: import_Types.ZWaveFrameType.BeamStart, ...retBase, destinationNodeId: beam.destinationNodeId, homeIdHash: beam.homeIdHash }; } else if (beam instanceof LongRangeBeamStart) { return { protocol: import_core.Protocols.ZWaveLongRange, type: import_Types.LongRangeFrameType.BeamStart, ...retBase, destinationNodeId: beam.destinationNodeId, homeIdHash: beam.homeIdHash, txPower: beam.txPower }; } else { const isLR = beam.frameInfo.channel === 4; if (isLR) { return { protocol: import_core.Protocols.ZWaveLongRange, type: import_Types.LongRangeFrameType.BeamStop, channel: beam.frameInfo.channel }; } else { return { protocol: import_core.Protocols.ZWave, type: import_Types.ZWaveFrameType.BeamStop, channel: beam.frameInfo.channel }; } } } __name(beamToFrame, "beamToFrame"); function znifferDataMessageToCorruptedFrame(msg, rssi) { if (msg.checksumOK) { throw new import_core.ZWaveError(`znifferDataMessageToCorruptedFrame expects the checksum to be incorrect`, import_core.ZWaveErrorCodes.Argument_Invalid); } return { channel: msg.channel, region: msg.region, rssiRaw: msg.rssiRaw, rssi, protocolDataRate: msg.protocolDataRate, payload: msg.payload }; } __name(znifferDataMessageToCorruptedFrame, "znifferDataMessageToCorruptedFrame"); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { AckLongRangeMPDU, AckZWaveMPDU, BeamStop, ExplorerZWaveMPDU, InclusionRequestExplorerZWaveMPDU, LongRangeBeamStart, LongRangeMPDU, MulticastZWaveMPDU, NormalExplorerZWaveMPDU, RoutedZWaveMPDU, SearchResultExplorerZWaveMPDU, SinglecastLongRangeMPDU, SinglecastZWaveMPDU, ZWaveBeamStart, ZWaveMPDU, beamToFrame, mpduToFrame, mpduToLongRangeFrame, mpduToZWaveFrame, parseBeamFrame, parseMPDU, znifferDataMessageToCorruptedFrame }); //# sourceMappingURL=MPDU.js.map