diff --git a/.gitignore b/.gitignore index 7d34db5f6209..c3c05297d253 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,8 @@ coverage/ # npm package files zwave-js-*.tgz +zwave-js.tgz +.monopack/ # ZWave cache */cache diff --git a/packages/cc/api.md b/packages/cc/api.md index f9c6ce540df7..7ed8cc137db3 100644 --- a/packages/cc/api.md +++ b/packages/cc/api.md @@ -4590,11 +4590,11 @@ export const DoorLockCCValues: Readonly<{ }; readonly options: { readonly internal: false; - readonly minVersion: 1; - readonly secret: false; readonly stateful: true; + readonly secret: false; + readonly minVersion: 1; readonly supportsEndpoints: true; - readonly autoCreate: true; + readonly autoCreate: (applHost: ZWaveApplicationHost_2, endpoint: IZWaveEndpoint_2) => boolean; }; }; doorSupported: { @@ -4641,11 +4641,11 @@ export const DoorLockCCValues: Readonly<{ }; readonly options: { readonly internal: false; - readonly minVersion: 1; - readonly secret: false; readonly stateful: true; + readonly secret: false; + readonly minVersion: 1; readonly supportsEndpoints: true; - readonly autoCreate: true; + readonly autoCreate: (applHost: ZWaveApplicationHost_2, endpoint: IZWaveEndpoint_2) => boolean; }; }; boltSupported: { @@ -4692,11 +4692,11 @@ export const DoorLockCCValues: Readonly<{ }; readonly options: { readonly internal: false; - readonly minVersion: 1; - readonly secret: false; readonly stateful: true; + readonly secret: false; + readonly minVersion: 1; readonly supportsEndpoints: true; - readonly autoCreate: true; + readonly autoCreate: (applHost: ZWaveApplicationHost_2, endpoint: IZWaveEndpoint_2) => boolean; }; }; latchSupported: { diff --git a/packages/cc/src/cc/DoorLockCC.ts b/packages/cc/src/cc/DoorLockCC.ts index cff3d566af8f..7781568c0b9a 100644 --- a/packages/cc/src/cc/DoorLockCC.ts +++ b/packages/cc/src/cc/DoorLockCC.ts @@ -2,6 +2,7 @@ import { CommandClasses, Duration, enumValuesToMetadataStates, + IZWaveEndpoint, Maybe, MessageOrCCLogEntry, MessagePriority, @@ -169,25 +170,76 @@ export const DoorLockCCValues = Object.freeze({ ), ...V.staticProperty("latchSupported", undefined, { internal: true }), - ...V.staticProperty("latchStatus", { - ...ValueMetadata.ReadOnly, - label: "Current status of the latch", - } as const), + ...V.staticProperty( + "latchStatus", + { + ...ValueMetadata.ReadOnly, + label: "Current status of the latch", + } as const, + { + autoCreate: shouldAutoCreateLatchStatusValue, + } as const, + ), ...V.staticProperty("boltSupported", undefined, { internal: true }), - ...V.staticProperty("boltStatus", { - ...ValueMetadata.ReadOnly, - label: "Current status of the bolt", - } as const), + ...V.staticProperty( + "boltStatus", + { + ...ValueMetadata.ReadOnly, + label: "Current status of the bolt", + } as const, + { + autoCreate: shouldAutoCreateBoltStatusValue, + } as const, + ), ...V.staticProperty("doorSupported", undefined, { internal: true }), - ...V.staticProperty("doorStatus", { - ...ValueMetadata.ReadOnly, - label: "Current status of the door", - } as const), + ...V.staticProperty( + "doorStatus", + { + ...ValueMetadata.ReadOnly, + label: "Current status of the door", + } as const, + { + autoCreate: shouldAutoCreateDoorStatusValue, + } as const, + ), }), }); +function shouldAutoCreateLatchStatusValue( + applHost: ZWaveApplicationHost, + endpoint: IZWaveEndpoint, +): boolean { + const valueDB = applHost.tryGetValueDB(endpoint.nodeId); + if (!valueDB) return false; + return !!valueDB.getValue( + DoorLockCCValues.latchSupported.endpoint(endpoint.index), + ); +} + +function shouldAutoCreateBoltStatusValue( + applHost: ZWaveApplicationHost, + endpoint: IZWaveEndpoint, +): boolean { + const valueDB = applHost.tryGetValueDB(endpoint.nodeId); + if (!valueDB) return false; + return !!valueDB.getValue( + DoorLockCCValues.boltSupported.endpoint(endpoint.index), + ); +} + +function shouldAutoCreateDoorStatusValue( + applHost: ZWaveApplicationHost, + endpoint: IZWaveEndpoint, +): boolean { + const valueDB = applHost.tryGetValueDB(endpoint.nodeId); + if (!valueDB) return false; + return !!valueDB.getValue( + DoorLockCCValues.doorSupported.endpoint(endpoint.index), + ); +} + const configurationSetParameters = [ "operationType", "outsideHandlesCanOpenDoorConfiguration", @@ -536,11 +588,7 @@ supports block to block: ${resp.blockToBlockSupported}`; if (!hadCriticalTimeout) { // Save support information for the status values const doorStatusValue = DoorLockCCValues.doorStatus; - this.setMetadata( - applHost, - doorStatusValue, - doorSupported ? doorStatusValue.meta : undefined, - ); + if (doorSupported) this.setMetadata(applHost, doorStatusValue); this.setValue( applHost, DoorLockCCValues.doorSupported, @@ -548,11 +596,7 @@ supports block to block: ${resp.blockToBlockSupported}`; ); const latchStatusValue = DoorLockCCValues.latchStatus; - this.setMetadata( - applHost, - latchStatusValue, - latchSupported ? latchStatusValue.meta : undefined, - ); + if (latchSupported) this.setMetadata(applHost, latchStatusValue); this.setValue( applHost, DoorLockCCValues.latchSupported, @@ -560,11 +604,7 @@ supports block to block: ${resp.blockToBlockSupported}`; ); const boltStatusValue = DoorLockCCValues.boltStatus; - this.setMetadata( - applHost, - boltStatusValue, - boltSupported ? boltStatusValue.meta : undefined, - ); + if (boltSupported) this.setMetadata(applHost, boltStatusValue); this.setValue( applHost, DoorLockCCValues.boltSupported, diff --git a/packages/cc/src/lib/CommandClass.ts b/packages/cc/src/lib/CommandClass.ts index 06f069327fca..3954cd16534b 100644 --- a/packages/cc/src/lib/CommandClass.ts +++ b/packages/cc/src/lib/CommandClass.ts @@ -725,6 +725,17 @@ export class CommandClass implements ICommandClass { ); } + private shouldAutoCreateValue( + applHost: ZWaveApplicationHost, + value: StaticCCValue, + ): boolean { + return ( + value.options.autoCreate === true || + (typeof value.options.autoCreate === "function" && + value.options.autoCreate(applHost, this.getEndpoint(applHost)!)) + ); + } + /** Returns a list of all value names that are defined for this CommandClass */ public getDefinedValueIDs(applHost: ZWaveApplicationHost): ValueID[] { // In order to compare value ids, we need them to be strings @@ -769,16 +780,7 @@ export class CommandClass implements ICommandClass { if (value.options.internal) continue; // And determine if this value should be automatically "created" - if ( - value.options.autoCreate === false || - (typeof value.options.autoCreate === "function" && - !value.options.autoCreate( - applHost, - this.getEndpoint(applHost)!, - )) - ) { - continue; - } + if (!this.shouldAutoCreateValue(applHost, value)) continue; existingValueIds.push(value.endpoint(this.endpointIndex)); } @@ -858,7 +860,9 @@ export class CommandClass implements ICommandClass { // ... but only if the value is included in the report we are persisting (sourceValue != undefined || // ... or if we know which CC version the node supports - this._knownVersion >= value.options.minVersion); + // and the value may be automatically created + (this._knownVersion >= value.options.minVersion && + this.shouldAutoCreateValue(applHost, value))); if (createMetadata && !valueDB.hasMetadata(valueId)) { valueDB.setMetadata(valueId, value.meta);