zwave-js
Version:
Z-Wave driver written entirely in JavaScript/TypeScript
265 lines (264 loc) • 11.9 kB
JavaScript
;
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 NotificationCC_exports = {};
__export(NotificationCC_exports, {
getDefaultNotificationHandlerStore: () => getDefaultNotificationHandlerStore,
handleNotificationReport: () => handleNotificationReport,
manuallyIdleNotificationValueInternal: () => manuallyIdleNotificationValueInternal
});
module.exports = __toCommonJS(NotificationCC_exports);
var import_cc = require("@zwave-js/cc");
var import_NotificationCC = require("@zwave-js/cc/NotificationCC");
var import_core = require("@zwave-js/core");
var import_shared = require("@zwave-js/shared");
function getDefaultNotificationHandlerStore() {
return {
idleTimeouts: /* @__PURE__ */ new Map()
};
}
__name(getDefaultNotificationHandlerStore, "getDefaultNotificationHandlerStore");
function handleNotificationReport(ctx, node, command, store) {
if (command.notificationType == void 0) {
if (command.alarmType == void 0) {
ctx.logNode(node.id, {
message: `received unsupported notification ${(0, import_shared.stringify)(command)}`,
direction: "inbound"
});
}
return;
}
const ccVersion = (0, import_cc.getEffectiveCCVersion)(ctx, command);
const notification = (0, import_core.getNotification)(command.notificationType);
if (notification) {
const notificationName = notification.name;
ctx.logNode(node.id, {
message: `[handleNotificationReport] notificationName: ${notificationName}`,
level: "silly"
});
const setStateIdle = /* @__PURE__ */ __name((prevValue) => {
manuallyIdleNotificationValueInternal(ctx, node, store, notification, prevValue, command.endpointIndex);
}, "setStateIdle");
const setUnknownStateIdle = /* @__PURE__ */ __name((prevValue) => {
const unknownNotificationVariableValueId = import_cc.NotificationCCValues.unknownNotificationVariable(command.notificationType, notificationName).endpoint(command.endpointIndex);
const currentValue = node.valueDB.getValue(unknownNotificationVariableValueId);
if (currentValue == void 0)
return;
if (prevValue == void 0 || currentValue === prevValue) {
node.valueDB.setValue(unknownNotificationVariableValueId, 0);
}
}, "setUnknownStateIdle");
const value = command.notificationEvent;
if (value === 0) {
if ((0, import_shared.isUint8Array)(command.eventParameters) && command.eventParameters.length) {
setStateIdle(command.eventParameters[0]);
setUnknownStateIdle(command.eventParameters[0]);
} else {
const nonIdleValues = node.valueDB.getValues(import_core.CommandClasses.Notification).filter((v) => (v.endpoint || 0) === command.endpointIndex && v.property === notificationName && typeof v.value === "number" && v.value !== 0);
for (const v of nonIdleValues) {
setStateIdle(v.value);
}
setUnknownStateIdle();
}
return;
}
const valueConfig = (0, import_core.getNotificationValue)(notification, value);
if (valueConfig) {
ctx.logNode(node.id, {
message: `[handleNotificationReport] valueConfig:
label: ${valueConfig.label}
${valueConfig.type === "event" ? "type: event" : `type: state
variableName: ${valueConfig.variableName}`}`,
level: "silly"
});
} else {
ctx.logNode(node.id, {
message: `[handleNotificationReport] valueConfig: undefined`,
level: "silly"
});
}
handleKnownNotification(ctx, node, command);
let allowIdleReset;
if (!valueConfig) {
allowIdleReset = false;
} else if (valueConfig.type === "state") {
allowIdleReset = valueConfig.idle;
} else {
const endpoint = node.getEndpoint(command.endpointIndex) ?? node;
node.emit("notification", endpoint, import_core.CommandClasses.Notification, {
type: command.notificationType,
event: value,
label: notification.name,
eventLabel: valueConfig.label,
parameters: command.eventParameters
});
if (valueConfig.idleVariables?.length) {
for (const variable of valueConfig.idleVariables) {
setStateIdle(variable);
}
}
return;
}
let valueId;
if (valueConfig) {
valueId = import_cc.NotificationCCValues.notificationVariable(notificationName, valueConfig.variableName).endpoint(command.endpointIndex);
extendNotificationValueMetadata(ctx, node, valueId, notification, valueConfig);
} else {
const unknownValue = import_cc.NotificationCCValues.unknownNotificationVariable(command.notificationType, notificationName);
valueId = unknownValue.endpoint(command.endpointIndex);
if (ccVersion >= 2) {
if (!node.valueDB.hasMetadata(valueId)) {
node.valueDB.setMetadata(valueId, unknownValue.meta);
}
}
}
if (typeof command.eventParameters === "number") {
const enumBehavior = valueConfig ? (0, import_NotificationCC.getNotificationEnumBehavior)(notification, valueConfig) : "extend";
const valueWithEnum = enumBehavior === "replace" ? command.eventParameters : (0, import_NotificationCC.getNotificationStateValueWithEnum)(value, command.eventParameters);
node.valueDB.setValue(valueId, valueWithEnum);
} else {
node.valueDB.setValue(valueId, value);
}
if (allowIdleReset && !!node.deviceConfig?.compat?.forceNotificationIdleReset) {
ctx.logNode(node.id, {
message: `[handleNotificationReport] scheduling idle reset`,
level: "silly"
});
scheduleNotificationIdleReset(store, valueId, () => setStateIdle(value));
}
} else {
const unknownValue = import_cc.NotificationCCValues.unknownNotificationType(command.notificationType);
const valueId = unknownValue.endpoint(command.endpointIndex);
if (ccVersion >= 2) {
if (!node.valueDB.hasMetadata(valueId)) {
node.valueDB.setMetadata(valueId, unknownValue.meta);
}
}
node.valueDB.setValue(valueId, command.notificationEvent);
}
}
__name(handleNotificationReport, "handleNotificationReport");
function handleKnownNotification(ctx, node, command) {
const lockEvents = /* @__PURE__ */ new Set([1, 3, 5, 9]);
const unlockEvents = /* @__PURE__ */ new Set([2, 4, 6]);
const doorStatusEvents = [
// Actual status
22,
23,
// Synthetic status with enum
5632,
5633
];
if (
// Access Control, manual/keypad/rf/auto (un)lock operation
command.notificationType === 6 && (lockEvents.has(command.notificationEvent) || unlockEvents.has(command.notificationEvent)) && (node.supportsCC(import_core.CommandClasses["Door Lock"]) || node.supportsCC(import_core.CommandClasses.Lock))
) {
const isLocked = lockEvents.has(command.notificationEvent);
if (node.supportsCC(import_core.CommandClasses["Door Lock"])) {
node.valueDB.setValue(import_cc.DoorLockCCValues.currentMode.endpoint(command.endpointIndex), isLocked ? import_cc.DoorLockMode.Secured : import_cc.DoorLockMode.Unsecured);
}
if (node.supportsCC(import_core.CommandClasses.Lock)) {
node.valueDB.setValue(import_cc.LockCCValues.locked.endpoint(command.endpointIndex), isLocked);
}
} else if (command.notificationType === 6 && doorStatusEvents.includes(command.notificationEvent)) {
node.valueDB.setValue(import_cc.NotificationCCValues.doorStateSimple.endpoint(command.endpointIndex), command.notificationEvent === 23 ? 23 : 22);
const tiltValue = import_cc.NotificationCCValues.doorTiltState;
const tiltValueId = tiltValue.endpoint(command.endpointIndex);
let tiltValueWasCreated = node.valueDB.hasMetadata(tiltValueId);
if (command.eventParameters === 1 && !tiltValueWasCreated) {
node.valueDB.setMetadata(tiltValueId, tiltValue.meta);
tiltValueWasCreated = true;
}
if (tiltValueWasCreated) {
node.valueDB.setValue(tiltValueId, command.eventParameters === 1 ? 1 : 0);
}
} else if (
// Access Control, all user codes deleted
command.notificationType === 6 && command.notificationEvent === 12 && node.supportsCC(import_core.CommandClasses["User Code"])
) {
const endpoint = {
nodeId: node.id,
index: command.endpointIndex,
virtual: false
};
const numUsers = import_cc.UserCodeCC.getSupportedUsersCached(ctx, endpoint) ?? 0;
for (let userId = 1; userId <= numUsers; userId++) {
import_cc.UserCodeCC.setUserIdStatusCached(ctx, endpoint, userId, import_cc.UserIDStatus.Available);
import_cc.UserCodeCC.setUserCodeCached(ctx, endpoint, userId, "");
}
}
}
__name(handleKnownNotification, "handleKnownNotification");
function manuallyIdleNotificationValueInternal(ctx, node, store, notification, prevValue, endpointIndex) {
const valueConfig = (0, import_core.getNotificationValue)(notification, prevValue);
if (!valueConfig || valueConfig.type !== "state")
return;
if (!valueConfig.idle)
return;
const notificationName = notification.name;
const variableName = valueConfig.variableName;
const valueId = import_cc.NotificationCCValues.notificationVariable(notificationName, variableName).endpoint(endpointIndex);
if (node.valueDB.getValue(valueId) !== prevValue)
return;
clearNotificationIdleReset(store, valueId);
extendNotificationValueMetadata(ctx, node, valueId, notification, valueConfig);
node.valueDB.setValue(
valueId,
0
/* idle */
);
}
__name(manuallyIdleNotificationValueInternal, "manuallyIdleNotificationValueInternal");
function scheduleNotificationIdleReset(store, valueId, handler) {
clearNotificationIdleReset(store, valueId);
const key = (0, import_core.valueIdToString)(valueId);
store.idleTimeouts.set(
key,
// Unref'ing long running timeouts allows to quit the application before the timeout elapses
(0, import_shared.setTimer)(
handler,
5 * 60 * 1e3
/* 5 minutes */
).unref()
);
}
__name(scheduleNotificationIdleReset, "scheduleNotificationIdleReset");
function clearNotificationIdleReset(store, valueId) {
const key = (0, import_core.valueIdToString)(valueId);
if (store.idleTimeouts.has(key)) {
store.idleTimeouts.get(key)?.clear();
store.idleTimeouts.delete(key);
}
}
__name(clearNotificationIdleReset, "clearNotificationIdleReset");
function extendNotificationValueMetadata(ctx, node, valueId, notification, valueConfig) {
const ccVersion = ctx.getSupportedCCVersion(import_core.CommandClasses.Notification, node.id, node.index);
if (ccVersion === 2 || !node.valueDB.hasMetadata(valueId)) {
const metadata = (0, import_NotificationCC.getNotificationValueMetadata)(node.valueDB.getMetadata(valueId), notification, valueConfig);
node.valueDB.setMetadata(valueId, metadata);
}
}
__name(extendNotificationValueMetadata, "extendNotificationValueMetadata");
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
getDefaultNotificationHandlerStore,
handleNotificationReport,
manuallyIdleNotificationValueInternal
});
//# sourceMappingURL=NotificationCC.js.map