zwave-js
Version:
Z-Wave driver written entirely in JavaScript/TypeScript
129 lines • 5.15 kB
JavaScript
import { isEncapsulatingCommandClass, isMultiEncapsulatingCommandClass, } from "@zwave-js/cc";
import { ZWaveLoggerBase, getDirectionPrefix, messageRecordToLines, rssiToString, tagify, znifferProtocolDataRateToString, } from "@zwave-js/core";
import { buffer2hex, num2hex } from "@zwave-js/shared";
export const ZNIFFER_LABEL = "ZNIFFR";
const ZNIFFER_LOGLEVEL = "info";
export class ZnifferLogger extends ZWaveLoggerBase {
zniffer;
constructor(zniffer, loggers) {
super(loggers, ZNIFFER_LABEL);
this.zniffer = zniffer;
}
isLogVisible() {
return this.container.isLoglevelVisible(ZNIFFER_LOGLEVEL);
}
/**
* Logs a message
* @param msg The message to output
*/
print(message, level) {
const actualLevel = level || ZNIFFER_LOGLEVEL;
if (!this.container.isLoglevelVisible(actualLevel))
return;
this.logger.log({
level: actualLevel,
message,
direction: getDirectionPrefix("none"),
context: { source: "zniffer", direction: "none" },
});
}
crcError(frame, rssi) {
if (!this.isLogVisible())
return;
const logEntry = {
tags: ["CRC ERROR"],
message: {
channel: frame.channel,
"protocol/data rate": znifferProtocolDataRateToString(frame.protocolDataRate),
RSSI: rssi != undefined
? rssiToString(rssi)
: frame.rssiRaw.toString(),
payload: buffer2hex(frame.payload),
},
};
const msg = [tagify(logEntry.tags)];
msg.push(...messageRecordToLines(logEntry.message).map((line) => " " + line));
try {
// If possible, include information about the CCs
this.logger.log({
level: "warn",
message: msg,
direction: getDirectionPrefix("inbound"),
context: { source: "zniffer", direction: "inbound" },
});
}
catch { }
}
mpdu(mpdu, payloadCC) {
if (!this.isLogVisible())
return;
const hasPayload = !!payloadCC || mpdu.payload.length > 0;
const logEntry = mpdu.toLogEntry();
let msg = [tagify(logEntry.tags)];
if (logEntry.message) {
msg.push(...messageRecordToLines(logEntry.message).map((line) => (hasPayload ? "│ " : " ") + line));
}
try {
// If possible, include information about the CCs
if (!!payloadCC) {
// Remove the default payload message and draw a bracket
msg = msg.filter((line) => !line.startsWith("│ payload:"));
const logCC = (cc, indent = 0) => {
const isEncapCC = isEncapsulatingCommandClass(cc)
|| isMultiEncapsulatingCommandClass(cc);
const loggedCC = cc.toLogEntry(this.zniffer);
msg.push(" ".repeat(indent * 2) + "└─" + tagify(loggedCC.tags));
indent++;
if (loggedCC.message) {
msg.push(...messageRecordToLines(loggedCC.message).map((line) => `${" ".repeat(indent * 2)}${isEncapCC ? "│ " : " "}${line}`));
}
// If this is an encap CC, continue
if (isEncapsulatingCommandClass(cc)) {
logCC(cc.encapsulated, indent);
}
else if (isMultiEncapsulatingCommandClass(cc)) {
for (const encap of cc.encapsulated) {
logCC(encap, indent);
}
}
};
logCC(payloadCC);
}
const homeId = mpdu.homeId.toString(16).padStart(8, "0")
.toLowerCase();
this.logger.log({
level: ZNIFFER_LOGLEVEL,
secondaryTags: tagify([homeId]),
message: msg,
direction: getDirectionPrefix("inbound"),
context: { source: "zniffer", direction: "inbound" },
});
}
catch { }
}
beam(beam) {
if (!this.isLogVisible())
return;
const logEntry = beam.toLogEntry();
const msg = [tagify(logEntry.tags)];
if (logEntry.message) {
msg.push(...messageRecordToLines(logEntry.message).map((line) => (" ") + line));
}
try {
// If possible, include information about the CCs
let secondaryTags;
if ("homeIdHash" in beam && beam.homeIdHash) {
secondaryTags = tagify([`hash: ${num2hex(beam.homeIdHash)}`]);
}
this.logger.log({
level: ZNIFFER_LOGLEVEL,
secondaryTags,
message: msg,
direction: getDirectionPrefix("inbound"),
context: { source: "zniffer", direction: "inbound" },
});
}
catch { }
}
}
//# sourceMappingURL=Zniffer.js.map