@@ -80,40 +80,43 @@ function arrayEquals<T>(as: T[], bs: T[]): boolean {
80
80
return true ;
81
81
}
82
82
83
- function addToLookup ( zigbeeModel : string , definition : Definition ) : void {
84
- zigbeeModel = zigbeeModel ? zigbeeModel . toLowerCase ( ) : null ;
83
+ function addToLookup ( zigbeeModel : string | undefined , definition : Definition ) : void {
84
+ const lookupModel = zigbeeModel ? zigbeeModel . toLowerCase ( ) : ' null' ;
85
85
86
- if ( ! lookup . has ( zigbeeModel ) ) {
87
- lookup . set ( zigbeeModel , [ ] ) ;
86
+ if ( ! lookup . has ( lookupModel ) ) {
87
+ lookup . set ( lookupModel , [ ] ) ;
88
88
}
89
89
90
- if ( ! lookup . get ( zigbeeModel ) . includes ( definition ) ) {
91
- lookup . get ( zigbeeModel ) . splice ( 0 , 0 , definition ) ;
90
+ // key created above as needed
91
+ if ( ! lookup . get ( lookupModel ) ! . includes ( definition ) ) {
92
+ lookup . get ( lookupModel ) ! . splice ( 0 , 0 , definition ) ;
92
93
}
93
94
}
94
95
95
- function removeFromLookup ( zigbeeModel : string , definition : Definition ) : void {
96
- if ( lookup . has ( zigbeeModel ) ) {
97
- const i = lookup . get ( zigbeeModel ) . indexOf ( definition ) ;
96
+ function removeFromLookup ( zigbeeModel : string | undefined , definition : Definition ) : void {
97
+ const lookupModel = zigbeeModel ? zigbeeModel . toLowerCase ( ) : 'null' ;
98
+
99
+ if ( lookup . has ( lookupModel ) ) {
100
+ const i = lookup . get ( lookupModel ) ! . indexOf ( definition ) ;
98
101
99
102
if ( i > - 1 ) {
100
- lookup . get ( zigbeeModel ) . splice ( i , 1 ) ;
103
+ lookup . get ( lookupModel ) ! . splice ( i , 1 ) ;
101
104
}
102
- }
103
105
104
- if ( lookup . get ( zigbeeModel ) . length === 0 ) {
105
- lookup . delete ( zigbeeModel ) ;
106
+ if ( lookup . get ( lookupModel ) ! . length === 0 ) {
107
+ lookup . delete ( lookupModel ) ;
108
+ }
106
109
}
107
110
}
108
111
109
- function getFromLookup ( zigbeeModel : string ) : Definition [ ] | undefined {
110
- zigbeeModel = zigbeeModel ? zigbeeModel . toLowerCase ( ) : null ;
112
+ function getFromLookup ( zigbeeModel : string | undefined ) : Definition [ ] | undefined {
113
+ const lookupModel = zigbeeModel ? zigbeeModel . toLowerCase ( ) : ' null' ;
111
114
112
- if ( lookup . has ( zigbeeModel ) ) {
113
- return lookup . get ( zigbeeModel ) ;
115
+ if ( lookup . has ( lookupModel ) ) {
116
+ return lookup . get ( lookupModel ) ;
114
117
}
115
118
116
- return lookup . get ( zigbeeModel ? zigbeeModel . replace ( / \0 ( .| \n ) * $ / g, '' ) . trim ( ) : null ) ;
119
+ return lookup . get ( lookupModel . replace ( / \0 ( .| \n ) * $ / g, '' ) . trim ( ) ) ;
117
120
}
118
121
119
122
const converterRequiredFields = {
@@ -126,13 +129,11 @@ const converterRequiredFields = {
126
129
127
130
function validateDefinition ( definition : Definition ) : asserts definition is Definition {
128
131
for ( const [ field , expectedType ] of Object . entries ( converterRequiredFields ) ) {
129
- assert . notStrictEqual ( null , definition [ field as keyof Definition ] , `Converter field ${ field } is null` ) ;
130
- assert . notStrictEqual ( undefined , definition [ field as keyof Definition ] , `Converter field ${ field } is undefined` ) ;
131
- assert . strictEqual (
132
- definition [ field as keyof Definition ] . constructor . name ,
133
- expectedType ,
134
- `Converter field ${ field } expected type doenst match to ${ definition [ field as keyof Definition ] } ` ,
135
- ) ;
132
+ const val = definition [ field as keyof Definition ] ;
133
+
134
+ assert ( val !== null , `Converter field ${ field } is null` ) ;
135
+ assert ( val !== undefined , `Converter field ${ field } is undefined` ) ;
136
+ assert ( val . constructor . name === expectedType , `Converter field ${ field } expected type doenst match to ${ val } ` ) ;
136
137
}
137
138
138
139
assert . ok ( Array . isArray ( definition . exposes ) || typeof definition . exposes === 'function' , 'Exposes incorrect' ) ;
@@ -247,7 +248,7 @@ function processExtensions(definition: DefinitionWithExtend): Definition {
247
248
allExposes . push ( exposesLib . presets . action ( uniqueActions ) ) ;
248
249
}
249
250
250
- let configure : Configure = null ;
251
+ let configure : Configure | undefined ;
251
252
252
253
if ( configures . length !== 0 ) {
253
254
configure = async ( device , coordinatorEndpoint , configureDefinition ) => {
@@ -257,7 +258,7 @@ function processExtensions(definition: DefinitionWithExtend): Definition {
257
258
} ;
258
259
}
259
260
260
- let onEvent : OnEvent = null ;
261
+ let onEvent : OnEvent | undefined ;
261
262
262
263
if ( onEvents . length !== 0 ) {
263
264
onEvent = async ( type , data , device , settings , state ) => {
@@ -325,7 +326,7 @@ function prepareDefinition(definition: DefinitionWithExtend): Definition {
325
326
const optionKeys = definition . options . map ( ( o ) => o . name ) ;
326
327
327
328
// Add calibration/precision options based on expose
328
- for ( const expose of Array . isArray ( definition . exposes ) ? definition . exposes : definition . exposes ( null , null ) ) {
329
+ for ( const expose of Array . isArray ( definition . exposes ) ? definition . exposes : definition . exposes ( undefined , undefined ) ) {
329
330
if (
330
331
! optionKeys . includes ( expose . name ) &&
331
332
utils . isNumericExpose ( expose ) &&
@@ -367,14 +368,14 @@ function prepareDefinition(definition: DefinitionWithExtend): Definition {
367
368
export function postProcessConvertedFromZigbeeMessage ( definition : Definition , payload : KeyValue , options : KeyValue ) : void {
368
369
// Apply calibration/precision options
369
370
for ( const [ key , value ] of Object . entries ( payload ) ) {
370
- const definitionExposes = Array . isArray ( definition . exposes ) ? definition . exposes : definition . exposes ( null , null ) ;
371
+ const definitionExposes = Array . isArray ( definition . exposes ) ? definition . exposes : definition . exposes ( undefined , undefined ) ;
371
372
const expose = definitionExposes . find ( ( e ) => e . property === key ) ;
372
373
373
- if ( expose ?. name in utils . calibrateAndPrecisionRoundOptionsDefaultPrecision && value !== '' && utils . isNumber ( value ) ) {
374
+ if ( expose ?. name && expose . name in utils . calibrateAndPrecisionRoundOptionsDefaultPrecision && value !== '' && utils . isNumber ( value ) ) {
374
375
try {
375
376
payload [ key ] = utils . calibrateAndPrecisionRoundOptions ( value , options , expose . name ) ;
376
377
} catch ( error ) {
377
- logger . logger . error ( `Failed to apply calibration to '${ expose . name } ': ${ error . message } ` , NS ) ;
378
+ logger . logger . error ( `Failed to apply calibration to '${ expose . name } ': ${ ( error as Error ) . message } ` , NS ) ;
378
379
}
379
380
}
380
381
}
@@ -388,13 +389,13 @@ export function removeExternalDefinitions(converterName?: string): void {
388
389
continue ;
389
390
}
390
391
391
- if ( 'zigbeeModel' in definition ) {
392
+ if ( 'zigbeeModel' in definition && definition . zigbeeModel ) {
392
393
for ( const zigbeeModel of definition . zigbeeModel ) {
393
394
removeFromLookup ( zigbeeModel , definition ) ;
394
395
}
395
396
}
396
397
397
- if ( 'fingerprint' in definition ) {
398
+ if ( 'fingerprint' in definition && definition . fingerprint ) {
398
399
for ( const fingerprint of definition . fingerprint ) {
399
400
removeFromLookup ( fingerprint . modelID , definition ) ;
400
401
}
@@ -416,13 +417,13 @@ export function addDefinition(definition: DefinitionWithExtend): void {
416
417
externalDefinitionsCount ++ ;
417
418
}
418
419
419
- if ( 'fingerprint' in definition ) {
420
+ if ( 'fingerprint' in definition && definition . fingerprint ) {
420
421
for ( const fingerprint of definition . fingerprint ) {
421
422
addToLookup ( fingerprint . modelID , definition ) ;
422
423
}
423
424
}
424
425
425
- if ( 'zigbeeModel' in definition ) {
426
+ if ( 'zigbeeModel' in definition && definition . zigbeeModel ) {
426
427
for ( const zigbeeModel of definition . zigbeeModel ) {
427
428
addToLookup ( zigbeeModel , definition ) ;
428
429
}
@@ -471,13 +472,16 @@ export async function findDefinition(device: Zh.Device, generateForUnknown: bool
471
472
return candidates [ 0 ] ;
472
473
} else {
473
474
// First try to match based on fingerprint, return the first matching one.
474
- const fingerprintMatch : { priority : number ; definition : Definition } = { priority : null , definition : null } ;
475
+ const fingerprintMatch : { priority ? : number ; definition ? : Definition } = { priority : undefined , definition : undefined } ;
475
476
476
477
for ( const candidate of candidates ) {
477
478
if ( candidate . fingerprint ) {
478
479
for ( const fingerprint of candidate . fingerprint ) {
479
480
const priority = fingerprint . priority ?? 0 ;
480
- if ( isFingerprintMatch ( fingerprint , device ) && ( ! fingerprintMatch . definition || priority > fingerprintMatch . priority ) ) {
481
+ if (
482
+ isFingerprintMatch ( fingerprint , device ) &&
483
+ ( fingerprintMatch . priority === undefined || priority > fingerprintMatch . priority )
484
+ ) {
481
485
fingerprintMatch . definition = candidate ;
482
486
fingerprintMatch . priority = priority ;
483
487
}
@@ -491,7 +495,7 @@ export async function findDefinition(device: Zh.Device, generateForUnknown: bool
491
495
492
496
// Match based on fingerprint failed, return first matching definition based on zigbeeModel
493
497
for ( const candidate of candidates ) {
494
- if ( candidate . zigbeeModel && candidate . zigbeeModel . includes ( device . modelID ) ) {
498
+ if ( candidate . zigbeeModel && device . modelID && candidate . zigbeeModel . includes ( device . modelID ) ) {
495
499
return candidate ;
496
500
}
497
501
}
@@ -517,7 +521,7 @@ function isFingerprintMatch(fingerprint: Fingerprint, device: Zh.Device): boolea
517
521
( ! fingerprint . softwareBuildID || device . softwareBuildID === fingerprint . softwareBuildID ) &&
518
522
( ! fingerprint . stackVersion || device . stackVersion === fingerprint . stackVersion ) &&
519
523
( ! fingerprint . zclVersion || device . zclVersion === fingerprint . zclVersion ) &&
520
- ( ! fingerprint . ieeeAddr || device . ieeeAddr . match ( fingerprint . ieeeAddr ) ) &&
524
+ ( ! fingerprint . ieeeAddr || device . ieeeAddr . match ( fingerprint . ieeeAddr ) !== null ) &&
521
525
( ! fingerprint . endpoints ||
522
526
arrayEquals (
523
527
device . endpoints . map ( ( e ) => e . ID ) ,
@@ -526,13 +530,15 @@ function isFingerprintMatch(fingerprint: Fingerprint, device: Zh.Device): boolea
526
530
527
531
if ( match && fingerprint . endpoints ) {
528
532
for ( const fingerprintEndpoint of fingerprint . endpoints ) {
529
- const deviceEndpoint = device . getEndpoint ( fingerprintEndpoint . ID ) ;
533
+ const deviceEndpoint = fingerprintEndpoint . ID !== undefined ? device . getEndpoint ( fingerprintEndpoint . ID ) : undefined ;
530
534
match =
531
535
match &&
532
- ( ! fingerprintEndpoint . deviceID || deviceEndpoint . deviceID === fingerprintEndpoint . deviceID ) &&
533
- ( ! fingerprintEndpoint . profileID || deviceEndpoint . profileID === fingerprintEndpoint . profileID ) &&
534
- ( ! fingerprintEndpoint . inputClusters || arrayEquals ( deviceEndpoint . inputClusters , fingerprintEndpoint . inputClusters ) ) &&
535
- ( ! fingerprintEndpoint . outputClusters || arrayEquals ( deviceEndpoint . outputClusters , fingerprintEndpoint . outputClusters ) ) ;
536
+ ( ! fingerprintEndpoint . deviceID || ( deviceEndpoint !== undefined && deviceEndpoint . deviceID === fingerprintEndpoint . deviceID ) ) &&
537
+ ( ! fingerprintEndpoint . profileID || ( deviceEndpoint !== undefined && deviceEndpoint . profileID === fingerprintEndpoint . profileID ) ) &&
538
+ ( ! fingerprintEndpoint . inputClusters ||
539
+ ( deviceEndpoint !== undefined && arrayEquals ( deviceEndpoint . inputClusters , fingerprintEndpoint . inputClusters ) ) ) &&
540
+ ( ! fingerprintEndpoint . outputClusters ||
541
+ ( deviceEndpoint !== undefined && arrayEquals ( deviceEndpoint . outputClusters , fingerprintEndpoint . outputClusters ) ) ) ;
536
542
}
537
543
}
538
544
0 commit comments