zwave-js 14.3.3 → 14.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/lib/_version.d.ts +1 -1
- package/build/cjs/lib/_version.js +1 -1
- package/build/cjs/lib/_version.js.map +1 -1
- package/build/cjs/lib/controller/Controller.js +66 -60
- package/build/cjs/lib/controller/Controller.js.map +1 -1
- package/build/cjs/lib/controller/ControllerStatistics.js +4 -0
- package/build/cjs/lib/controller/ControllerStatistics.js.map +1 -1
- package/build/cjs/lib/controller/FirmwareUpdateService.js +8 -0
- package/build/cjs/lib/controller/FirmwareUpdateService.js.map +1 -1
- package/build/cjs/lib/controller/MockControllerBehaviors.js +3 -0
- package/build/cjs/lib/controller/MockControllerBehaviors.js.map +1 -1
- package/build/cjs/lib/controller/NVMIO.js +7 -0
- package/build/cjs/lib/controller/NVMIO.js.map +1 -1
- package/build/cjs/lib/controller/NodeInformationFrame.js +2 -0
- package/build/cjs/lib/controller/NodeInformationFrame.js.map +1 -1
- package/build/cjs/lib/controller/ZWaveSDKVersions.js +3 -0
- package/build/cjs/lib/controller/ZWaveSDKVersions.js.map +1 -1
- package/build/cjs/lib/controller/utils.js +4 -0
- package/build/cjs/lib/controller/utils.js.map +1 -1
- package/build/cjs/lib/driver/Bootloader.js +4 -0
- package/build/cjs/lib/driver/Bootloader.js.map +1 -1
- package/build/cjs/lib/driver/Driver.js +63 -56
- package/build/cjs/lib/driver/Driver.js.map +1 -1
- package/build/cjs/lib/driver/DriverMock.js +6 -3
- package/build/cjs/lib/driver/DriverMock.js.map +1 -1
- package/build/cjs/lib/driver/MessageGenerators.js +26 -18
- package/build/cjs/lib/driver/MessageGenerators.js.map +1 -1
- package/build/cjs/lib/driver/NetworkCache.js +43 -23
- package/build/cjs/lib/driver/NetworkCache.js.map +1 -1
- package/build/cjs/lib/driver/Queue.js +6 -2
- package/build/cjs/lib/driver/Queue.js.map +1 -1
- package/build/cjs/lib/driver/SerialAPICommandMachine.js +45 -40
- package/build/cjs/lib/driver/SerialAPICommandMachine.js.map +1 -1
- package/build/cjs/lib/driver/StateMachineShared.js +5 -0
- package/build/cjs/lib/driver/StateMachineShared.js.map +1 -1
- package/build/cjs/lib/driver/Statistics.js +4 -0
- package/build/cjs/lib/driver/Statistics.js.map +1 -1
- package/build/cjs/lib/driver/Task.js +9 -2
- package/build/cjs/lib/driver/Task.js.map +1 -1
- package/build/cjs/lib/driver/Transaction.js +8 -4
- package/build/cjs/lib/driver/Transaction.js.map +1 -1
- package/build/cjs/lib/driver/TransportServiceMachine.js +9 -7
- package/build/cjs/lib/driver/TransportServiceMachine.js.map +1 -1
- package/build/cjs/lib/driver/UpdateConfig.js +8 -4
- package/build/cjs/lib/driver/UpdateConfig.js.map +1 -1
- package/build/cjs/lib/driver/UserAgent.js +4 -0
- package/build/cjs/lib/driver/UserAgent.js.map +1 -1
- package/build/cjs/lib/driver/mDNSDiscovery.js +2 -0
- package/build/cjs/lib/driver/mDNSDiscovery.js.map +1 -1
- package/build/cjs/lib/log/Driver.js +6 -2
- package/build/cjs/lib/log/Driver.js.map +1 -1
- package/build/cjs/lib/log/Zniffer.js +6 -2
- package/build/cjs/lib/log/Zniffer.js.map +1 -1
- package/build/cjs/lib/node/DeviceClass.js +4 -0
- package/build/cjs/lib/node/DeviceClass.js.map +1 -1
- package/build/cjs/lib/node/Endpoint.js +9 -5
- package/build/cjs/lib/node/Endpoint.js.map +1 -1
- package/build/cjs/lib/node/HealthCheck.js +6 -0
- package/build/cjs/lib/node/HealthCheck.js.map +1 -1
- package/build/cjs/lib/node/MockNodeBehaviors.js +2 -0
- package/build/cjs/lib/node/MockNodeBehaviors.js.map +1 -1
- package/build/cjs/lib/node/MultiCCAPIWrapper.js +10 -8
- package/build/cjs/lib/node/MultiCCAPIWrapper.js.map +1 -1
- package/build/cjs/lib/node/Node.js +51 -46
- package/build/cjs/lib/node/Node.js.map +1 -1
- package/build/cjs/lib/node/NodeReadyMachine.js +3 -1
- package/build/cjs/lib/node/NodeReadyMachine.js.map +1 -1
- package/build/cjs/lib/node/NodeStatistics.js +5 -0
- package/build/cjs/lib/node/NodeStatistics.js.map +1 -1
- package/build/cjs/lib/node/NodeStatusMachine.js +5 -2
- package/build/cjs/lib/node/NodeStatusMachine.js.map +1 -1
- package/build/cjs/lib/node/VirtualEndpoint.js +8 -4
- package/build/cjs/lib/node/VirtualEndpoint.js.map +1 -1
- package/build/cjs/lib/node/VirtualNode.js +7 -2
- package/build/cjs/lib/node/VirtualNode.js.map +1 -1
- package/build/cjs/lib/node/mixins/00_Base.js +4 -0
- package/build/cjs/lib/node/mixins/00_Base.js.map +1 -1
- package/build/cjs/lib/node/mixins/01_NetworkRole.js +4 -0
- package/build/cjs/lib/node/mixins/01_NetworkRole.js.map +1 -1
- package/build/cjs/lib/node/mixins/05_Security.js +7 -3
- package/build/cjs/lib/node/mixins/05_Security.js.map +1 -1
- package/build/cjs/lib/node/mixins/10_Events.js +4 -0
- package/build/cjs/lib/node/mixins/10_Events.js.map +1 -1
- package/build/cjs/lib/node/mixins/20_Status.js +4 -0
- package/build/cjs/lib/node/mixins/20_Status.js.map +1 -1
- package/build/cjs/lib/node/mixins/30_Wakeup.js +4 -0
- package/build/cjs/lib/node/mixins/30_Wakeup.js.map +1 -1
- package/build/cjs/lib/node/mixins/40_Values.js +4 -0
- package/build/cjs/lib/node/mixins/40_Values.js.map +1 -1
- package/build/cjs/lib/node/mixins/50_Endpoints.js +4 -0
- package/build/cjs/lib/node/mixins/50_Endpoints.js.map +1 -1
- package/build/cjs/lib/node/mixins/60_ScheduledPoll.js +4 -0
- package/build/cjs/lib/node/mixins/60_ScheduledPoll.js.map +1 -1
- package/build/cjs/lib/node/mixins/70_FirmwareUpdate.js +8 -3
- package/build/cjs/lib/node/mixins/70_FirmwareUpdate.js.map +1 -1
- package/build/cjs/lib/node/mixins/index.js +4 -0
- package/build/cjs/lib/node/mixins/index.js.map +1 -1
- package/build/cjs/lib/node/mockCCBehaviors/ColorSwitch.js +2 -1
- package/build/cjs/lib/node/mockCCBehaviors/ColorSwitch.js.map +1 -1
- package/build/cjs/lib/node/mockCCBehaviors/Configuration.js +2 -1
- package/build/cjs/lib/node/mockCCBehaviors/Configuration.js.map +1 -1
- package/build/cjs/lib/node/mockCCBehaviors/ScheduleEntryLock.js +2 -1
- package/build/cjs/lib/node/mockCCBehaviors/ScheduleEntryLock.js.map +1 -1
- package/build/cjs/lib/node/mockCCBehaviors/ThermostatSetpoint.js +3 -2
- package/build/cjs/lib/node/mockCCBehaviors/ThermostatSetpoint.js.map +1 -1
- package/build/cjs/lib/node/mockCCBehaviors/UserCode.js +3 -2
- package/build/cjs/lib/node/mockCCBehaviors/UserCode.js.map +1 -1
- package/build/cjs/lib/node/utils.js +22 -2
- package/build/cjs/lib/node/utils.js.map +1 -1
- package/build/cjs/lib/telemetry/deviceConfig.js +2 -0
- package/build/cjs/lib/telemetry/deviceConfig.js.map +1 -1
- package/build/cjs/lib/telemetry/statistics.js +3 -0
- package/build/cjs/lib/telemetry/statistics.js.map +1 -1
- package/build/cjs/lib/zniffer/MPDU.js +57 -0
- package/build/cjs/lib/zniffer/MPDU.js.map +1 -1
- package/build/cjs/lib/zniffer/Zniffer.js +10 -3
- package/build/cjs/lib/zniffer/Zniffer.js.map +1 -1
- package/build/cjs/mockServer.js +14 -0
- package/build/cjs/mockServer.js.map +1 -1
- package/build/esm/lib/_version.d.ts +1 -1
- package/build/esm/lib/_version.js +1 -1
- package/package.json +12 -12
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/node/mixins/40_Values.ts"],
|
|
4
4
|
"sourcesContent": ["import {\n\ttype CCValueOptions,\n\tCommandClass,\n\tdefaultCCValueOptions,\n\tgetCCValues,\n} from \"@zwave-js/cc\";\nimport {\n\ttype CommandClasses,\n\ttype MaybeNotKnown,\n\ttype MetadataUpdatedArgs,\n\tValueDB,\n\ttype ValueID,\n\tValueMetadata,\n\ttype ValueUpdatedArgs,\n\tapplicationCCs,\n\tgetCCName,\n} from \"@zwave-js/core\";\nimport { pick } from \"@zwave-js/shared\";\nimport { type Driver } from \"../../driver/Driver.js\";\nimport { type DeviceClass } from \"../DeviceClass.js\";\nimport { type ZWaveNodeValueEventCallbacks } from \"../_Types.js\";\nimport * as nodeUtils from \"../utils.js\";\nimport { NodeWakeupMixin } from \"./30_Wakeup.js\";\n\n/** Defines functionality of Z-Wave nodes related to the value DB */\nexport interface NodeValues {\n\t/**\n\t * Provides access to this node's values\n\t * @internal\n\t */\n\treadonly valueDB: ValueDB;\n\n\t/**\n\t * Retrieves a stored value for a given value id.\n\t * This does not request an updated value from the node!\n\t */\n\tgetValue<T = unknown>(valueId: ValueID): MaybeNotKnown<T>;\n\n\t/**\n\t * Returns when the given value id was last updated by an update from the node.\n\t */\n\tgetValueTimestamp(valueId: ValueID): MaybeNotKnown<number>;\n\n\t/**\n\t * Retrieves metadata for a given value id.\n\t * This can be used to enhance the user interface of an application\n\t */\n\tgetValueMetadata(valueId: ValueID): ValueMetadata;\n}\n\nexport abstract class NodeValuesMixin extends NodeWakeupMixin\n\timplements NodeValues\n{\n\tpublic constructor(\n\t\tnodeId: number,\n\t\tdriver: Driver,\n\t\tendpointIndex: number,\n\t\tdeviceClass?: DeviceClass,\n\t\tsupportedCCs?: CommandClasses[],\n\t\tvalueDB?: ValueDB,\n\t) {\n\t\t// Define this node's intrinsic endpoint as the root device (0)\n\t\tsuper(nodeId, driver, endpointIndex, deviceClass, supportedCCs);\n\t\tthis._valueDB = valueDB\n\t\t\t?? new ValueDB(nodeId, driver.valueDB!, driver.metadataDB!);\n\n\t\t// Pass value events to our listeners\n\t\tfor (\n\t\t\tconst event of [\n\t\t\t\t\"value added\",\n\t\t\t\t\"value updated\",\n\t\t\t\t\"value removed\",\n\t\t\t\t\"value notification\",\n\t\t\t\t\"metadata updated\",\n\t\t\t] as const\n\t\t) {\n\t\t\tthis._valueDB.on(event, this.translateValueEvent.bind(this, event));\n\t\t}\n\t}\n\n\tprotected _valueDB: ValueDB;\n\tpublic get valueDB(): ValueDB {\n\t\treturn this._valueDB;\n\t}\n\n\tpublic getValue<T = unknown>(valueId: ValueID): MaybeNotKnown<T> {\n\t\treturn this._valueDB.getValue(valueId);\n\t}\n\n\tpublic getValueTimestamp(valueId: ValueID): MaybeNotKnown<number> {\n\t\treturn this._valueDB.getTimestamp(valueId);\n\t}\n\n\tpublic getValueMetadata(valueId: ValueID): ValueMetadata {\n\t\t// Check if a corresponding CC value is defined for this value ID\n\t\t// so we can extend the returned metadata\n\t\tconst definedCCValues = getCCValues(valueId.commandClass);\n\t\tlet valueOptions: Required<CCValueOptions> | undefined;\n\t\tlet meta: ValueMetadata | undefined;\n\t\tif (definedCCValues) {\n\t\t\tconst value = Object.values(definedCCValues)\n\t\t\t\t.find((v) => v?.is(valueId));\n\t\t\tif (value) {\n\t\t\t\tif (typeof value !== \"function\") {\n\t\t\t\t\tmeta = value.meta;\n\t\t\t\t}\n\t\t\t\tvalueOptions = value.options;\n\t\t\t}\n\t\t}\n\n\t\tconst existingMetadata = this._valueDB.getMetadata(valueId);\n\t\treturn {\n\t\t\t// The priority for returned metadata is valueDB > defined value > Any (default)\n\t\t\t...(existingMetadata ?? meta ?? ValueMetadata.Any),\n\t\t\t// ...except for these flags, which are taken from defined values:\n\t\t\tstateful: valueOptions?.stateful ?? defaultCCValueOptions.stateful,\n\t\t\tsecret: valueOptions?.secret ?? defaultCCValueOptions.secret,\n\t\t};\n\t}\n\n\t/**\n\t * Enhances the raw event args of the ValueDB so it can be consumed better by applications\n\t */\n\tprotected translateValueEvent<T extends ValueID>(\n\t\teventName: keyof ZWaveNodeValueEventCallbacks,\n\t\targ: T,\n\t): void {\n\t\t// Try to retrieve the speaking CC name\n\t\tconst outArg = nodeUtils.translateValueID(this.driver, this, arg);\n\t\t// This can happen for value updated events\n\t\tif (\"source\" in outArg) delete outArg.source;\n\n\t\tconst loglevel = this.driver.getLogConfig().level;\n\n\t\t// If this is a metadata event, make sure we return the merged metadata\n\t\tif (\"metadata\" in outArg) {\n\t\t\t(outArg as unknown as MetadataUpdatedArgs).metadata = this\n\t\t\t\t.getValueMetadata(arg);\n\t\t}\n\n\t\tconst ccInstance = CommandClass.createInstanceUnchecked(\n\t\t\tthis,\n\t\t\targ.commandClass,\n\t\t);\n\t\tconst isInternalValue = !!ccInstance?.isInternalValue(arg);\n\t\t// Check whether this value change may be logged\n\t\tconst isSecretValue = !!ccInstance?.isSecretValue(arg);\n\n\t\tif (loglevel === \"silly\") {\n\t\t\tthis.driver.controllerLog.logNode(this.id, {\n\t\t\t\tmessage: `[translateValueEvent: ${eventName}]\n commandClass: ${getCCName(arg.commandClass)}\n endpoint: ${arg.endpoint}\n property: ${arg.property}\n propertyKey: ${arg.propertyKey}\n internal: ${isInternalValue}\n secret: ${isSecretValue}\n event source: ${(arg as any as ValueUpdatedArgs).source}`,\n\t\t\t\tlevel: \"silly\",\n\t\t\t});\n\t\t}\n\n\t\tif (\n\t\t\t!isSecretValue\n\t\t\t&& (arg as any as ValueUpdatedArgs).source !== \"driver\"\n\t\t) {\n\t\t\t// Log the value change, except for updates caused by the driver itself\n\t\t\t// I don't like the splitting and any but its the easiest solution here\n\t\t\tconst [changeTarget, changeType] = eventName.split(\" \");\n\t\t\tconst logArgument = {\n\t\t\t\t...outArg,\n\t\t\t\tnodeId: this.id,\n\t\t\t\tinternal: isInternalValue,\n\t\t\t};\n\t\t\tif (changeTarget === \"value\") {\n\t\t\t\tthis.driver.controllerLog.value(\n\t\t\t\t\tchangeType as any,\n\t\t\t\t\tlogArgument as any,\n\t\t\t\t);\n\t\t\t} else if (changeTarget === \"metadata\") {\n\t\t\t\tthis.driver.controllerLog.metadataUpdated(logArgument);\n\t\t\t}\n\t\t}\n\n\t\t// Don't expose value events for internal value IDs...\n\t\tif (isInternalValue) return;\n\n\t\tif (loglevel === \"silly\") {\n\t\t\tthis.driver.controllerLog.logNode(this.id, {\n\t\t\t\tmessage: `[translateValueEvent: ${eventName}]\n is root endpoint: ${!arg.endpoint}\n is application CC: ${applicationCCs.includes(arg.commandClass)}\n should hide root values: ${\n\t\t\t\t\tnodeUtils.shouldHideRootApplicationCCValues(\n\t\t\t\t\t\tthis.driver,\n\t\t\t\t\t\tthis.id,\n\t\t\t\t\t)\n\t\t\t\t}`,\n\t\t\t\tlevel: \"silly\",\n\t\t\t});\n\t\t}\n\n\t\t// ... and root values ID that mirrors endpoint functionality\n\t\tif (\n\t\t\t// Only root endpoint values need to be filtered\n\t\t\t!arg.endpoint\n\t\t\t// Only application CCs need to be filtered\n\t\t\t&& applicationCCs.includes(arg.commandClass)\n\t\t\t// and only if the endpoints are not unnecessary and the root values mirror them\n\t\t\t&& nodeUtils.shouldHideRootApplicationCCValues(this.driver, this.id)\n\t\t) {\n\t\t\t// Iterate through all possible non-root endpoints of this node and\n\t\t\t// check if there is a value ID that mirrors root endpoint functionality\n\t\t\tfor (\n\t\t\t\tconst endpoint of nodeUtils.getEndpointIndizes(\n\t\t\t\t\tthis.driver,\n\t\t\t\t\tthis.id,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\tconst possiblyMirroredValueID: ValueID = {\n\t\t\t\t\t// same CC, property and key\n\t\t\t\t\t...pick(arg, [\"commandClass\", \"property\", \"propertyKey\"]),\n\t\t\t\t\t// but different endpoint\n\t\t\t\t\tendpoint,\n\t\t\t\t};\n\t\t\t\tif (this.valueDB.hasValue(possiblyMirroredValueID)) {\n\t\t\t\t\tif (loglevel === \"silly\") {\n\t\t\t\t\t\tthis.driver.controllerLog.logNode(this.id, {\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t`[translateValueEvent: ${eventName}] found mirrored value ID on different endpoint, ignoring event:\n commandClass: ${getCCName(possiblyMirroredValueID.commandClass)}\n endpoint: ${possiblyMirroredValueID.endpoint}\n property: ${possiblyMirroredValueID.property}\n propertyKey: ${possiblyMirroredValueID.propertyKey}`,\n\t\t\t\t\t\t\tlevel: \"silly\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// And pass the translated event to our listeners\n\t\tthis._emit(eventName, this, outArg as any);\n\t}\n}\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -5,6 +5,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
8
9
|
var __export = (target, all) => {
|
|
9
10
|
for (var name in all)
|
|
10
11
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -39,6 +40,9 @@ var import_Endpoint = require("../Endpoint.js");
|
|
|
39
40
|
var nodeUtils = __toESM(require("../utils.js"), 1);
|
|
40
41
|
var import_Values = require("./40_Values.js");
|
|
41
42
|
class EndpointsMixin extends import_Values.NodeValuesMixin {
|
|
43
|
+
static {
|
|
44
|
+
__name(this, "EndpointsMixin");
|
|
45
|
+
}
|
|
42
46
|
get endpointCountIsDynamic() {
|
|
43
47
|
return nodeUtils.endpointCountIsDynamic(this.driver, this.id);
|
|
44
48
|
}
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/node/mixins/50_Endpoints.ts"],
|
|
4
4
|
"sourcesContent": ["import { MultiChannelCCValues } from \"@zwave-js/cc\";\nimport {\n\ttype CommandClasses,\n\ttype GetAllEndpoints,\n\ttype GetEndpoint,\n\ttype MaybeNotKnown,\n\tZWaveError,\n\tZWaveErrorCodes,\n} from \"@zwave-js/core\";\nimport { isArray, isObject } from \"alcalzone-shared/typeguards\";\nimport { DeviceClass } from \"../DeviceClass.js\";\nimport { Endpoint } from \"../Endpoint.js\";\nimport * as nodeUtils from \"../utils.js\";\nimport { NodeValuesMixin } from \"./40_Values.js\";\n\n/** Defines functionality of Z-Wave nodes related to accessing endpoints and their capabilities */\nexport interface Endpoints {\n\t/** Whether the endpoint count is dynamic */\n\treadonly endpointCountIsDynamic: MaybeNotKnown<boolean>;\n\t/** Whether all endpoints have identical capabilities */\n\treadonly endpointsHaveIdenticalCapabilities: MaybeNotKnown<boolean>;\n\t/** The number of individual endpoints */\n\treadonly individualEndpointCount: MaybeNotKnown<number>;\n\t/** The number of aggregated endpoints */\n\treadonly aggregatedEndpointCount: MaybeNotKnown<number>;\n\t/** Returns the current endpoint count of this node.\n\t *\n\t * If you want to enumerate the existing endpoints, use `getEndpointIndizes` instead.\n\t * Some devices are known to contradict themselves.\n\t */\n\tgetEndpointCount(): number;\n\t/** Returns indizes of all endpoints on the node. */\n\tgetEndpointIndizes(): number[];\n\t/** Returns an endpoint of this node with the given index. 0 returns the node itself. */\n\tgetEndpoint(index: 0): Endpoint;\n\tgetEndpoint(index: number): Endpoint | undefined;\n\t/** Returns an endpoint of this node with the given index. Throws if the endpoint does not exist. */\n\tgetEndpointOrThrow(index: number): Endpoint;\n\t/** Returns a list of all endpoints of this node, including the root endpoint (index 0) */\n\tgetAllEndpoints(): Endpoint[];\n}\n\nexport abstract class EndpointsMixin extends NodeValuesMixin\n\timplements Endpoints, GetEndpoint<Endpoint>, GetAllEndpoints<Endpoint>\n{\n\tpublic get endpointCountIsDynamic(): MaybeNotKnown<boolean> {\n\t\treturn nodeUtils.endpointCountIsDynamic(this.driver, this.id);\n\t}\n\n\tpublic get endpointsHaveIdenticalCapabilities(): MaybeNotKnown<boolean> {\n\t\treturn nodeUtils.endpointsHaveIdenticalCapabilities(\n\t\t\tthis.driver,\n\t\t\tthis.id,\n\t\t);\n\t}\n\n\tpublic get individualEndpointCount(): MaybeNotKnown<number> {\n\t\treturn nodeUtils.getIndividualEndpointCount(this.driver, this.id);\n\t}\n\n\tpublic get aggregatedEndpointCount(): MaybeNotKnown<number> {\n\t\treturn nodeUtils.getAggregatedEndpointCount(this.driver, this.id);\n\t}\n\n\t/** Returns the device class of an endpoint. Falls back to the node's device class if the information is not known. */\n\tprivate getEndpointDeviceClass(index: number): MaybeNotKnown<DeviceClass> {\n\t\tconst deviceClass = this.getValue<{\n\t\t\tgeneric: number;\n\t\t\tspecific: number;\n\t\t}>(\n\t\t\tMultiChannelCCValues.endpointDeviceClass.endpoint(\n\t\t\t\tthis.endpointsHaveIdenticalCapabilities ? 1 : index,\n\t\t\t),\n\t\t);\n\t\tif (deviceClass && this.deviceClass) {\n\t\t\treturn new DeviceClass(\n\t\t\t\tthis.deviceClass.basic,\n\t\t\t\tdeviceClass.generic,\n\t\t\t\tdeviceClass.specific,\n\t\t\t);\n\t\t}\n\t\t// fall back to the node's device class if it is known\n\t\treturn this.deviceClass;\n\t}\n\n\tprivate getEndpointCCs(index: number): MaybeNotKnown<CommandClasses[]> {\n\t\tconst ret = this.getValue(\n\t\t\tMultiChannelCCValues.endpointCCs.endpoint(\n\t\t\t\tthis.endpointsHaveIdenticalCapabilities ? 1 : index,\n\t\t\t),\n\t\t);\n\t\t// Workaround for the change in #1977\n\t\tif (isArray(ret)) {\n\t\t\t// The value is set up correctly, return it\n\t\t\treturn ret as CommandClasses[];\n\t\t} else if (isObject(ret) && \"supportedCCs\" in ret) {\n\t\t\treturn ret.supportedCCs as CommandClasses[];\n\t\t}\n\t}\n\n\t/**\n\t * Returns the current endpoint count of this node.\n\t *\n\t * If you want to enumerate the existing endpoints, use `getEndpointIndizes` instead.\n\t * Some devices are known to contradict themselves.\n\t */\n\tpublic getEndpointCount(): number {\n\t\treturn nodeUtils.getEndpointCount(this.driver, this.id);\n\t}\n\n\t/**\n\t * Returns indizes of all endpoints on the node.\n\t */\n\tpublic getEndpointIndizes(): number[] {\n\t\treturn nodeUtils.getEndpointIndizes(this.driver, this.id);\n\t}\n\n\t/** Whether the Multi Channel CC has been interviewed and all endpoint information is known */\n\tprivate get isMultiChannelInterviewComplete(): boolean {\n\t\treturn nodeUtils.isMultiChannelInterviewComplete(this.driver, this.id);\n\t}\n\n\t/** Cache for this node's endpoint instances */\n\tprotected _endpointInstances = new Map<number, Endpoint>();\n\t/**\n\t * Returns an endpoint of this node with the given index. 0 returns the node itself.\n\t */\n\tpublic getEndpoint(index: 0): Endpoint;\n\tpublic getEndpoint(index: number): Endpoint | undefined;\n\tpublic getEndpoint(index: number): Endpoint | undefined {\n\t\tif (index < 0) {\n\t\t\tthrow new ZWaveError(\n\t\t\t\t\"The endpoint index must be positive!\",\n\t\t\t\tZWaveErrorCodes.Argument_Invalid,\n\t\t\t);\n\t\t}\n\t\t// Zero is the root endpoint - i.e. this node\n\t\tif (index === 0) return this;\n\t\t// Check if the Multi Channel CC interview for this node is completed,\n\t\t// because we don't have all the information before that\n\t\tif (!this.isMultiChannelInterviewComplete) {\n\t\t\tthis.driver.driverLog.print(\n\t\t\t\t`Node ${this.id}, Endpoint ${index}: Trying to access endpoint instance before Multi Channel interview`,\n\t\t\t\t\"error\",\n\t\t\t);\n\t\t\treturn undefined;\n\t\t}\n\t\t// Check if the endpoint index is in the list of known endpoint indizes\n\t\tif (!this.getEndpointIndizes().includes(index)) return undefined;\n\n\t\t// Create an endpoint instance if it does not exist\n\t\tif (!this._endpointInstances.has(index)) {\n\t\t\tthis._endpointInstances.set(\n\t\t\t\tindex,\n\t\t\t\tnew Endpoint(\n\t\t\t\t\tthis.id,\n\t\t\t\t\tthis.driver,\n\t\t\t\t\tindex,\n\t\t\t\t\tthis.getEndpointDeviceClass(index),\n\t\t\t\t\tthis.getEndpointCCs(index),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\treturn this._endpointInstances.get(index)!;\n\t}\n\n\tpublic getEndpointOrThrow(index: number): Endpoint {\n\t\tconst ret = this.getEndpoint(index);\n\t\tif (!ret) {\n\t\t\tthrow new ZWaveError(\n\t\t\t\t`Endpoint ${index} does not exist on Node ${this.id}`,\n\t\t\t\tZWaveErrorCodes.Controller_EndpointNotFound,\n\t\t\t);\n\t\t}\n\t\treturn ret;\n\t}\n\n\t/** Returns a list of all endpoints of this node, including the root endpoint (index 0) */\n\tpublic getAllEndpoints(): Endpoint[] {\n\t\treturn nodeUtils.getAllEndpoints(this.driver, this);\n\t}\n}\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;AAAA,gBAAqC;AACrC,kBAOO;AACP,wBAAkC;AAClC,yBAA4B;AAC5B,sBAAyB;AACzB,gBAA2B;AAC3B,oBAAgC;AA6B1B,MAAgB,uBAAuB,8BAAe;EA1C5D,OA0C4D;;;EAG3D,IAAW,yBAAsB;AAChC,WAAO,UAAU,uBAAuB,KAAK,QAAQ,KAAK,EAAE;EAC7D;EAEA,IAAW,qCAAkC;AAC5C,WAAO,UAAU,mCAChB,KAAK,QACL,KAAK,EAAE;EAET;EAEA,IAAW,0BAAuB;AACjC,WAAO,UAAU,2BAA2B,KAAK,QAAQ,KAAK,EAAE;EACjE;EAEA,IAAW,0BAAuB;AACjC,WAAO,UAAU,2BAA2B,KAAK,QAAQ,KAAK,EAAE;EACjE;;EAGQ,uBAAuB,OAAa;AAC3C,UAAM,cAAc,KAAK,SAIxB,+BAAqB,oBAAoB,SACxC,KAAK,qCAAqC,IAAI,KAAK,CACnD;AAEF,QAAI,eAAe,KAAK,aAAa;AACpC,aAAO,IAAI,+BACV,KAAK,YAAY,OACjB,YAAY,SACZ,YAAY,QAAQ;IAEtB;AAEA,WAAO,KAAK;EACb;EAEQ,eAAe,OAAa;AACnC,UAAM,MAAM,KAAK,SAChB,+BAAqB,YAAY,SAChC,KAAK,qCAAqC,IAAI,KAAK,CACnD;AAGF,YAAI,2BAAQ,GAAG,GAAG;AAEjB,aAAO;IACR,eAAW,4BAAS,GAAG,KAAK,kBAAkB,KAAK;AAClD,aAAO,IAAI;IACZ;EACD;;;;;;;EAQO,mBAAgB;AACtB,WAAO,UAAU,iBAAiB,KAAK,QAAQ,KAAK,EAAE;EACvD;;;;EAKO,qBAAkB;AACxB,WAAO,UAAU,mBAAmB,KAAK,QAAQ,KAAK,EAAE;EACzD;;EAGA,IAAY,kCAA+B;AAC1C,WAAO,UAAU,gCAAgC,KAAK,QAAQ,KAAK,EAAE;EACtE;;EAGU,qBAAqB,oBAAI,IAAG;EAM/B,YAAY,OAAa;AAC/B,QAAI,QAAQ,GAAG;AACd,YAAM,IAAI,uBACT,wCACA,4BAAgB,gBAAgB;IAElC;AAEA,QAAI,UAAU;AAAG,aAAO;AAGxB,QAAI,CAAC,KAAK,iCAAiC;AAC1C,WAAK,OAAO,UAAU,MACrB,QAAQ,KAAK,EAAE,cAAc,KAAK,uEAClC,OAAO;AAER,aAAO;IACR;AAEA,QAAI,CAAC,KAAK,mBAAkB,EAAG,SAAS,KAAK;AAAG,aAAO;AAGvD,QAAI,CAAC,KAAK,mBAAmB,IAAI,KAAK,GAAG;AACxC,WAAK,mBAAmB,IACvB,OACA,IAAI,yBACH,KAAK,IACL,KAAK,QACL,OACA,KAAK,uBAAuB,KAAK,GACjC,KAAK,eAAe,KAAK,CAAC,CAC1B;IAEH;AACA,WAAO,KAAK,mBAAmB,IAAI,KAAK;EACzC;EAEO,mBAAmB,OAAa;AACtC,UAAM,MAAM,KAAK,YAAY,KAAK;AAClC,QAAI,CAAC,KAAK;AACT,YAAM,IAAI,uBACT,YAAY,KAAK,2BAA2B,KAAK,EAAE,IACnD,4BAAgB,2BAA2B;IAE7C;AACA,WAAO;EACR;;EAGO,kBAAe;AACrB,WAAO,UAAU,gBAAgB,KAAK,QAAQ,IAAI;EACnD;;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
7
|
var __export = (target, all) => {
|
|
7
8
|
for (var name in all)
|
|
8
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -27,6 +28,9 @@ var import_shared = require("@zwave-js/shared");
|
|
|
27
28
|
var import_node_util = require("node:util");
|
|
28
29
|
var import_Endpoints = require("./50_Endpoints.js");
|
|
29
30
|
class SchedulePollMixin extends import_Endpoints.EndpointsMixin {
|
|
31
|
+
static {
|
|
32
|
+
__name(this, "SchedulePollMixin");
|
|
33
|
+
}
|
|
30
34
|
constructor(nodeId, driver, endpointIndex, deviceClass, supportedCCs, valueDB) {
|
|
31
35
|
super(nodeId, driver, endpointIndex, deviceClass, supportedCCs, valueDB);
|
|
32
36
|
for (const event of ["value updated", "value removed"]) {
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/node/mixins/60_ScheduledPoll.ts"],
|
|
4
4
|
"sourcesContent": ["import { type CCAPI } from \"@zwave-js/cc\";\nimport { type ValueDB, normalizeValueID } from \"@zwave-js/core\";\nimport {\n\ttype CommandClasses,\n\tMessagePriority,\n\ttype ValueID,\n\ttype ValueRemovedArgs,\n\ttype ValueUpdatedArgs,\n} from \"@zwave-js/core/safe\";\nimport { type NodeSchedulePollOptions } from \"@zwave-js/host\";\nimport { ObjectKeyMap } from \"@zwave-js/shared\";\nimport { isDeepStrictEqual } from \"node:util\";\nimport { type Driver } from \"../../driver/Driver.js\";\nimport { type DeviceClass } from \"../DeviceClass.js\";\nimport { EndpointsMixin } from \"./50_Endpoints.js\";\n\nexport interface ScheduledPoll {\n\ttimeout: NodeJS.Timeout;\n\texpectedValue?: unknown;\n}\n\n/** Defines functionality of Z-Wave nodes for scheduling polls for a later time and canceling scheduled polls */\nexport interface SchedulePoll {\n\t/**\n\t * @internal\n\t * Returns whether a poll is currently scheduled for this node\n\t */\n\thasScheduledPolls(): boolean;\n\n\t/**\n\t * @internal\n\t * Schedules a value to be polled after a given time. Only one schedule can be active for a given value ID.\n\t * @returns `true` if the poll was scheduled, `false` otherwise\n\t */\n\tschedulePoll(\n\t\tvalueId: ValueID,\n\t\toptions: NodeSchedulePollOptions,\n\t): boolean;\n\n\t/**\n\t * @internal\n\t * Cancels a poll that has been scheduled with schedulePoll.\n\t *\n\t * @param actualValue If given, this indicates the value that was received by a node, which triggered the poll to be canceled.\n\t * If the scheduled poll expects a certain value and this matches the expected value for the scheduled poll, the poll will be canceled.\n\t */\n\tcancelScheduledPoll(\n\t\tvalueId: ValueID,\n\t\tactualValue?: unknown,\n\t): boolean;\n\n\t/**\n\t * @internal\n\t * Cancels all polls that have been scheduled with schedulePoll.\n\t */\n\tcancelAllScheduledPolls(): void;\n}\n\nexport abstract class SchedulePollMixin extends EndpointsMixin\n\timplements SchedulePoll\n{\n\tpublic constructor(\n\t\tnodeId: number,\n\t\tdriver: Driver,\n\t\tendpointIndex: number,\n\t\tdeviceClass?: DeviceClass,\n\t\tsupportedCCs?: CommandClasses[],\n\t\tvalueDB?: ValueDB,\n\t) {\n\t\tsuper(\n\t\t\tnodeId,\n\t\t\tdriver,\n\t\t\tendpointIndex,\n\t\t\tdeviceClass,\n\t\t\tsupportedCCs,\n\t\t\tvalueDB,\n\t\t);\n\n\t\t// Avoid verifying a value change for which we recently received an update\n\t\tfor (const event of [\"value updated\", \"value removed\"] as const) {\n\t\t\tthis.valueDB.on(\n\t\t\t\tevent,\n\t\t\t\t(args: ValueUpdatedArgs | ValueRemovedArgs) => {\n\t\t\t\t\t// Value updates caused by the driver should never cancel a scheduled poll\n\t\t\t\t\tif (\"source\" in args && args.source === \"driver\") return;\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis.cancelScheduledPoll(\n\t\t\t\t\t\t\targs,\n\t\t\t\t\t\t\t(args as ValueUpdatedArgs).newValue,\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.driver.controllerLog.logNode(\n\t\t\t\t\t\t\tthis.id,\n\t\t\t\t\t\t\t\"Scheduled poll canceled because expected value was received\",\n\t\t\t\t\t\t\t\"verbose\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * All polls that are currently scheduled for this node\n\t */\n\tprivate _scheduledPolls = new ObjectKeyMap<ValueID, ScheduledPoll>();\n\n\tpublic hasScheduledPolls(): boolean {\n\t\treturn this._scheduledPolls.size > 0;\n\t}\n\n\tpublic schedulePoll(\n\t\tvalueId: ValueID,\n\t\toptions: NodeSchedulePollOptions = {},\n\t): boolean {\n\t\tconst {\n\t\t\ttimeoutMs = this.driver.options.timeouts.refreshValue,\n\t\t\texpectedValue,\n\t\t} = options;\n\n\t\t// Avoid false positives or false negatives due to a mis-formatted value ID\n\t\tvalueId = normalizeValueID(valueId);\n\n\t\t// Try to retrieve the corresponding CC API\n\t\tconst endpointInstance = this.getEndpoint(valueId.endpoint || 0);\n\t\tif (!endpointInstance) return false;\n\n\t\tconst api = (\n\t\t\t(endpointInstance.commandClasses as any)[\n\t\t\t\tvalueId.commandClass\n\t\t\t] as CCAPI\n\t\t).withOptions({\n\t\t\t// We do not want to delay more important communication by polling, so give it\n\t\t\t// the lowest priority and don't retry unless overwritten by the options\n\t\t\tmaxSendAttempts: 1,\n\t\t\tpriority: MessagePriority.Poll,\n\t\t});\n\n\t\t// Check if the pollValue method is implemented\n\t\tif (!api.pollValue) return false;\n\n\t\t// make sure there is only one timeout instance per poll\n\t\tthis.cancelScheduledPoll(valueId);\n\t\tconst timeout = setTimeout(async () => {\n\t\t\t// clean up after the timeout\n\t\t\tthis.cancelScheduledPoll(valueId);\n\t\t\ttry {\n\t\t\t\tawait api.pollValue!.call(api, valueId);\n\t\t\t} catch {\n\t\t\t\t/* ignore */\n\t\t\t}\n\t\t}, timeoutMs).unref();\n\t\tthis._scheduledPolls.set(valueId, { timeout, expectedValue });\n\n\t\treturn true;\n\t}\n\n\tpublic cancelScheduledPoll(\n\t\tvalueId: ValueID,\n\t\tactualValue?: unknown,\n\t): boolean {\n\t\t// Avoid false positives or false negatives due to a mis-formatted value ID\n\t\tvalueId = normalizeValueID(valueId);\n\n\t\tconst poll = this._scheduledPolls.get(valueId);\n\t\tif (!poll) return false;\n\n\t\tif (\n\t\t\tactualValue !== undefined\n\t\t\t&& poll.expectedValue !== undefined\n\t\t\t&& !isDeepStrictEqual(poll.expectedValue, actualValue)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\tclearTimeout(poll.timeout);\n\t\tthis._scheduledPolls.delete(valueId);\n\n\t\treturn true;\n\t}\n\n\tpublic cancelAllScheduledPolls(): void {\n\t\t// Remove queued polls that would interfere with the interview\n\t\tfor (const valueId of this._scheduledPolls.keys()) {\n\t\t\tthis.cancelScheduledPoll(valueId);\n\t\t}\n\t}\n}\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;AACA;;;;;AAAA,kBAA+C;AAC/C,kBAMO;AAEP,oBAA6B;AAC7B,uBAAkC;AAGlC,uBAA+B;AA4CzB,MAAgB,0BAA0B,gCAAc;EAzD9D,OAyD8D;;;EAG7D,YACC,QACA,QACA,eACA,aACA,cACA,SAAiB;AAEjB,UACC,QACA,QACA,eACA,aACA,cACA,OAAO;AAIR,eAAW,SAAS,CAAC,iBAAiB,eAAe,GAAY;AAChE,WAAK,QAAQ,GACZ,OACA,CAAC,SAA6C;AAE7C,YAAI,YAAY,QAAQ,KAAK,WAAW;AAAU;AAElD,YACC,KAAK,oBACJ,MACC,KAA0B,QAAQ,GAEnC;AACD,eAAK,OAAO,cAAc,QACzB,KAAK,IACL,+DACA,SAAS;QAEX;MACD,CAAC;IAEH;EACD;;;;EAKQ,kBAAkB,IAAI,2BAAY;EAEnC,oBAAiB;AACvB,WAAO,KAAK,gBAAgB,OAAO;EACpC;EAEO,aACN,SACA,UAAmC,CAAA,GAAE;AAErC,UAAM,EACL,YAAY,KAAK,OAAO,QAAQ,SAAS,cACzC,cAAa,IACV;AAGJ,kBAAU,8BAAiB,OAAO;AAGlC,UAAM,mBAAmB,KAAK,YAAY,QAAQ,YAAY,CAAC;AAC/D,QAAI,CAAC;AAAkB,aAAO;AAE9B,UAAM,MACJ,iBAAiB,eACjB,QAAQ,YAAY,EAEpB,YAAY;;;MAGb,iBAAiB;MACjB,UAAU,4BAAgB;KAC1B;AAGD,QAAI,CAAC,IAAI;AAAW,aAAO;AAG3B,SAAK,oBAAoB,OAAO;AAChC,UAAM,UAAU,WAAW,YAAW;AAErC,WAAK,oBAAoB,OAAO;AAChC,UAAI;AACH,cAAM,IAAI,UAAW,KAAK,KAAK,OAAO;MACvC,QAAQ;MAER;IACD,GAAG,SAAS,EAAE,MAAK;AACnB,SAAK,gBAAgB,IAAI,SAAS,EAAE,SAAS,cAAa,CAAE;AAE5D,WAAO;EACR;EAEO,oBACN,SACA,aAAqB;AAGrB,kBAAU,8BAAiB,OAAO;AAElC,UAAM,OAAO,KAAK,gBAAgB,IAAI,OAAO;AAC7C,QAAI,CAAC;AAAM,aAAO;AAElB,QACC,gBAAgB,UACb,KAAK,kBAAkB,UACvB,KAAC,oCAAkB,KAAK,eAAe,WAAW,GACpD;AACD,aAAO;IACR;AAEA,iBAAa,KAAK,OAAO;AACzB,SAAK,gBAAgB,OAAO,OAAO;AAEnC,WAAO;EACR;EAEO,0BAAuB;AAE7B,eAAW,WAAW,KAAK,gBAAgB,KAAI,GAAI;AAClD,WAAK,oBAAoB,OAAO;IACjC;EACD;;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
7
|
var __export = (target, all) => {
|
|
7
8
|
for (var name in all)
|
|
8
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -35,7 +36,11 @@ var import_ScheduledPoll = require("./60_ScheduledPoll.js");
|
|
|
35
36
|
function isFirmwareUpdateOTATask(t) {
|
|
36
37
|
return t.tag?.id === "firmware-update-ota";
|
|
37
38
|
}
|
|
39
|
+
__name(isFirmwareUpdateOTATask, "isFirmwareUpdateOTATask");
|
|
38
40
|
class FirmwareUpdateMixin extends import_ScheduledPoll.SchedulePollMixin {
|
|
41
|
+
static {
|
|
42
|
+
__name(this, "FirmwareUpdateMixin");
|
|
43
|
+
}
|
|
39
44
|
_abortFirmwareUpdate;
|
|
40
45
|
async abortFirmwareUpdate() {
|
|
41
46
|
if (!this._abortFirmwareUpdate)
|
|
@@ -79,7 +84,7 @@ class FirmwareUpdateMixin extends import_ScheduledPoll.SchedulePollMixin {
|
|
|
79
84
|
// Firmware updates cause a lot of traffic. Execute them in the background.
|
|
80
85
|
priority: import_Task.TaskPriority.Lower,
|
|
81
86
|
tag: { id: "firmware-update-ota", nodeId: self.id },
|
|
82
|
-
task: async function* firmwareUpdateTask() {
|
|
87
|
+
task: /* @__PURE__ */ __name(async function* firmwareUpdateTask() {
|
|
83
88
|
keepAwake = self.keepAwake;
|
|
84
89
|
self.keepAwake = true;
|
|
85
90
|
const abortContext = {
|
|
@@ -224,7 +229,7 @@ class FirmwareUpdateMixin extends import_ScheduledPoll.SchedulePollMixin {
|
|
|
224
229
|
keepAwake = true;
|
|
225
230
|
self._emit("firmware update finished", self, result);
|
|
226
231
|
return result;
|
|
227
|
-
},
|
|
232
|
+
}, "firmwareUpdateTask"),
|
|
228
233
|
cleanup() {
|
|
229
234
|
self._abortFirmwareUpdate = void 0;
|
|
230
235
|
self._firmwareUpdatePrematureRequest = void 0;
|
|
@@ -361,7 +366,7 @@ class FirmwareUpdateMixin extends import_ScheduledPoll.SchedulePollMixin {
|
|
|
361
366
|
}
|
|
362
367
|
}
|
|
363
368
|
hasPendingFirmwareUpdateFragment(fragmentNumber) {
|
|
364
|
-
const isCurrentFirmwareFragment = (t) => t.message.getNodeId() === this.id && (0, import_serialapi.containsCC)(t.message) && t.message.command instanceof import_cc.FirmwareUpdateMetaDataCCReport && t.message.command.reportNumber === fragmentNumber;
|
|
369
|
+
const isCurrentFirmwareFragment = /* @__PURE__ */ __name((t) => t.message.getNodeId() === this.id && (0, import_serialapi.containsCC)(t.message) && t.message.command instanceof import_cc.FirmwareUpdateMetaDataCCReport && t.message.command.reportNumber === fragmentNumber, "isCurrentFirmwareFragment");
|
|
365
370
|
return this.driver.hasPendingTransactions(isCurrentFirmwareFragment);
|
|
366
371
|
}
|
|
367
372
|
async *doFirmwareUpdateInternal(data, fragmentSize, nonSecureTransfer, abortContext, onProgress) {
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/node/mixins/70_FirmwareUpdate.ts"],
|
|
4
4
|
"sourcesContent": ["import {\n\ttype FirmwareUpdateMetaData,\n\tFirmwareUpdateMetaDataCC,\n\tFirmwareUpdateMetaDataCCGet,\n\ttype FirmwareUpdateMetaDataCCMetaDataGet,\n\tFirmwareUpdateMetaDataCCReport,\n\tFirmwareUpdateMetaDataCCRequestReport,\n\tFirmwareUpdateMetaDataCCStatusReport,\n\ttype FirmwareUpdateOptions,\n\ttype FirmwareUpdateProgress,\n\tFirmwareUpdateRequestStatus,\n\ttype FirmwareUpdateResult,\n\tFirmwareUpdateStatus,\n\tgetEffectiveCCVersion,\n} from \"@zwave-js/cc\";\nimport {\n\tCRC16_CCITT,\n\tCommandClasses,\n\tEncapsulationFlags,\n\ttype Firmware,\n\tSecurityClass,\n\tZWaveError,\n\tZWaveErrorCodes,\n\trandomBytes,\n\tsecurityClassIsS2,\n\ttimespan,\n} from \"@zwave-js/core\";\nimport { containsCC } from \"@zwave-js/serial/serialapi\";\nimport { getEnumMemberName, throttle } from \"@zwave-js/shared\";\nimport { distinct } from \"alcalzone-shared/arrays\";\nimport { wait } from \"alcalzone-shared/async\";\nimport {\n\ttype DeferredPromise,\n\tcreateDeferredPromise,\n} from \"alcalzone-shared/deferred-promise\";\nimport { roundTo } from \"alcalzone-shared/math\";\nimport {\n\ttype Task,\n\ttype TaskBuilder,\n\tTaskPriority,\n} from \"../../driver/Task.js\";\nimport { type Transaction } from \"../../driver/Transaction.js\";\nimport { SchedulePollMixin } from \"./60_ScheduledPoll.js\";\n\ninterface AbortFirmwareUpdateContext {\n\tabort: boolean;\n\ttooLateToAbort: boolean;\n\tabortPromise: DeferredPromise<boolean>;\n}\n\ntype PartialFirmwareUpdateResult =\n\t& Pick<FirmwareUpdateResult, \"status\" | \"waitTime\">\n\t& { success: boolean };\n\n/** Checks if a task belongs to a route rebuilding process */\nexport function isFirmwareUpdateOTATask(t: Task<unknown>): boolean {\n\treturn t.tag?.id === \"firmware-update-ota\";\n}\n\nexport interface NodeFirmwareUpdate {\n\t/**\n\t * Aborts an active firmware update process\n\t */\n\tabortFirmwareUpdate(): Promise<void>;\n\n\t/**\n\t * Performs an OTA firmware upgrade of one or more chips on this node.\n\t *\n\t * This method will resolve after the process has **COMPLETED**. Failure to start any one of the provided updates will throw an error.\n\t *\n\t * **WARNING: Use at your own risk! We don't take any responsibility if your devices don't work after an update.**\n\t *\n\t * @param updates An array of firmware updates that will be done in sequence\n\t *\n\t * @returns Whether all of the given updates were successful.\n\t */\n\tupdateFirmware(\n\t\tupdates: Firmware[],\n\t\toptions?: FirmwareUpdateOptions,\n\t): Promise<FirmwareUpdateResult>;\n\n\t/**\n\t * Returns whether a firmware update is in progress for this node.\n\t */\n\tisFirmwareUpdateInProgress(): boolean;\n}\n\nexport abstract class FirmwareUpdateMixin extends SchedulePollMixin\n\timplements NodeFirmwareUpdate\n{\n\tprivate _abortFirmwareUpdate: (() => Promise<void>) | undefined;\n\tpublic async abortFirmwareUpdate(): Promise<void> {\n\t\tif (!this._abortFirmwareUpdate) return;\n\t\tawait this._abortFirmwareUpdate();\n\t}\n\n\t// Stores the CRC of the previously transferred firmware image.\n\t// Allows detecting whether resuming is supported and where to continue in a multi-file transfer.\n\tprivate _previousFirmwareCRC: number | undefined;\n\n\t/** Is used to remember fragment requests that came in before they were able to be handled */\n\tprivate _firmwareUpdatePrematureRequest:\n\t\t| FirmwareUpdateMetaDataCCGet\n\t\t| undefined;\n\n\tpublic async updateFirmware(\n\t\tupdates: Firmware[],\n\t\toptions: FirmwareUpdateOptions = {},\n\t): Promise<FirmwareUpdateResult> {\n\t\tif (updates.length === 0) {\n\t\t\tthrow new ZWaveError(\n\t\t\t\t`At least one update must be provided`,\n\t\t\t\tZWaveErrorCodes.Argument_Invalid,\n\t\t\t);\n\t\t}\n\n\t\t// Check that each update has a buffer with at least 1 byte\n\t\tif (updates.some((u) => u.data.length === 0)) {\n\t\t\tthrow new ZWaveError(\n\t\t\t\t`All firmware updates must have a non-empty data buffer`,\n\t\t\t\tZWaveErrorCodes.Argument_Invalid,\n\t\t\t);\n\t\t}\n\n\t\t// Check that the targets are not duplicates\n\t\tif (\n\t\t\tdistinct(updates.map((u) => u.firmwareTarget ?? 0)).length\n\t\t\t\t!== updates.length\n\t\t) {\n\t\t\tthrow new ZWaveError(\n\t\t\t\t`The target of all provided firmware updates must be unique`,\n\t\t\t\tZWaveErrorCodes.Argument_Invalid,\n\t\t\t);\n\t\t}\n\n\t\t// Don't start the process twice\n\t\tif (this.driver.controller.isFirmwareUpdateInProgress()) {\n\t\t\tthrow new ZWaveError(\n\t\t\t\t`Failed to start the update: An OTW upgrade of the controller is in progress!`,\n\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_Busy,\n\t\t\t);\n\t\t}\n\n\t\t// Don't allow starting two firmware updates for the same node\n\t\tconst task = this.getUpdateFirmwareTask(updates, options);\n\t\tif (task instanceof Promise) {\n\t\t\tthrow new ZWaveError(\n\t\t\t\t`Failed to start the update: A firmware update is already in progress for this node!`,\n\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_Busy,\n\t\t\t);\n\t\t}\n\n\t\t// Queue the task\n\t\treturn this.driver.scheduler.queueTask(task);\n\t}\n\n\tpublic isFirmwareUpdateInProgress(): boolean {\n\t\treturn !!this.driver.scheduler.findTask(isFirmwareUpdateOTATask);\n\t}\n\n\tprivate getUpdateFirmwareTask(\n\t\tupdates: Firmware[],\n\t\toptions: FirmwareUpdateOptions = {},\n\t): Promise<FirmwareUpdateResult> | TaskBuilder<FirmwareUpdateResult> {\n\t\tconst self = this;\n\n\t\t// This task should only run once at a time\n\t\tconst existingTask = this.driver.scheduler.findTask<\n\t\t\tFirmwareUpdateResult\n\t\t>((t) =>\n\t\t\tt.tag?.id === \"firmware-update-ota\"\n\t\t\t&& t.tag.nodeId === self.id\n\t\t);\n\t\tif (existingTask) return existingTask;\n\n\t\tlet keepAwake: boolean;\n\n\t\treturn {\n\t\t\t// Firmware updates cause a lot of traffic. Execute them in the background.\n\t\t\tpriority: TaskPriority.Lower,\n\t\t\ttag: { id: \"firmware-update-ota\", nodeId: self.id },\n\t\t\ttask: async function* firmwareUpdateTask() {\n\t\t\t\t// Keep battery powered nodes awake during the process\n\t\t\t\tkeepAwake = self.keepAwake;\n\t\t\t\tself.keepAwake = true;\n\n\t\t\t\t// Support aborting the update\n\t\t\t\tconst abortContext = {\n\t\t\t\t\tabort: false,\n\t\t\t\t\ttooLateToAbort: false,\n\t\t\t\t\tabortPromise: createDeferredPromise<boolean>(),\n\t\t\t\t};\n\n\t\t\t\tself._abortFirmwareUpdate = async () => {\n\t\t\t\t\tif (abortContext.tooLateToAbort) {\n\t\t\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t\t\t`The firmware update was transmitted completely, cannot abort anymore.`,\n\t\t\t\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_FailedToAbort,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tself.driver.controllerLog.logNode(self.id, {\n\t\t\t\t\t\tmessage: `Aborting firmware update...`,\n\t\t\t\t\t\tdirection: \"outbound\",\n\t\t\t\t\t});\n\n\t\t\t\t\t// Trigger the abort\n\t\t\t\t\tabortContext.abort = true;\n\t\t\t\t\tconst aborted = await abortContext.abortPromise;\n\t\t\t\t\tif (!aborted) {\n\t\t\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t\t\t`The node did not acknowledge the aborted update`,\n\t\t\t\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_FailedToAbort,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tself.driver.controllerLog.logNode(self.id, {\n\t\t\t\t\t\tmessage: `Firmware update aborted`,\n\t\t\t\t\t\tdirection: \"inbound\",\n\t\t\t\t\t});\n\t\t\t\t};\n\n\t\t\t\t// Prepare the firmware update\n\t\t\t\tlet fragmentSizeSecure: number;\n\t\t\t\tlet fragmentSizeNonSecure: number;\n\t\t\t\tlet meta: FirmwareUpdateMetaData;\n\t\t\t\ttry {\n\t\t\t\t\tconst prepareResult = await self\n\t\t\t\t\t\t.prepareFirmwareUpdateInternal(\n\t\t\t\t\t\t\tupdates.map((u) => u.firmwareTarget ?? 0),\n\t\t\t\t\t\t\tabortContext,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t// Handle early aborts\n\t\t\t\t\tif (abortContext.abort) {\n\t\t\t\t\t\tconst result: FirmwareUpdateResult = {\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\tstatus: FirmwareUpdateStatus\n\t\t\t\t\t\t\t\t.Error_TransmissionFailed,\n\t\t\t\t\t\t\treInterview: false,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tself._emit(\n\t\t\t\t\t\t\t\"firmware update finished\",\n\t\t\t\t\t\t\tself,\n\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t}\n\n\t\t\t\t\t// If the firmware update was not aborted, prepareResult is definitely defined\n\t\t\t\t\t({\n\t\t\t\t\t\tfragmentSizeSecure,\n\t\t\t\t\t\tfragmentSizeNonSecure,\n\t\t\t\t\t\t...meta\n\t\t\t\t\t} = prepareResult!);\n\t\t\t\t} catch {\n\t\t\t\t\t// Not sure what the error is, but we'll label it \"transmission failed\"\n\t\t\t\t\tconst result: FirmwareUpdateResult = {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tstatus: FirmwareUpdateStatus.Error_TransmissionFailed,\n\t\t\t\t\t\treInterview: false,\n\t\t\t\t\t};\n\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tyield; // Give the task scheduler time to do something else\n\n\t\t\t\t// The resume and non-secure transfer features may not be supported by the node\n\t\t\t\t// If not, disable them, even though the application requested them\n\t\t\t\tif (!meta.supportsResuming) options.resume = false;\n\n\t\t\t\tconst securityClass = self.getHighestSecurityClass();\n\t\t\t\tconst isSecure = securityClass === SecurityClass.S0_Legacy\n\t\t\t\t\t|| securityClassIsS2(securityClass);\n\t\t\t\tif (!isSecure) {\n\t\t\t\t\t// The nonSecureTransfer option is only relevant for secure devices\n\t\t\t\t\toptions.nonSecureTransfer = false;\n\t\t\t\t} else if (!meta.supportsNonSecureTransfer) {\n\t\t\t\t\toptions.nonSecureTransfer = false;\n\t\t\t\t}\n\n\t\t\t\t// Throttle the progress emitter so applications can handle the load of events\n\t\t\t\tconst notifyProgress = throttle(\n\t\t\t\t\t(progress) =>\n\t\t\t\t\t\tself._emit(\n\t\t\t\t\t\t\t\"firmware update progress\",\n\t\t\t\t\t\t\tself,\n\t\t\t\t\t\t\tprogress,\n\t\t\t\t\t\t),\n\t\t\t\t\t250,\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\n\t\t\t\t// If resuming is supported and desired, try to figure out with which file to continue\n\t\t\t\tconst updatesWithChecksum = updates.map((u) => ({\n\t\t\t\t\t...u,\n\t\t\t\t\tchecksum: CRC16_CCITT(u.data),\n\t\t\t\t}));\n\t\t\t\tlet skipFinishedFiles = -1;\n\t\t\t\tlet shouldResume = options.resume\n\t\t\t\t\t&& self._previousFirmwareCRC != undefined;\n\t\t\t\tif (shouldResume) {\n\t\t\t\t\tskipFinishedFiles = updatesWithChecksum.findIndex(\n\t\t\t\t\t\t(u) => u.checksum === self._previousFirmwareCRC,\n\t\t\t\t\t);\n\t\t\t\t\tif (skipFinishedFiles === -1) shouldResume = false;\n\t\t\t\t}\n\n\t\t\t\t// Perform all firmware updates in sequence\n\t\t\t\tlet updateResult!: PartialFirmwareUpdateResult;\n\t\t\t\tlet conservativeWaitTime: number;\n\n\t\t\t\tconst totalBytes: number = updatesWithChecksum.reduce(\n\t\t\t\t\t(total, update) => total + update.data.length,\n\t\t\t\t\t0,\n\t\t\t\t);\n\t\t\t\tlet sentBytesOfPreviousFiles = 0;\n\n\t\t\t\tfor (let i = 0; i < updatesWithChecksum.length; i++) {\n\t\t\t\t\tconst { firmwareTarget: target = 0, data, checksum } =\n\t\t\t\t\t\tupdatesWithChecksum[i];\n\n\t\t\t\t\tif (i < skipFinishedFiles) {\n\t\t\t\t\t\t// If we are resuming, skip this file since it was already done before\n\t\t\t\t\t\tself.driver.controllerLog.logNode(\n\t\t\t\t\t\t\tself.id,\n\t\t\t\t\t\t\t`Skipping already completed firmware update (part ${\n\t\t\t\t\t\t\t\ti + 1\n\t\t\t\t\t\t\t} / ${updatesWithChecksum.length})...`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tsentBytesOfPreviousFiles += data.length;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tself.driver.controllerLog.logNode(\n\t\t\t\t\t\tself.id,\n\t\t\t\t\t\t`Updating firmware (part ${\n\t\t\t\t\t\t\ti + 1\n\t\t\t\t\t\t} / ${updatesWithChecksum.length})...`,\n\t\t\t\t\t);\n\n\t\t\t\t\t// For determining the initial fragment size, assume the node respects our choice.\n\t\t\t\t\t// If the node is not secure, these two values are identical anyways.\n\t\t\t\t\tlet fragmentSize = options.nonSecureTransfer\n\t\t\t\t\t\t? fragmentSizeNonSecure\n\t\t\t\t\t\t: fragmentSizeSecure;\n\n\t\t\t\t\t// Tell the node to start requesting fragments\n\t\t\t\t\tconst { resume, nonSecureTransfer } = yield* self\n\t\t\t\t\t\t.beginFirmwareUpdateInternal(\n\t\t\t\t\t\t\tdata,\n\t\t\t\t\t\t\ttarget,\n\t\t\t\t\t\t\tmeta,\n\t\t\t\t\t\t\tfragmentSize,\n\t\t\t\t\t\t\tchecksum,\n\t\t\t\t\t\t\tshouldResume,\n\t\t\t\t\t\t\toptions.nonSecureTransfer,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t// If the node did not accept non-secure transfer, revisit our choice of fragment size\n\t\t\t\t\tif (options.nonSecureTransfer && !nonSecureTransfer) {\n\t\t\t\t\t\tfragmentSize = fragmentSizeSecure;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remember the checksum, so we can resume if necessary\n\t\t\t\t\tself._previousFirmwareCRC = checksum;\n\n\t\t\t\t\tif (shouldResume) {\n\t\t\t\t\t\tself.driver.controllerLog.logNode(\n\t\t\t\t\t\t\tself.id,\n\t\t\t\t\t\t\t`Node ${\n\t\t\t\t\t\t\t\tresume ? \"accepted\" : \"did not accept\"\n\t\t\t\t\t\t\t} resuming the update...`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif (nonSecureTransfer) {\n\t\t\t\t\t\tself.driver.controllerLog.logNode(\n\t\t\t\t\t\t\tself.id,\n\t\t\t\t\t\t\t`Firmware will be transferred without encryption...`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tyield; // Give the task scheduler time to do something else\n\n\t\t\t\t\t// Listen for firmware update fragment requests and handle them\n\t\t\t\t\tupdateResult = yield* self.doFirmwareUpdateInternal(\n\t\t\t\t\t\tdata,\n\t\t\t\t\t\tfragmentSize,\n\t\t\t\t\t\tnonSecureTransfer,\n\t\t\t\t\t\tabortContext,\n\t\t\t\t\t\t(fragment, total) => {\n\t\t\t\t\t\t\tconst progress: FirmwareUpdateProgress = {\n\t\t\t\t\t\t\t\tcurrentFile: i + 1,\n\t\t\t\t\t\t\t\ttotalFiles: updatesWithChecksum.length,\n\t\t\t\t\t\t\t\tsentFragments: fragment,\n\t\t\t\t\t\t\t\ttotalFragments: total,\n\t\t\t\t\t\t\t\tprogress: roundTo(\n\t\t\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t\t(sentBytesOfPreviousFiles\n\t\t\t\t\t\t\t\t\t\t\t+ Math.min(\n\t\t\t\t\t\t\t\t\t\t\t\tfragment * fragmentSize,\n\t\t\t\t\t\t\t\t\t\t\t\tdata.length,\n\t\t\t\t\t\t\t\t\t\t\t))\n\t\t\t\t\t\t\t\t\t\t/ totalBytes\n\t\t\t\t\t\t\t\t\t) * 100,\n\t\t\t\t\t\t\t\t\t2,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tnotifyProgress(progress);\n\n\t\t\t\t\t\t\t// When this file is done, add the fragments to the total, so we can compute the total progress correctly\n\t\t\t\t\t\t\tif (fragment === total) {\n\t\t\t\t\t\t\t\tsentBytesOfPreviousFiles += data.length;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\n\t\t\t\t\t// If we wait, wait a bit longer than the device told us, so it is actually ready to use\n\t\t\t\t\tconservativeWaitTime = self.driver\n\t\t\t\t\t\t.getConservativeWaitTimeAfterFirmwareUpdate(\n\t\t\t\t\t\t\tupdateResult.waitTime,\n\t\t\t\t\t\t);\n\n\t\t\t\t\tif (!updateResult.success) {\n\t\t\t\t\t\tself.driver.controllerLog.logNode(self.id, {\n\t\t\t\t\t\t\tmessage: `Firmware update (part ${\n\t\t\t\t\t\t\t\ti + 1\n\t\t\t\t\t\t\t} / ${updatesWithChecksum.length}) failed with status ${\n\t\t\t\t\t\t\t\tgetEnumMemberName(\n\t\t\t\t\t\t\t\t\tFirmwareUpdateStatus,\n\t\t\t\t\t\t\t\t\tupdateResult.status,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\tdirection: \"inbound\",\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst result: FirmwareUpdateResult = {\n\t\t\t\t\t\t\t...updateResult,\n\t\t\t\t\t\t\twaitTime: undefined,\n\t\t\t\t\t\t\treInterview: false,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tself._emit(\n\t\t\t\t\t\t\t\"firmware update finished\",\n\t\t\t\t\t\t\tself,\n\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t} else if (i < updatesWithChecksum.length - 1) {\n\t\t\t\t\t\t// Update succeeded, but we're not done yet\n\n\t\t\t\t\t\tself.driver.controllerLog.logNode(self.id, {\n\t\t\t\t\t\t\tmessage: `Firmware update (part ${\n\t\t\t\t\t\t\t\ti + 1\n\t\t\t\t\t\t\t} / ${updatesWithChecksum.length}) succeeded with status ${\n\t\t\t\t\t\t\t\tgetEnumMemberName(\n\t\t\t\t\t\t\t\t\tFirmwareUpdateStatus,\n\t\t\t\t\t\t\t\t\tupdateResult.status,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\tdirection: \"inbound\",\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tself.driver.controllerLog.logNode(\n\t\t\t\t\t\t\tself.id,\n\t\t\t\t\t\t\t`Continuing with next part in ${conservativeWaitTime} seconds...`,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// If we've resumed the previous file, there's no need to resume the next one too\n\t\t\t\t\t\tshouldResume = false;\n\n\t\t\t\t\t\tyield () => wait(conservativeWaitTime * 1000, true);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// We're done. No need to resume this update\n\t\t\t\tself._previousFirmwareCRC = undefined;\n\n\t\t\t\tconst result: FirmwareUpdateResult = {\n\t\t\t\t\t...updateResult,\n\t\t\t\t\twaitTime: conservativeWaitTime!,\n\t\t\t\t\treInterview: true,\n\t\t\t\t};\n\n\t\t\t\t// After a successful firmware update, we want to interview sleeping nodes immediately,\n\t\t\t\t// so don't send them to sleep when they wake up\n\t\t\t\tkeepAwake = true;\n\n\t\t\t\tself._emit(\"firmware update finished\", self, result);\n\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tcleanup() {\n\t\t\t\tself._abortFirmwareUpdate = undefined;\n\t\t\t\tself._firmwareUpdatePrematureRequest = undefined;\n\n\t\t\t\t// Make sure that the keepAwake flag gets reset at the end\n\t\t\t\tself.keepAwake = keepAwake;\n\t\t\t\tif (!keepAwake) {\n\t\t\t\t\tsetImmediate(() => {\n\t\t\t\t\t\tself.driver.debounceSendNodeToSleep(self);\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn Promise.resolve();\n\t\t\t},\n\t\t};\n\t}\n\n\t/** Prepares the firmware update of a single target by collecting the necessary information */\n\tprivate async prepareFirmwareUpdateInternal(\n\t\ttargets: number[],\n\t\tabortContext: AbortFirmwareUpdateContext,\n\t): Promise<\n\t\t| undefined\n\t\t| (FirmwareUpdateMetaData & {\n\t\t\tfragmentSizeSecure: number;\n\t\t\tfragmentSizeNonSecure: number;\n\t\t})\n\t> {\n\t\tconst api = this.commandClasses[\"Firmware Update Meta Data\"];\n\n\t\t// ================================\n\t\t// STEP 1:\n\t\t// Check if this update is possible\n\t\tconst meta = await api.getMetaData();\n\t\tif (!meta) {\n\t\t\tthrow new ZWaveError(\n\t\t\t\t`Failed to start the update: The node did not respond in time!`,\n\t\t\t\tZWaveErrorCodes.Controller_NodeTimeout,\n\t\t\t);\n\t\t}\n\n\t\tfor (const target of targets) {\n\t\t\tif (target === 0) {\n\t\t\t\tif (!meta.firmwareUpgradable) {\n\t\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t\t`Failed to start the update: The Z-Wave chip firmware is not upgradable!`,\n\t\t\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_NotUpgradable,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (api.version < 3) {\n\t\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t\t`Failed to start the update: The node does not support upgrading a different firmware target than 0!`,\n\t\t\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_TargetNotFound,\n\t\t\t\t\t);\n\t\t\t\t} else if (\n\t\t\t\t\tmeta.additionalFirmwareIDs[target - 1] == undefined\n\t\t\t\t) {\n\t\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t\t`Failed to start the update: Firmware target #${target} not found on this node!`,\n\t\t\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_TargetNotFound,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// ================================\n\t\t// STEP 2:\n\t\t// Determine the fragment size\n\t\tconst fcc = new FirmwareUpdateMetaDataCC({ nodeId: this.id });\n\t\tfcc.toggleEncapsulationFlag(\n\t\t\tEncapsulationFlags.Security,\n\t\t\tthis.driver.isCCSecure(fcc.ccId, this.id),\n\t\t);\n\t\tconst maxGrossPayloadSizeSecure = this.driver\n\t\t\t.computeNetCCPayloadSize(\n\t\t\t\tfcc,\n\t\t\t);\n\t\tconst maxGrossPayloadSizeNonSecure = this.driver\n\t\t\t.computeNetCCPayloadSize(fcc, true);\n\n\t\tconst ccVersion = getEffectiveCCVersion(this.driver, fcc);\n\t\tconst maxNetPayloadSizeSecure = maxGrossPayloadSizeSecure\n\t\t\t- 2 // report number\n\t\t\t- (ccVersion >= 2 ? 2 : 0); // checksum\n\t\tconst maxNetPayloadSizeNonSecure = maxGrossPayloadSizeNonSecure\n\t\t\t- 2 // report number\n\t\t\t- (ccVersion >= 2 ? 2 : 0); // checksum\n\n\t\t// Use the smallest allowed payload\n\t\tconst fragmentSizeSecure = Math.min(\n\t\t\tmaxNetPayloadSizeSecure,\n\t\t\tmeta.maxFragmentSize ?? Number.POSITIVE_INFINITY,\n\t\t);\n\t\tconst fragmentSizeNonSecure = Math.min(\n\t\t\tmaxNetPayloadSizeNonSecure,\n\t\t\tmeta.maxFragmentSize ?? Number.POSITIVE_INFINITY,\n\t\t);\n\n\t\tif (abortContext.abort) {\n\t\t\tabortContext.abortPromise.resolve(true);\n\t\t\treturn;\n\t\t} else {\n\t\t\treturn {\n\t\t\t\t...meta,\n\t\t\t\tfragmentSizeSecure,\n\t\t\t\tfragmentSizeNonSecure,\n\t\t\t};\n\t\t}\n\t}\n\n\tprotected async handleUnexpectedFirmwareUpdateGet(\n\t\tcommand: FirmwareUpdateMetaDataCCGet,\n\t): Promise<void> {\n\t\t// This method will only be called under two circumstances:\n\t\t// 1. The node is currently busy responding to a firmware update request -> remember the request\n\t\tif (this.isFirmwareUpdateInProgress()) {\n\t\t\tthis._firmwareUpdatePrematureRequest = command;\n\t\t\treturn;\n\t\t}\n\n\t\t// 2. No firmware update is in progress -> abort\n\t\tthis.driver.controllerLog.logNode(this.id, {\n\t\t\tmessage:\n\t\t\t\t`Received Firmware Update Get, but no firmware update is in progress. Forcing the node to abort...`,\n\t\t\tdirection: \"inbound\",\n\t\t});\n\n\t\t// Since no update is in progress, we need to determine the fragment size again\n\t\tconst fcc = new FirmwareUpdateMetaDataCC({ nodeId: this.id });\n\t\tfcc.toggleEncapsulationFlag(\n\t\t\tEncapsulationFlags.Security,\n\t\t\t!!(command.encapsulationFlags & EncapsulationFlags.Security),\n\t\t);\n\t\tconst ccVersion = getEffectiveCCVersion(this.driver, fcc);\n\t\tconst fragmentSize = this.driver.computeNetCCPayloadSize(fcc)\n\t\t\t- 2 // report number\n\t\t\t- (ccVersion >= 2 ? 2 : 0); // checksum\n\t\tconst fragment = randomBytes(fragmentSize);\n\t\ttry {\n\t\t\tawait this.sendCorruptedFirmwareUpdateReport(\n\t\t\t\tcommand.reportNumber,\n\t\t\t\tfragment,\n\t\t\t);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\t/** Kicks off a firmware update of a single target. Returns whether the node accepted resuming and non-secure transfer */\n\tprivate async *beginFirmwareUpdateInternal(\n\t\tdata: Uint8Array,\n\t\ttarget: number,\n\t\tmeta: FirmwareUpdateMetaData,\n\t\tfragmentSize: number,\n\t\tchecksum: number,\n\t\tresume: boolean | undefined,\n\t\tnonSecureTransfer: boolean | undefined,\n\t) {\n\t\tconst api = this.commandClasses[\"Firmware Update Meta Data\"];\n\n\t\t// ================================\n\t\t// STEP 3:\n\t\t// Start the update\n\t\tthis.driver.controllerLog.logNode(this.id, {\n\t\t\tmessage: `Starting firmware update...`,\n\t\t\tdirection: \"outbound\",\n\t\t});\n\n\t\t// Request the node to start the upgrade\n\t\tawait api.requestUpdate({\n\t\t\t// TODO: Should manufacturer id and firmware id be provided externally?\n\t\t\tmanufacturerId: meta.manufacturerId,\n\t\t\tfirmwareId: target == 0\n\t\t\t\t? meta.firmwareId\n\t\t\t\t: meta.additionalFirmwareIDs[target - 1],\n\t\t\tfirmwareTarget: target,\n\t\t\tfragmentSize,\n\t\t\tchecksum,\n\t\t\tresume,\n\t\t\tnonSecureTransfer,\n\t\t});\n\t\t// Pause the task until the response is received, because that can take\n\t\t// up to a minute\n\t\tconst result: FirmwareUpdateMetaDataCCRequestReport = yield () =>\n\t\t\tthis.driver\n\t\t\t\t.waitForCommand<FirmwareUpdateMetaDataCCRequestReport>(\n\t\t\t\t\t(cc) =>\n\t\t\t\t\t\tcc instanceof FirmwareUpdateMetaDataCCRequestReport\n\t\t\t\t\t\t&& cc.nodeId === this.id,\n\t\t\t\t\t60000,\n\t\t\t\t);\n\n\t\tswitch (result.status) {\n\t\t\tcase FirmwareUpdateRequestStatus.Error_AuthenticationExpected:\n\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t`Failed to start the update: A manual authentication event (e.g. button push) was expected!`,\n\t\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_FailedToStart,\n\t\t\t\t);\n\t\t\tcase FirmwareUpdateRequestStatus.Error_BatteryLow:\n\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t`Failed to start the update: The battery level is too low!`,\n\t\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_FailedToStart,\n\t\t\t\t);\n\t\t\tcase FirmwareUpdateRequestStatus\n\t\t\t\t.Error_FirmwareUpgradeInProgress:\n\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t`Failed to start the update: A firmware upgrade is already in progress!`,\n\t\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_Busy,\n\t\t\t\t);\n\t\t\tcase FirmwareUpdateRequestStatus\n\t\t\t\t.Error_InvalidManufacturerOrFirmwareID:\n\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t`Failed to start the update: Invalid manufacturer or firmware id!`,\n\t\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_FailedToStart,\n\t\t\t\t);\n\t\t\tcase FirmwareUpdateRequestStatus.Error_InvalidHardwareVersion:\n\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t`Failed to start the update: Invalid hardware version!`,\n\t\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_FailedToStart,\n\t\t\t\t);\n\t\t\tcase FirmwareUpdateRequestStatus.Error_NotUpgradable:\n\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t`Failed to start the update: Firmware target #${target} is not upgradable!`,\n\t\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_NotUpgradable,\n\t\t\t\t);\n\t\t\tcase FirmwareUpdateRequestStatus.Error_FragmentSizeTooLarge:\n\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t`Failed to start the update: The chosen fragment size is too large!`,\n\t\t\t\t\tZWaveErrorCodes.FirmwareUpdateCC_FailedToStart,\n\t\t\t\t);\n\t\t\tcase FirmwareUpdateRequestStatus.OK:\n\t\t\t\t// All good, we have started!\n\t\t\t\t// Keep the node awake until the update is done.\n\t\t\t\tthis.keepAwake = true;\n\t\t}\n\n\t\treturn {\n\t\t\tresume: !!result.resume,\n\t\t\tnonSecureTransfer: !!result.nonSecureTransfer,\n\t\t};\n\t}\n\n\tprotected async handleFirmwareUpdateMetaDataGet(\n\t\tcommand: FirmwareUpdateMetaDataCCMetaDataGet,\n\t): Promise<void> {\n\t\tconst endpoint = this.getEndpoint(command.endpointIndex)\n\t\t\t?? this;\n\n\t\t// We are being queried, so the device may actually not support the CC, just control it.\n\t\t// Using the commandClasses property would throw in that case\n\t\tconst api = endpoint\n\t\t\t.createAPI(CommandClasses[\"Firmware Update Meta Data\"], false)\n\t\t\t.withOptions({\n\t\t\t\t// Answer with the same encapsulation as asked, but omit\n\t\t\t\t// Supervision as it shouldn't be used for Get-Report flows\n\t\t\t\tencapsulationFlags: command.encapsulationFlags\n\t\t\t\t\t& ~EncapsulationFlags.Supervision,\n\t\t\t});\n\n\t\t// We do not support the firmware to be upgraded.\n\t\tawait api.reportMetaData({\n\t\t\tmanufacturerId: this.driver.options.vendor?.manufacturerId\n\t\t\t\t?? 0xffff,\n\t\t\tfirmwareUpgradable: false,\n\t\t\thardwareVersion: this.driver.options.vendor?.hardwareVersion\n\t\t\t\t?? 0,\n\t\t});\n\t}\n\n\tprivate async sendCorruptedFirmwareUpdateReport(\n\t\treportNum: number,\n\t\tfragment: Uint8Array,\n\t\tnonSecureTransfer: boolean = false,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tawait this.commandClasses[\"Firmware Update Meta Data\"]\n\t\t\t\t.withOptions({\n\t\t\t\t\t// Only encapsulate if the transfer is secure\n\t\t\t\t\tautoEncapsulate: !nonSecureTransfer,\n\t\t\t\t})\n\t\t\t\t.sendFirmwareFragment(reportNum, true, fragment);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\tprivate hasPendingFirmwareUpdateFragment(\n\t\tfragmentNumber: number,\n\t): boolean {\n\t\t// Avoid queuing duplicate fragments\n\t\tconst isCurrentFirmwareFragment = (t: Transaction) =>\n\t\t\tt.message.getNodeId() === this.id\n\t\t\t&& containsCC(t.message)\n\t\t\t&& t.message.command instanceof FirmwareUpdateMetaDataCCReport\n\t\t\t&& t.message.command.reportNumber === fragmentNumber;\n\n\t\treturn this.driver.hasPendingTransactions(\n\t\t\tisCurrentFirmwareFragment,\n\t\t);\n\t}\n\n\tprivate async *doFirmwareUpdateInternal(\n\t\tdata: Uint8Array,\n\t\tfragmentSize: number,\n\t\tnonSecureTransfer: boolean,\n\t\tabortContext: AbortFirmwareUpdateContext,\n\t\tonProgress: (fragment: number, total: number) => void,\n\t): AsyncGenerator<\n\t\tany,\n\t\tPartialFirmwareUpdateResult,\n\t\tany\n\t> {\n\t\tconst numFragments = Math.ceil(data.length / fragmentSize);\n\n\t\t// Make sure we're not responding to an outdated request immediately\n\t\tthis._firmwareUpdatePrematureRequest = undefined;\n\n\t\t// ================================\n\t\t// STEP 4:\n\t\t// Respond to fragment requests from the node\n\t\tupdate: while (true) {\n\t\t\tyield; // Give the task scheduler time to do something else\n\n\t\t\t// During ongoing firmware updates, it can happen that the next request is received before the callback for the previous response\n\t\t\t// is back. In that case we can immediately handle the premature request. Otherwise wait for the next request.\n\t\t\tlet fragmentRequest: FirmwareUpdateMetaDataCCGet;\n\t\t\tif (this._firmwareUpdatePrematureRequest) {\n\t\t\t\tfragmentRequest = this._firmwareUpdatePrematureRequest;\n\t\t\t\tthis._firmwareUpdatePrematureRequest = undefined;\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tfragmentRequest = yield () =>\n\t\t\t\t\t\tthis.driver\n\t\t\t\t\t\t\t.waitForCommand<FirmwareUpdateMetaDataCCGet>(\n\t\t\t\t\t\t\t\t(cc) =>\n\t\t\t\t\t\t\t\t\tcc.nodeId === this.id\n\t\t\t\t\t\t\t\t\t&& cc\n\t\t\t\t\t\t\t\t\t\tinstanceof FirmwareUpdateMetaDataCCGet,\n\t\t\t\t\t\t\t\t// Wait up to 2 minutes for each fragment request.\n\t\t\t\t\t\t\t\t// Some users try to update devices with unstable connections, where 30s can be too short.\n\t\t\t\t\t\t\t\ttimespan.minutes(2),\n\t\t\t\t\t\t\t);\n\t\t\t\t} catch {\n\t\t\t\t\t// In some cases it can happen that the device stops requesting update frames\n\t\t\t\t\t// We need to timeout the update in this case so it can be restarted\n\t\t\t\t\tthis.driver.controllerLog.logNode(this.id, {\n\t\t\t\t\t\tmessage: `Firmware update timed out`,\n\t\t\t\t\t\tdirection: \"none\",\n\t\t\t\t\t\tlevel: \"warn\",\n\t\t\t\t\t});\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tstatus: FirmwareUpdateStatus.Error_Timeout,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// When a node requests a firmware update fragment, it must be awake\n\t\t\tthis.markAsAwake();\n\n\t\t\tif (fragmentRequest.reportNumber > numFragments) {\n\t\t\t\tthis.driver.controllerLog.logNode(this.id, {\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t`Received Firmware Update Get for an out-of-bounds fragment. Forcing the node to abort...`,\n\t\t\t\t\tdirection: \"inbound\",\n\t\t\t\t});\n\t\t\t\tawait this.sendCorruptedFirmwareUpdateReport(\n\t\t\t\t\tfragmentRequest.reportNumber,\n\t\t\t\t\trandomBytes(fragmentSize),\n\t\t\t\t\tnonSecureTransfer,\n\t\t\t\t);\n\t\t\t\t// This will cause the node to abort the process, wait for that\n\t\t\t\tbreak update;\n\t\t\t}\n\n\t\t\t// Actually send the requested frames\n\t\t\trequest: for (\n\t\t\t\tlet num = fragmentRequest.reportNumber;\n\t\t\t\tnum\n\t\t\t\t\t< fragmentRequest.reportNumber\n\t\t\t\t\t\t+ fragmentRequest.numReports;\n\t\t\t\tnum++\n\t\t\t) {\n\t\t\t\tyield; // Give the task scheduler time to do something else\n\n\t\t\t\t// Check if the node requested more fragments than are left\n\t\t\t\tif (num > numFragments) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tconst fragment = data.subarray(\n\t\t\t\t\t(num - 1) * fragmentSize,\n\t\t\t\t\tnum * fragmentSize,\n\t\t\t\t);\n\n\t\t\t\tif (abortContext.abort) {\n\t\t\t\t\tawait this.sendCorruptedFirmwareUpdateReport(\n\t\t\t\t\t\tfragmentRequest.reportNumber,\n\t\t\t\t\t\trandomBytes(fragment.length),\n\t\t\t\t\t\tnonSecureTransfer,\n\t\t\t\t\t);\n\t\t\t\t\t// This will cause the node to abort the process, wait for that\n\t\t\t\t\tbreak update;\n\t\t\t\t} else {\n\t\t\t\t\t// Avoid queuing duplicate fragments\n\t\t\t\t\tif (this.hasPendingFirmwareUpdateFragment(num)) {\n\t\t\t\t\t\tthis.driver.controllerLog.logNode(this.id, {\n\t\t\t\t\t\t\tmessage: `Firmware fragment ${num} already queued`,\n\t\t\t\t\t\t\tlevel: \"warn\",\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue request;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.driver.controllerLog.logNode(this.id, {\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t`Sending firmware fragment ${num} / ${numFragments}`,\n\t\t\t\t\t\tdirection: \"outbound\",\n\t\t\t\t\t});\n\t\t\t\t\tconst isLast = num === numFragments;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this\n\t\t\t\t\t\t\t.commandClasses[\"Firmware Update Meta Data\"]\n\t\t\t\t\t\t\t.withOptions({\n\t\t\t\t\t\t\t\t// Only encapsulate if the transfer is secure\n\t\t\t\t\t\t\t\tautoEncapsulate: !nonSecureTransfer,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.sendFirmwareFragment(num, isLast, fragment);\n\n\t\t\t\t\t\tonProgress(num, numFragments);\n\n\t\t\t\t\t\t// If that was the last one wait for status report from the node and restart interview\n\t\t\t\t\t\tif (isLast) {\n\t\t\t\t\t\t\tabortContext.tooLateToAbort = true;\n\t\t\t\t\t\t\tbreak update;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// When transmitting fails, simply stop responding to this request and wait for the node to re-request the fragment\n\t\t\t\t\t\tthis.driver.controllerLog.logNode(this.id, {\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t`Failed to send firmware fragment ${num} / ${numFragments}`,\n\t\t\t\t\t\t\tdirection: \"outbound\",\n\t\t\t\t\t\t\tlevel: \"warn\",\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak request;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tyield; // Give the task scheduler time to do something else\n\n\t\t// ================================\n\t\t// STEP 5:\n\t\t// Finalize the update process\n\n\t\tconst statusReport:\n\t\t\t| FirmwareUpdateMetaDataCCStatusReport\n\t\t\t| undefined = yield () =>\n\t\t\t\tthis.driver\n\t\t\t\t\t.waitForCommand(\n\t\t\t\t\t\t(cc) =>\n\t\t\t\t\t\t\tcc.nodeId === this.id\n\t\t\t\t\t\t\t&& cc\n\t\t\t\t\t\t\t\tinstanceof FirmwareUpdateMetaDataCCStatusReport,\n\t\t\t\t\t\t// Wait up to 5 minutes. It should never take that long, but the specs\n\t\t\t\t\t\t// don't say anything specific\n\t\t\t\t\t\t5 * 60000,\n\t\t\t\t\t)\n\t\t\t\t\t.catch(() => undefined);\n\n\t\tif (abortContext.abort) {\n\t\t\tabortContext.abortPromise.resolve(\n\t\t\t\tstatusReport?.status\n\t\t\t\t\t=== FirmwareUpdateStatus.Error_TransmissionFailed,\n\t\t\t);\n\t\t}\n\n\t\tif (!statusReport) {\n\t\t\tthis.driver.controllerLog.logNode(\n\t\t\t\tthis.id,\n\t\t\t\t`The node did not acknowledge the completed update`,\n\t\t\t\t\"warn\",\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tstatus: FirmwareUpdateStatus.Error_Timeout,\n\t\t\t};\n\t\t}\n\n\t\tconst { status, waitTime } = statusReport;\n\n\t\t// Actually, OK_WaitingForActivation should never happen since we don't allow\n\t\t// delayed activation in the RequestGet command\n\t\tconst success = status >= FirmwareUpdateStatus.OK_WaitingForActivation;\n\n\t\treturn {\n\t\t\tsuccess,\n\t\t\tstatus,\n\t\t\twaitTime,\n\t\t};\n\t}\n}\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["result"]
|
|
7
7
|
}
|
|
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
7
|
var __export = (target, all) => {
|
|
7
8
|
for (var name in all)
|
|
8
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -23,6 +24,9 @@ __export(mixins_exports, {
|
|
|
23
24
|
module.exports = __toCommonJS(mixins_exports);
|
|
24
25
|
var import_FirmwareUpdate = require("./70_FirmwareUpdate.js");
|
|
25
26
|
class ZWaveNodeMixins extends import_FirmwareUpdate.FirmwareUpdateMixin {
|
|
27
|
+
static {
|
|
28
|
+
__name(this, "ZWaveNodeMixins");
|
|
29
|
+
}
|
|
26
30
|
}
|
|
27
31
|
// Annotate the CommonJS export names for ESM import in node:
|
|
28
32
|
0 && (module.exports = {
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/node/mixins/index.ts"],
|
|
4
4
|
"sourcesContent": ["import { FirmwareUpdateMixin } from \"./70_FirmwareUpdate.js\";\n\nexport abstract class ZWaveNodeMixins extends FirmwareUpdateMixin {}\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;;;;;AAAA,4BAAoC;AAE9B,MAAgB,wBAAwB,0CAAmB;EAFjE,OAEiE;;;;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
7
|
var __export = (target, all) => {
|
|
7
8
|
for (var name in all)
|
|
8
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -30,7 +31,7 @@ const defaultCapabilities = {
|
|
|
30
31
|
};
|
|
31
32
|
const STATE_KEY_PREFIX = "ColorSwitch_";
|
|
32
33
|
const StateKeys = {
|
|
33
|
-
component: (component) => `${STATE_KEY_PREFIX}${(0, import_shared.getEnumMemberName)(import_cc.ColorComponent, component)}
|
|
34
|
+
component: /* @__PURE__ */ __name((component) => `${STATE_KEY_PREFIX}${(0, import_shared.getEnumMemberName)(import_cc.ColorComponent, component)}`, "component")
|
|
34
35
|
};
|
|
35
36
|
const respondToColorSwitchSupportedGet = {
|
|
36
37
|
handleCC(controller, self, receivedCC) {
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/node/mockCCBehaviors/ColorSwitch.ts"],
|
|
4
4
|
"sourcesContent": ["import { ColorComponent, ColorComponentMap } from \"@zwave-js/cc\";\nimport {\n\tColorSwitchCCGet,\n\tColorSwitchCCReport,\n\tColorSwitchCCSet,\n\tColorSwitchCCStartLevelChange,\n\tColorSwitchCCStopLevelChange,\n\tColorSwitchCCSupportedGet,\n\tColorSwitchCCSupportedReport,\n} from \"@zwave-js/cc/ColorSwitchCC\";\nimport { CommandClasses } from \"@zwave-js/core/safe\";\nimport { getEnumMemberName } from \"@zwave-js/shared\";\nimport {\n\ttype ColorSwitchCCCapabilities,\n\ttype MockNodeBehavior,\n} from \"@zwave-js/testing\";\n\nconst defaultCapabilities: ColorSwitchCCCapabilities = {\n\tcolorComponents: {},\n};\n\nconst STATE_KEY_PREFIX = \"ColorSwitch_\";\nconst StateKeys = {\n\tcomponent: (component: ColorComponent) =>\n\t\t`${STATE_KEY_PREFIX}${getEnumMemberName(ColorComponent, component)}`,\n} as const;\n\nconst respondToColorSwitchSupportedGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ColorSwitchCCSupportedGet) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Color Switch\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst cc = new ColorSwitchCCSupportedReport({\n\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\tsupportedColorComponents: Object.keys(\n\t\t\t\t\tcapabilities.colorComponents,\n\t\t\t\t).map(\n\t\t\t\t\t(c) => parseInt(c),\n\t\t\t\t),\n\t\t\t});\n\t\t\treturn { action: \"sendCC\", cc };\n\t\t}\n\t},\n};\n\nconst respondToColorSwitchSet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ColorSwitchCCSet) {\n\t\t\tfor (const [key, value] of Object.entries(receivedCC.colorTable)) {\n\t\t\t\tconst component = ColorComponentMap[\n\t\t\t\t\tkey as any as keyof typeof ColorComponentMap\n\t\t\t\t];\n\t\t\t\tself.state.set(StateKeys.component(component), value);\n\t\t\t}\n\t\t\treturn { action: \"ok\" };\n\t\t}\n\t},\n};\n\nconst respondToColorSwitchGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ColorSwitchCCGet) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Color Switch\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst component = receivedCC.colorComponent;\n\t\t\tif (component in capabilities.colorComponents) {\n\t\t\t\tconst cc = new ColorSwitchCCReport({\n\t\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\t\tcolorComponent: component,\n\t\t\t\t\tcurrentValue:\n\t\t\t\t\t\t(self.state.get(StateKeys.component(component))\n\t\t\t\t\t\t\t?? capabilities.colorComponents[component]\n\t\t\t\t\t\t\t?? 0) as number,\n\t\t\t\t});\n\t\t\t\treturn { action: \"sendCC\", cc };\n\t\t\t} else {\n\t\t\t\treturn { action: \"stop\" };\n\t\t\t}\n\t\t}\n\t},\n};\n\nconst respondToColorSwitchStartLevelChange: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ColorSwitchCCStartLevelChange) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Color Switch\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\n\t\t\tconst component = receivedCC.colorComponent;\n\t\t\tif (component in capabilities.colorComponents) {\n\t\t\t\t// TODO: A proper simulation should gradually transition the value. We just set it to the target value.\n\t\t\t\tself.state.set(\n\t\t\t\t\tStateKeys.component(component),\n\t\t\t\t\treceivedCC.direction === \"up\" ? 255 : 0,\n\t\t\t\t);\n\n\t\t\t\treturn { action: \"ok\" };\n\t\t\t} else {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\t\t}\n\t},\n};\n\nconst respondToColorSwitchStopLevelChange: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ColorSwitchCCStopLevelChange) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Color Switch\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\n\t\t\tconst component = receivedCC.colorComponent;\n\t\t\tif (component in capabilities.colorComponents) {\n\t\t\t\treturn { action: \"ok\" };\n\t\t\t} else {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\t\t}\n\t},\n};\n\nexport const ColorSwitchCCBehaviors = [\n\trespondToColorSwitchSupportedGet,\n\trespondToColorSwitchSet,\n\trespondToColorSwitchGet,\n\trespondToColorSwitchStartLevelChange,\n\trespondToColorSwitchStopLevelChange,\n];\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;;;;;AAAA,gBAAkD;AAClD,2BAQO;AACP,kBAA+B;AAC/B,oBAAkC;AAMlC,MAAM,sBAAiD;EACtD,iBAAiB,CAAA;;AAGlB,MAAM,mBAAmB;AACzB,MAAM,YAAY;EACjB,WAAW,wBAAC,cACX,GAAG,gBAAgB,OAAG,iCAAkB,0BAAgB,SAAS,CAAC,IADxD;;AAIZ,MAAM,mCAAqD;EAC1D,SAAS,YAAY,MAAM,YAAU;AACpC,QAAI,sBAAsB,gDAA2B;AACpD,YAAM,eAAe;QACpB,GAAG;QACH,GAAG,KAAK,kBACP,2BAAe,cAAc,GAC7B,WAAW,aAAa;;AAG1B,YAAM,KAAK,IAAI,kDAA6B;QAC3C,QAAQ,WAAW;QACnB,0BAA0B,OAAO,KAChC,aAAa,eAAe,EAC3B,IACD,CAAC,MAAM,SAAS,CAAC,CAAC;OAEnB;AACD,aAAO,EAAE,QAAQ,UAAU,GAAE;IAC9B;EACD;;AAGD,MAAM,0BAA4C;EACjD,SAAS,YAAY,MAAM,YAAU;AACpC,QAAI,sBAAsB,uCAAkB;AAC3C,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,WAAW,UAAU,GAAG;AACjE,cAAM,YAAY,4BACjB,GAA4C;AAE7C,aAAK,MAAM,IAAI,UAAU,UAAU,SAAS,GAAG,KAAK;MACrD;AACA,aAAO,EAAE,QAAQ,KAAI;IACtB;EACD;;AAGD,MAAM,0BAA4C;EACjD,SAAS,YAAY,MAAM,YAAU;AACpC,QAAI,sBAAsB,uCAAkB;AAC3C,YAAM,eAAe;QACpB,GAAG;QACH,GAAG,KAAK,kBACP,2BAAe,cAAc,GAC7B,WAAW,aAAa;;AAG1B,YAAM,YAAY,WAAW;AAC7B,UAAI,aAAa,aAAa,iBAAiB;AAC9C,cAAM,KAAK,IAAI,yCAAoB;UAClC,QAAQ,WAAW;UACnB,gBAAgB;UAChB,cACE,KAAK,MAAM,IAAI,UAAU,UAAU,SAAS,CAAC,KAC1C,aAAa,gBAAgB,SAAS,KACtC;SACL;AACD,eAAO,EAAE,QAAQ,UAAU,GAAE;MAC9B,OAAO;AACN,eAAO,EAAE,QAAQ,OAAM;MACxB;IACD;EACD;;AAGD,MAAM,uCAAyD;EAC9D,SAAS,YAAY,MAAM,YAAU;AACpC,QAAI,sBAAsB,oDAA+B;AACxD,YAAM,eAAe;QACpB,GAAG;QACH,GAAG,KAAK,kBACP,2BAAe,cAAc,GAC7B,WAAW,aAAa;;AAI1B,YAAM,YAAY,WAAW;AAC7B,UAAI,aAAa,aAAa,iBAAiB;AAE9C,aAAK,MAAM,IACV,UAAU,UAAU,SAAS,GAC7B,WAAW,cAAc,OAAO,MAAM,CAAC;AAGxC,eAAO,EAAE,QAAQ,KAAI;MACtB,OAAO;AACN,eAAO,EAAE,QAAQ,OAAM;MACxB;IACD;EACD;;AAGD,MAAM,sCAAwD;EAC7D,SAAS,YAAY,MAAM,YAAU;AACpC,QAAI,sBAAsB,mDAA8B;AACvD,YAAM,eAAe;QACpB,GAAG;QACH,GAAG,KAAK,kBACP,2BAAe,cAAc,GAC7B,WAAW,aAAa;;AAI1B,YAAM,YAAY,WAAW;AAC7B,UAAI,aAAa,aAAa,iBAAiB;AAC9C,eAAO,EAAE,QAAQ,KAAI;MACtB,OAAO;AACN,eAAO,EAAE,QAAQ,OAAM;MACxB;IACD;EACD;;AAGM,MAAM,yBAAyB;EACrC;EACA;EACA;EACA;EACA;;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
7
|
var __export = (target, all) => {
|
|
7
8
|
for (var name in all)
|
|
8
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -29,7 +30,7 @@ const defaultCapabilities = {
|
|
|
29
30
|
};
|
|
30
31
|
const STATE_KEY_PREFIX = "Configuration_";
|
|
31
32
|
const StateKeys = {
|
|
32
|
-
value: (param) => `${STATE_KEY_PREFIX}value_${param}
|
|
33
|
+
value: /* @__PURE__ */ __name((param) => `${STATE_KEY_PREFIX}value_${param}`, "value")
|
|
33
34
|
};
|
|
34
35
|
const respondToConfigurationGet = {
|
|
35
36
|
handleCC(controller, self, receivedCC) {
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/node/mockCCBehaviors/Configuration.ts"],
|
|
4
4
|
"sourcesContent": ["import {\n\tConfigurationCCDefaultReset,\n\tConfigurationCCGet,\n\tConfigurationCCInfoGet,\n\tConfigurationCCInfoReport,\n\tConfigurationCCNameGet,\n\tConfigurationCCNameReport,\n\tConfigurationCCPropertiesGet,\n\tConfigurationCCPropertiesReport,\n\tConfigurationCCReport,\n\tConfigurationCCSet,\n} from \"@zwave-js/cc/ConfigurationCC\";\nimport { CommandClasses, ConfigValueFormat } from \"@zwave-js/core/safe\";\nimport {\n\ttype ConfigurationCCCapabilities,\n\ttype MockNodeBehavior,\n} from \"@zwave-js/testing\";\n\nconst defaultCapabilities: ConfigurationCCCapabilities = {\n\tbulkSupport: false,\n\tparameters: [],\n};\n\nconst STATE_KEY_PREFIX = \"Configuration_\";\nconst StateKeys = {\n\tvalue: (param: number) => `${STATE_KEY_PREFIX}value_${param}`,\n} as const;\n\nconst respondToConfigurationGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ConfigurationCCGet) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses.Configuration,\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\n\t\t\tconst parameter = receivedCC.parameter;\n\n\t\t\tconst paramInfo = capabilities.parameters.find(\n\t\t\t\t(p) => p[\"#\"] === parameter,\n\t\t\t);\n\n\t\t\t// Do not respond if the parameter is not supported\n\t\t\tif (!paramInfo) return { action: \"stop\" };\n\n\t\t\tconst value = (self.state.get(StateKeys.value(parameter)) as number)\n\t\t\t\t?? paramInfo.defaultValue\n\t\t\t\t?? 0;\n\n\t\t\tconst cc = new ConfigurationCCReport({\n\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\tparameter,\n\t\t\t\tvalue,\n\t\t\t\tvalueSize: paramInfo.valueSize,\n\t\t\t\tvalueFormat: paramInfo.format,\n\t\t\t});\n\t\t\treturn { action: \"sendCC\", cc };\n\t\t}\n\t},\n};\n\nconst respondToConfigurationSet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ConfigurationCCSet) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses.Configuration,\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst parameter = receivedCC.parameter;\n\t\t\tconst paramInfo = capabilities.parameters.find(\n\t\t\t\t(p) => p[\"#\"] === parameter,\n\t\t\t);\n\t\t\t// Do nothing if the parameter is not supported\n\t\t\tif (!paramInfo) return { action: \"fail\" };\n\n\t\t\tif (receivedCC.resetToDefault) {\n\t\t\t\tself.state.delete(StateKeys.value(parameter));\n\t\t\t\treturn { action: \"ok\" };\n\t\t\t}\n\n\t\t\tconst value = receivedCC.value!;\n\n\t\t\t// Do nothing if the value is out of range\n\t\t\tif (paramInfo.minValue != undefined && value < paramInfo.minValue) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t} else if (\n\t\t\t\tparamInfo.maxValue != undefined\n\t\t\t\t&& value > paramInfo.maxValue\n\t\t\t) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tself.state.set(StateKeys.value(parameter), value);\n\t\t\treturn { action: \"ok\" };\n\t\t}\n\t},\n};\n\nconst respondToConfigurationDefaultReset: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ConfigurationCCDefaultReset) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses.Configuration,\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tfor (const paramInfo of capabilities.parameters) {\n\t\t\t\tself.state.delete(StateKeys.value(paramInfo[\"#\"]));\n\t\t\t}\n\t\t\treturn { action: \"ok\" };\n\t\t}\n\t},\n};\n\nconst respondToConfigurationNameGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ConfigurationCCNameGet) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses.Configuration,\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst parameter = receivedCC.parameter;\n\t\t\tconst paramInfo = capabilities.parameters.find(\n\t\t\t\t(p) => p[\"#\"] === parameter,\n\t\t\t);\n\t\t\t// Do nothing if the parameter is not supported\n\t\t\tif (!paramInfo) return { action: \"fail\" };\n\n\t\t\tconst cc = new ConfigurationCCNameReport({\n\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\tparameter,\n\t\t\t\tname: paramInfo.name ?? \"\",\n\t\t\t\treportsToFollow: 0,\n\t\t\t});\n\t\t\treturn { action: \"sendCC\", cc };\n\t\t}\n\t},\n};\n\nconst respondToConfigurationInfoGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ConfigurationCCInfoGet) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses.Configuration,\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst parameter = receivedCC.parameter;\n\t\t\tconst paramInfo = capabilities.parameters.find(\n\t\t\t\t(p) => p[\"#\"] === parameter,\n\t\t\t);\n\t\t\t// Do nothing if the parameter is not supported\n\t\t\tif (!paramInfo) return { action: \"fail\" };\n\n\t\t\tconst cc = new ConfigurationCCInfoReport({\n\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\tparameter,\n\t\t\t\tinfo: paramInfo.info ?? \"\",\n\t\t\t\treportsToFollow: 0,\n\t\t\t});\n\t\t\treturn { action: \"sendCC\", cc };\n\t\t}\n\t},\n};\n\nconst respondToConfigurationPropertiesGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ConfigurationCCPropertiesGet) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses.Configuration,\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst parameter = receivedCC.parameter;\n\t\t\tconst paramIndex = capabilities.parameters.findIndex(\n\t\t\t\t(p) => p[\"#\"] === parameter,\n\t\t\t);\n\t\t\tconst paramInfo = capabilities.parameters[paramIndex];\n\t\t\tconst nextParameter = capabilities.parameters[paramIndex + 1];\n\n\t\t\tlet cc: ConfigurationCCPropertiesReport;\n\n\t\t\t// If the parameter is not supported, respond with the first supported parameter\n\t\t\tif (!paramInfo) {\n\t\t\t\tcc = new ConfigurationCCPropertiesReport({\n\t\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\t\tparameter,\n\t\t\t\t\tvalueFormat: 0,\n\t\t\t\t\tvalueSize: 0,\n\t\t\t\t\tnextParameter: nextParameter?.[\"#\"] ?? 0,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tcc = new ConfigurationCCPropertiesReport({\n\t\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\t\tparameter,\n\t\t\t\t\tvalueSize: paramInfo.valueSize,\n\t\t\t\t\tvalueFormat: paramInfo.format\n\t\t\t\t\t\t?? ConfigValueFormat.SignedInteger,\n\t\t\t\t\tminValue: paramInfo.minValue,\n\t\t\t\t\tmaxValue: paramInfo.maxValue,\n\t\t\t\t\tdefaultValue: paramInfo.defaultValue,\n\t\t\t\t\tisAdvanced: paramInfo.isAdvanced ?? false,\n\t\t\t\t\taltersCapabilities: paramInfo.altersCapabilities ?? false,\n\t\t\t\t\tisReadonly: paramInfo.readonly ?? false,\n\t\t\t\t\tnoBulkSupport: !(capabilities.bulkSupport ?? false),\n\t\t\t\t\tnextParameter: nextParameter?.[\"#\"] ?? 0,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { action: \"sendCC\", cc };\n\t\t}\n\t},\n};\n\nexport const ConfigurationCCBehaviors = [\n\trespondToConfigurationGet,\n\trespondToConfigurationSet,\n\trespondToConfigurationNameGet,\n\trespondToConfigurationInfoGet,\n\trespondToConfigurationPropertiesGet,\n\trespondToConfigurationDefaultReset,\n];\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
7
|
var __export = (target, all) => {
|
|
7
8
|
for (var name in all)
|
|
8
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -34,7 +35,7 @@ const STATE_KEY_PREFIX = "ScheduleEntryLock_";
|
|
|
34
35
|
const StateKeys = {
|
|
35
36
|
standardOffset: `${STATE_KEY_PREFIX}standardOffset`,
|
|
36
37
|
dstOffset: `${STATE_KEY_PREFIX}dstOffset`,
|
|
37
|
-
schedule: (userId, slotId, kind) => `${STATE_KEY_PREFIX}schedule_${userId}_${slotId}_${kind}
|
|
38
|
+
schedule: /* @__PURE__ */ __name((userId, slotId, kind) => `${STATE_KEY_PREFIX}schedule_${userId}_${slotId}_${kind}`, "schedule")
|
|
38
39
|
};
|
|
39
40
|
const respondToScheduleEntryLockSupportedGet = {
|
|
40
41
|
handleCC(controller, self, receivedCC) {
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/node/mockCCBehaviors/ScheduleEntryLock.ts"],
|
|
4
4
|
"sourcesContent": ["import {\n\ttype ScheduleEntryLockDailyRepeatingSchedule,\n\tScheduleEntryLockScheduleKind,\n\tScheduleEntryLockSetAction,\n\ttype ScheduleEntryLockWeekDaySchedule,\n\ttype ScheduleEntryLockYearDaySchedule,\n} from \"@zwave-js/cc\";\nimport {\n\tScheduleEntryLockCCDailyRepeatingScheduleGet,\n\tScheduleEntryLockCCDailyRepeatingScheduleReport,\n\tScheduleEntryLockCCDailyRepeatingScheduleSet,\n\tScheduleEntryLockCCEnableAllSet,\n\tScheduleEntryLockCCEnableSet,\n\tScheduleEntryLockCCSupportedGet,\n\tScheduleEntryLockCCSupportedReport,\n\tScheduleEntryLockCCTimeOffsetGet,\n\tScheduleEntryLockCCTimeOffsetReport,\n\tScheduleEntryLockCCTimeOffsetSet,\n\tScheduleEntryLockCCWeekDayScheduleGet,\n\tScheduleEntryLockCCWeekDayScheduleReport,\n\tScheduleEntryLockCCWeekDayScheduleSet,\n\tScheduleEntryLockCCYearDayScheduleGet,\n\tScheduleEntryLockCCYearDayScheduleReport,\n\tScheduleEntryLockCCYearDayScheduleSet,\n} from \"@zwave-js/cc/ScheduleEntryLockCC\";\nimport { CommandClasses } from \"@zwave-js/core/safe\";\nimport { type AllOrNone } from \"@zwave-js/shared/safe\";\nimport {\n\ttype MockNodeBehavior,\n\ttype ScheduleEntryLockCCCapabilities,\n} from \"@zwave-js/testing\";\nimport { defaultCapabilities as defaultUserCodeCapabilities } from \"./UserCode.js\";\n\nconst defaultCapabilities: ScheduleEntryLockCCCapabilities = {\n\tnumWeekDaySlots: 1,\n\tnumYearDaySlots: 0,\n\tnumDailyRepeatingSlots: 0,\n};\n\nconst STATE_KEY_PREFIX = \"ScheduleEntryLock_\";\nconst StateKeys = {\n\tstandardOffset: `${STATE_KEY_PREFIX}standardOffset`,\n\tdstOffset: `${STATE_KEY_PREFIX}dstOffset`,\n\tschedule: (\n\t\tuserId: number,\n\t\tslotId: number,\n\t\tkind: ScheduleEntryLockScheduleKind,\n\t) => `${STATE_KEY_PREFIX}schedule_${userId}_${slotId}_${kind}`,\n} as const;\n\nconst respondToScheduleEntryLockSupportedGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ScheduleEntryLockCCSupportedGet) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Schedule Entry Lock\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst cc = new ScheduleEntryLockCCSupportedReport({\n\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\t...capabilities,\n\t\t\t});\n\t\t\treturn { action: \"sendCC\", cc };\n\t\t}\n\t},\n};\n\nconst respondToScheduleEntryLockTimeOffsetSet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ScheduleEntryLockCCTimeOffsetSet) {\n\t\t\tself.state.set(\n\t\t\t\tStateKeys.standardOffset,\n\t\t\t\treceivedCC.standardOffset,\n\t\t\t);\n\t\t\tself.state.set(StateKeys.dstOffset, receivedCC.dstOffset);\n\t\t\treturn { action: \"ok\" };\n\t\t}\n\t},\n};\n\nconst respondToScheduleEntryLockTimeOffsetGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ScheduleEntryLockCCTimeOffsetGet) {\n\t\t\tconst cc = new ScheduleEntryLockCCTimeOffsetReport({\n\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\tstandardOffset: (self.state.get(StateKeys.standardOffset)\n\t\t\t\t\t?? 0) as number,\n\t\t\t\tdstOffset: (self.state.get(StateKeys.dstOffset) ?? 0) as number,\n\t\t\t});\n\t\t\treturn { action: \"sendCC\", cc };\n\t\t}\n\t},\n};\n\nconst respondToScheduleEntryLockEnableSet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ScheduleEntryLockCCEnableSet) {\n\t\t\t// No need to do anything, this cannot be queried\n\t\t\treturn { action: \"ok\" };\n\t\t}\n\t},\n};\n\nconst respondToScheduleEntryLockEnableAllSet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ScheduleEntryLockCCEnableAllSet) {\n\t\t\t// No need to do anything, this cannot be queried\n\t\t\treturn { action: \"ok\" };\n\t\t}\n\t},\n};\n\nconst respondToScheduleEntryLockWeekDayScheduleSet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ScheduleEntryLockCCWeekDayScheduleSet) {\n\t\t\tconst userCodeCapabilities = {\n\t\t\t\t...defaultUserCodeCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"User Code\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\t// If the user identifier is out of range, the command will be ignored\n\t\t\tconst userId = receivedCC.userId;\n\t\t\tif (userId > userCodeCapabilities.numUsers) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Schedule Entry Lock\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst slotId = receivedCC.slotId;\n\t\t\t// Ignore out of range slot queries\n\t\t\tif (slotId > capabilities.numWeekDaySlots) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tconst kind = ScheduleEntryLockScheduleKind.WeekDay;\n\n\t\t\tconst schedule =\n\t\t\t\treceivedCC.action === ScheduleEntryLockSetAction.Set\n\t\t\t\t\t? {\n\t\t\t\t\t\tweekday: receivedCC.weekday!,\n\t\t\t\t\t\tstartHour: receivedCC.startHour!,\n\t\t\t\t\t\tstartMinute: receivedCC.startMinute!,\n\t\t\t\t\t\tstopHour: receivedCC.stopHour!,\n\t\t\t\t\t\tstopMinute: receivedCC.stopMinute!,\n\t\t\t\t\t}\n\t\t\t\t\t: undefined;\n\n\t\t\tself.state.set(StateKeys.schedule(userId, slotId, kind), schedule);\n\t\t\treturn { action: \"ok\" };\n\t\t}\n\t},\n};\n\nconst respondToScheduleEntryLockWeekDayScheduleGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ScheduleEntryLockCCWeekDayScheduleGet) {\n\t\t\tconst userCodeCapabilities = {\n\t\t\t\t...defaultUserCodeCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"User Code\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\t// If the user identifier is out of range, the command will be ignored\n\t\t\tconst userId = receivedCC.userId;\n\t\t\tif (userId > userCodeCapabilities.numUsers) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Schedule Entry Lock\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst slotId = receivedCC.slotId;\n\t\t\t// Ignore out of range slot queries\n\t\t\tif (slotId > capabilities.numWeekDaySlots) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tconst kind = ScheduleEntryLockScheduleKind.WeekDay;\n\n\t\t\tconst schedule = (self.state.get(\n\t\t\t\tStateKeys.schedule(userId, slotId, kind),\n\t\t\t) ?? {}) as AllOrNone<ScheduleEntryLockWeekDaySchedule>;\n\n\t\t\tconst cc = new ScheduleEntryLockCCWeekDayScheduleReport({\n\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\tuserId,\n\t\t\t\tslotId,\n\t\t\t\t...schedule,\n\t\t\t});\n\t\t\treturn { action: \"sendCC\", cc };\n\t\t}\n\t},\n};\n\nconst respondToScheduleEntryLockYearDayScheduleSet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ScheduleEntryLockCCYearDayScheduleSet) {\n\t\t\tconst userCodeCapabilities = {\n\t\t\t\t...defaultUserCodeCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"User Code\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\t// If the user identifier is out of range, the command will be ignored\n\t\t\tconst userId = receivedCC.userId;\n\t\t\tif (userId > userCodeCapabilities.numUsers) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Schedule Entry Lock\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst slotId = receivedCC.slotId;\n\t\t\t// Ignore out of range slot queries\n\t\t\tif (slotId > capabilities.numYearDaySlots) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tconst kind = ScheduleEntryLockScheduleKind.YearDay;\n\n\t\t\tconst schedule =\n\t\t\t\treceivedCC.action === ScheduleEntryLockSetAction.Set\n\t\t\t\t\t? {\n\t\t\t\t\t\tstartYear: receivedCC.startYear!,\n\t\t\t\t\t\tstartMonth: receivedCC.startMonth!,\n\t\t\t\t\t\tstartDay: receivedCC.startDay!,\n\t\t\t\t\t\tstartHour: receivedCC.startHour!,\n\t\t\t\t\t\tstartMinute: receivedCC.startMinute!,\n\t\t\t\t\t\tstopYear: receivedCC.stopYear!,\n\t\t\t\t\t\tstopMonth: receivedCC.stopMonth!,\n\t\t\t\t\t\tstopDay: receivedCC.stopDay!,\n\t\t\t\t\t\tstopHour: receivedCC.stopHour!,\n\t\t\t\t\t\tstopMinute: receivedCC.stopMinute!,\n\t\t\t\t\t}\n\t\t\t\t\t: undefined;\n\n\t\t\tself.state.set(StateKeys.schedule(userId, slotId, kind), schedule);\n\t\t\treturn { action: \"ok\" };\n\t\t}\n\t},\n};\n\nconst respondToScheduleEntryLockYearDayScheduleGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ScheduleEntryLockCCYearDayScheduleGet) {\n\t\t\tconst userCodeCapabilities = {\n\t\t\t\t...defaultUserCodeCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"User Code\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\t// If the user identifier is out of range, the command will be ignored\n\t\t\tconst userId = receivedCC.userId;\n\t\t\tif (userId > userCodeCapabilities.numUsers) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Schedule Entry Lock\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst slotId = receivedCC.slotId;\n\t\t\t// Ignore out of range slot queries\n\t\t\tif (slotId > capabilities.numYearDaySlots) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tconst kind = ScheduleEntryLockScheduleKind.YearDay;\n\n\t\t\tconst schedule = (self.state.get(\n\t\t\t\tStateKeys.schedule(userId, slotId, kind),\n\t\t\t) ?? {}) as AllOrNone<ScheduleEntryLockYearDaySchedule>;\n\n\t\t\tconst cc = new ScheduleEntryLockCCYearDayScheduleReport({\n\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\tuserId,\n\t\t\t\tslotId,\n\t\t\t\t...schedule,\n\t\t\t});\n\t\t\treturn { action: \"sendCC\", cc };\n\t\t}\n\t},\n};\n\nconst respondToScheduleEntryLockDailyRepeatingScheduleSet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (\n\t\t\treceivedCC\n\t\t\t\tinstanceof ScheduleEntryLockCCDailyRepeatingScheduleSet\n\t\t) {\n\t\t\tconst userCodeCapabilities = {\n\t\t\t\t...defaultUserCodeCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"User Code\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\t// If the user identifier is out of range, the command will be ignored\n\t\t\tconst userId = receivedCC.userId;\n\t\t\tif (userId > userCodeCapabilities.numUsers) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Schedule Entry Lock\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst slotId = receivedCC.slotId;\n\t\t\t// Ignore out of range slot queries\n\t\t\tif (slotId > capabilities.numDailyRepeatingSlots) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tconst kind = ScheduleEntryLockScheduleKind.DailyRepeating;\n\n\t\t\tconst schedule =\n\t\t\t\treceivedCC.action === ScheduleEntryLockSetAction.Set\n\t\t\t\t\t? {\n\t\t\t\t\t\tweekdays: receivedCC.weekdays!,\n\t\t\t\t\t\tstartHour: receivedCC.startHour!,\n\t\t\t\t\t\tstartMinute: receivedCC.startMinute!,\n\t\t\t\t\t\tdurationHour: receivedCC.durationHour!,\n\t\t\t\t\t\tdurationMinute: receivedCC.durationMinute!,\n\t\t\t\t\t}\n\t\t\t\t\t: undefined;\n\n\t\t\tself.state.set(StateKeys.schedule(userId, slotId, kind), schedule);\n\t\t\treturn { action: \"ok\" };\n\t\t}\n\t},\n};\n\nconst respondToScheduleEntryLockDailyRepeatingScheduleGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (\n\t\t\treceivedCC\n\t\t\t\tinstanceof ScheduleEntryLockCCDailyRepeatingScheduleGet\n\t\t) {\n\t\t\tconst userCodeCapabilities = {\n\t\t\t\t...defaultUserCodeCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"User Code\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\t// If the user identifier is out of range, the command will be ignored\n\t\t\tconst userId = receivedCC.userId;\n\t\t\tif (userId > userCodeCapabilities.numUsers) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Schedule Entry Lock\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst slotId = receivedCC.slotId;\n\t\t\t// Ignore out of range slot queries\n\t\t\tif (slotId > capabilities.numDailyRepeatingSlots) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tconst kind = ScheduleEntryLockScheduleKind.DailyRepeating;\n\n\t\t\tconst schedule = (self.state.get(\n\t\t\t\tStateKeys.schedule(userId, slotId, kind),\n\t\t\t) ?? {}) as AllOrNone<ScheduleEntryLockDailyRepeatingSchedule>;\n\n\t\t\tconst cc = new ScheduleEntryLockCCDailyRepeatingScheduleReport({\n\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\tuserId,\n\t\t\t\tslotId,\n\t\t\t\t...schedule,\n\t\t\t});\n\t\t\treturn { action: \"sendCC\", cc };\n\t\t}\n\t},\n};\n\nexport const ScheduleEntryLockCCBehaviors = [\n\trespondToScheduleEntryLockSupportedGet,\n\trespondToScheduleEntryLockTimeOffsetSet,\n\trespondToScheduleEntryLockTimeOffsetGet,\n\trespondToScheduleEntryLockEnableSet,\n\trespondToScheduleEntryLockEnableAllSet,\n\trespondToScheduleEntryLockWeekDayScheduleSet,\n\trespondToScheduleEntryLockWeekDayScheduleGet,\n\trespondToScheduleEntryLockYearDayScheduleSet,\n\trespondToScheduleEntryLockYearDayScheduleGet,\n\trespondToScheduleEntryLockDailyRepeatingScheduleSet,\n\trespondToScheduleEntryLockDailyRepeatingScheduleGet,\n];\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["defaultUserCodeCapabilities"]
|
|
7
7
|
}
|
|
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
7
|
var __export = (target, all) => {
|
|
7
8
|
for (var name in all)
|
|
8
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -35,8 +36,8 @@ const defaultCapabilities = {
|
|
|
35
36
|
};
|
|
36
37
|
const STATE_KEY_PREFIX = "ThermostatSetpoint_";
|
|
37
38
|
const StateKeys = {
|
|
38
|
-
setpoint: (type) => `${STATE_KEY_PREFIX}setpoint_${type}`,
|
|
39
|
-
scale: (type) => `${STATE_KEY_PREFIX}scale_${type}
|
|
39
|
+
setpoint: /* @__PURE__ */ __name((type) => `${STATE_KEY_PREFIX}setpoint_${type}`, "setpoint"),
|
|
40
|
+
scale: /* @__PURE__ */ __name((type) => `${STATE_KEY_PREFIX}scale_${type}`, "scale")
|
|
40
41
|
};
|
|
41
42
|
const respondToThermostatSetpointSet = {
|
|
42
43
|
handleCC(controller, self, receivedCC) {
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/node/mockCCBehaviors/ThermostatSetpoint.ts"],
|
|
4
4
|
"sourcesContent": ["import { ThermostatSetpointType } from \"@zwave-js/cc\";\nimport {\n\tThermostatSetpointCCCapabilitiesGet,\n\tThermostatSetpointCCCapabilitiesReport,\n\tThermostatSetpointCCGet,\n\tThermostatSetpointCCReport,\n\tThermostatSetpointCCSet,\n\tThermostatSetpointCCSupportedGet,\n\tThermostatSetpointCCSupportedReport,\n} from \"@zwave-js/cc/ThermostatSetpointCC\";\nimport { CommandClasses } from \"@zwave-js/core/safe\";\nimport {\n\ttype MockNodeBehavior,\n\ttype ThermostatSetpointCCCapabilities,\n} from \"@zwave-js/testing\";\n\nconst defaultCapabilities: ThermostatSetpointCCCapabilities = {\n\tsetpoints: {\n\t\t[ThermostatSetpointType.Heating]: {\n\t\t\tminValue: 0,\n\t\t\tmaxValue: 100,\n\t\t\tscale: \"\u00B0C\",\n\t\t},\n\t},\n};\n\nconst STATE_KEY_PREFIX = \"ThermostatSetpoint_\";\nconst StateKeys = {\n\tsetpoint: (type: ThermostatSetpointType) =>\n\t\t`${STATE_KEY_PREFIX}setpoint_${type}`,\n\tscale: (type: ThermostatSetpointType) => `${STATE_KEY_PREFIX}scale_${type}`,\n} as const;\n\nconst respondToThermostatSetpointSet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ThermostatSetpointCCSet) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Thermostat Setpoint\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\t\t\tconst setpointCaps =\n\t\t\t\tcapabilities.setpoints[receivedCC.setpointType];\n\t\t\tif (!setpointCaps) return { action: \"fail\" };\n\n\t\t\tconst value = receivedCC.value;\n\t\t\tif (\n\t\t\t\tvalue > setpointCaps.minValue\n\t\t\t\t|| value > setpointCaps.maxValue\n\t\t\t) {\n\t\t\t\treturn { action: \"fail\" };\n\t\t\t}\n\n\t\t\tself.state.set(\n\t\t\t\tStateKeys.setpoint(receivedCC.setpointType),\n\t\t\t\tvalue,\n\t\t\t);\n\t\t\tself.state.set(\n\t\t\t\tStateKeys.scale(receivedCC.setpointType),\n\t\t\t\treceivedCC.scale,\n\t\t\t);\n\t\t\treturn { action: \"ok\" };\n\t\t}\n\t},\n};\n\nconst respondToThermostatSetpointGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ThermostatSetpointCCGet) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Thermostat Setpoint\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\n\t\t\tconst setpointType = receivedCC.setpointType;\n\n\t\t\tconst setpointCaps = capabilities.setpoints[setpointType];\n\n\t\t\tlet value = self.state.get(StateKeys.setpoint(setpointType)) as\n\t\t\t\t| number\n\t\t\t\t| undefined;\n\t\t\tlet scale = self.state.get(StateKeys.scale(setpointType)) as\n\t\t\t\t| number\n\t\t\t\t| undefined;\n\t\t\tif (setpointCaps) {\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tvalue = setpointCaps.defaultValue ?? setpointCaps.minValue;\n\t\t\t\t}\n\t\t\t\tif (scale === undefined) {\n\t\t\t\t\tscale = setpointCaps.scale === \"\u00B0F\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet cc: ThermostatSetpointCCReport;\n\t\t\tif (value !== undefined) {\n\t\t\t\tcc = new ThermostatSetpointCCReport({\n\t\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\t\ttype: setpointType,\n\t\t\t\t\tvalue,\n\t\t\t\t\tscale: scale ?? 0,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tcc = new ThermostatSetpointCCReport({\n\t\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\t\ttype: ThermostatSetpointType[\"N/A\"],\n\t\t\t\t\tscale: 0,\n\t\t\t\t\tvalue: 0,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { action: \"sendCC\", cc };\n\t\t}\n\t},\n};\n\nconst respondToThermostatSetpointSupportedGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ThermostatSetpointCCSupportedGet) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Thermostat Setpoint\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\n\t\t\tconst cc = new ThermostatSetpointCCSupportedReport({\n\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\tsupportedSetpointTypes: Object.keys(capabilities.setpoints).map(\n\t\t\t\t\t(k) => parseInt(k),\n\t\t\t\t),\n\t\t\t});\n\t\t\treturn { action: \"sendCC\", cc };\n\t\t}\n\t},\n};\n\nconst respondToThermostatSetpointCapabilitiesGet: MockNodeBehavior = {\n\thandleCC(controller, self, receivedCC) {\n\t\tif (receivedCC instanceof ThermostatSetpointCCCapabilitiesGet) {\n\t\t\tconst capabilities = {\n\t\t\t\t...defaultCapabilities,\n\t\t\t\t...self.getCCCapabilities(\n\t\t\t\t\tCommandClasses[\"Thermostat Setpoint\"],\n\t\t\t\t\treceivedCC.endpointIndex,\n\t\t\t\t),\n\t\t\t};\n\n\t\t\tconst setpointType = receivedCC.setpointType;\n\t\t\tconst setpointCaps = capabilities.setpoints[setpointType];\n\n\t\t\tlet cc: ThermostatSetpointCCCapabilitiesReport;\n\t\t\tif (setpointCaps) {\n\t\t\t\tcc = new ThermostatSetpointCCCapabilitiesReport({\n\t\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\t\ttype: setpointType,\n\t\t\t\t\tminValue: setpointCaps.minValue,\n\t\t\t\t\tmaxValue: setpointCaps.maxValue,\n\t\t\t\t\tminValueScale: setpointCaps.scale === \"\u00B0C\" ? 0 : 1,\n\t\t\t\t\tmaxValueScale: setpointCaps.scale === \"\u00B0C\" ? 0 : 1,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tcc = new ThermostatSetpointCCCapabilitiesReport({\n\t\t\t\t\tnodeId: controller.ownNodeId,\n\t\t\t\t\ttype: ThermostatSetpointType[\"N/A\"],\n\t\t\t\t\tminValue: 0,\n\t\t\t\t\tmaxValue: 0,\n\t\t\t\t\tminValueScale: 0,\n\t\t\t\t\tmaxValueScale: 0,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { action: \"sendCC\", cc };\n\t\t}\n\t},\n};\n\nexport const ThermostatSetpointCCBehaviors = [\n\trespondToThermostatSetpointGet,\n\trespondToThermostatSetpointSet,\n\trespondToThermostatSetpointSupportedGet,\n\trespondToThermostatSetpointCapabilitiesGet,\n];\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
7
|
var __export = (target, all) => {
|
|
7
8
|
for (var name in all)
|
|
8
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -41,8 +42,8 @@ const defaultCapabilities = {
|
|
|
41
42
|
};
|
|
42
43
|
const STATE_KEY_PREFIX = "UserCode_";
|
|
43
44
|
const StateKeys = {
|
|
44
|
-
userCode: (userId) => `${STATE_KEY_PREFIX}userCode_${userId}`,
|
|
45
|
-
userIdStatus: (userId) => `${STATE_KEY_PREFIX}userIdStatus_${userId}`,
|
|
45
|
+
userCode: /* @__PURE__ */ __name((userId) => `${STATE_KEY_PREFIX}userCode_${userId}`, "userCode"),
|
|
46
|
+
userIdStatus: /* @__PURE__ */ __name((userId) => `${STATE_KEY_PREFIX}userIdStatus_${userId}`, "userIdStatus"),
|
|
46
47
|
adminCode: `${STATE_KEY_PREFIX}adminCode`,
|
|
47
48
|
keypadMode: `${STATE_KEY_PREFIX}keypadMode`
|
|
48
49
|
};
|