tsvesync 1.0.45 → 1.0.47

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.
@@ -3,6 +3,16 @@
3
3
  */
4
4
  import { VeSyncBaseDevice } from './vesyncBaseDevice';
5
5
  import { Logger } from './logger';
6
+ /**
7
+ * Device exclusion configuration
8
+ */
9
+ export interface ExcludeConfig {
10
+ type?: string[];
11
+ model?: string[];
12
+ name?: string[];
13
+ namePattern?: string[];
14
+ id?: string[];
15
+ }
6
16
  /**
7
17
  * VeSync Manager Class
8
18
  */
@@ -14,6 +24,7 @@ export declare class VeSync {
14
24
  private _devList;
15
25
  private _lastUpdateTs;
16
26
  private _inProcess;
27
+ private _excludeConfig;
17
28
  username: string;
18
29
  password: string;
19
30
  token: string | null;
@@ -37,8 +48,9 @@ export declare class VeSync {
37
48
  * @param redact - Optional redact mode flag
38
49
  * @param apiUrl - Optional API base URL override
39
50
  * @param customLogger - Optional custom logger implementation
51
+ * @param excludeConfig - Optional device exclusion configuration
40
52
  */
41
- constructor(username: string, password: string, timeZone?: string, debug?: boolean, redact?: boolean, apiUrl?: string, customLogger?: Logger);
53
+ constructor(username: string, password: string, timeZone?: string, debug?: boolean, redact?: boolean, apiUrl?: string, customLogger?: Logger, excludeConfig?: ExcludeConfig);
42
54
  /**
43
55
  * Get/Set debug mode
44
56
  */
@@ -70,6 +82,10 @@ export declare class VeSync {
70
82
  * Correct devices without cid or uuid
71
83
  */
72
84
  static setDevId(devices: any[]): any[];
85
+ /**
86
+ * Check if a device should be excluded based on configuration
87
+ */
88
+ private shouldExcludeDevice;
73
89
  /**
74
90
  * Process devices from API response
75
91
  */
@@ -129,14 +129,16 @@ class VeSync {
129
129
  * @param redact - Optional redact mode flag
130
130
  * @param apiUrl - Optional API base URL override
131
131
  * @param customLogger - Optional custom logger implementation
132
+ * @param excludeConfig - Optional device exclusion configuration
132
133
  */
133
- constructor(username, password, timeZone = helpers_1.DEFAULT_TZ, debug = false, redact = true, apiUrl, customLogger) {
134
+ constructor(username, password, timeZone = helpers_1.DEFAULT_TZ, debug = false, redact = true, apiUrl, customLogger, excludeConfig) {
134
135
  this._debug = debug;
135
136
  this._redact = redact;
136
137
  this._energyUpdateInterval = DEFAULT_ENERGY_UPDATE_INTERVAL;
137
138
  this._energyCheck = true;
138
139
  this._lastUpdateTs = null;
139
140
  this._inProcess = false;
141
+ this._excludeConfig = excludeConfig || null;
140
142
  this.username = username;
141
143
  this.password = password;
142
144
  this.token = null;
@@ -283,6 +285,52 @@ class VeSync {
283
285
  }
284
286
  return devices;
285
287
  }
288
+ /**
289
+ * Check if a device should be excluded based on configuration
290
+ */
291
+ shouldExcludeDevice(device) {
292
+ var _a, _b, _c, _d, _e;
293
+ if (!this._excludeConfig) {
294
+ return false;
295
+ }
296
+ const exclude = this._excludeConfig;
297
+ // Check device type
298
+ if ((_a = exclude.type) === null || _a === void 0 ? void 0 : _a.includes(device.deviceType.toLowerCase())) {
299
+ logger_1.logger.debug(`Excluding device ${device.deviceName} by type: ${device.deviceType}`);
300
+ return true;
301
+ }
302
+ // Check device model
303
+ if ((_b = exclude.model) === null || _b === void 0 ? void 0 : _b.some(model => device.deviceType.toUpperCase().includes(model.toUpperCase()))) {
304
+ logger_1.logger.debug(`Excluding device ${device.deviceName} by model: ${device.deviceType}`);
305
+ return true;
306
+ }
307
+ // Check exact name match
308
+ if ((_c = exclude.name) === null || _c === void 0 ? void 0 : _c.includes(device.deviceName.trim())) {
309
+ logger_1.logger.debug(`Excluding device ${device.deviceName} by exact name match`);
310
+ return true;
311
+ }
312
+ // Check name patterns
313
+ if (exclude.namePattern) {
314
+ for (const pattern of exclude.namePattern) {
315
+ try {
316
+ const regex = new RegExp(pattern);
317
+ if (regex.test(device.deviceName.trim())) {
318
+ logger_1.logger.debug(`Excluding device ${device.deviceName} by name pattern: ${pattern}`);
319
+ return true;
320
+ }
321
+ }
322
+ catch (error) {
323
+ logger_1.logger.warn(`Invalid regex pattern in exclude config: ${pattern}`);
324
+ }
325
+ }
326
+ }
327
+ // Check device ID (cid or uuid)
328
+ if (((_d = exclude.id) === null || _d === void 0 ? void 0 : _d.includes(device.cid)) || ((_e = exclude.id) === null || _e === void 0 ? void 0 : _e.includes(device.uuid))) {
329
+ logger_1.logger.debug(`Excluding device ${device.deviceName} by ID: ${device.cid}/${device.uuid}`);
330
+ return true;
331
+ }
332
+ return false;
333
+ }
286
334
  /**
287
335
  * Process devices from API response
288
336
  */
@@ -298,6 +346,10 @@ class VeSync {
298
346
  }
299
347
  // Process each device
300
348
  deviceList.forEach(dev => {
349
+ // Check if device should be excluded
350
+ if (this.shouldExcludeDevice(dev)) {
351
+ return;
352
+ }
301
353
  const [category, device] = objectFactory(dev, this);
302
354
  // Handle outdoor plug sub-devices
303
355
  if (dev.deviceType === 'ESO15-TB' && dev.subDeviceNo) {
@@ -308,9 +360,12 @@ class VeSync {
308
360
  subDeviceNo: dev.subDeviceNo,
309
361
  isSubDevice: true,
310
362
  };
311
- const [subCategory, subDevice] = objectFactory(subDeviceDetails, this);
312
- if (subDevice && subCategory in this._devList) {
313
- this._devList[subCategory].push(subDevice);
363
+ // Check if sub-device should be excluded
364
+ if (!this.shouldExcludeDevice(subDeviceDetails)) {
365
+ const [subCategory, subDevice] = objectFactory(subDeviceDetails, this);
366
+ if (subDevice && subCategory in this._devList) {
367
+ this._devList[subCategory].push(subDevice);
368
+ }
314
369
  }
315
370
  }
316
371
  else if (device && category in this._devList) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsvesync",
3
- "version": "1.0.45",
3
+ "version": "1.0.47",
4
4
  "description": "A TypeScript library for interacting with VeSync smart home devices",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/lib/vesync.ts CHANGED
@@ -23,6 +23,17 @@ interface DeviceModules {
23
23
  // Device categories
24
24
  type DeviceCategory = 'fans' | 'outlets' | 'switches' | 'bulbs';
25
25
 
26
+ /**
27
+ * Device exclusion configuration
28
+ */
29
+ export interface ExcludeConfig {
30
+ type?: string[];
31
+ model?: string[];
32
+ name?: string[];
33
+ namePattern?: string[];
34
+ id?: string[];
35
+ }
36
+
26
37
  /**
27
38
  * Create device instance based on type
28
39
  */
@@ -147,6 +158,7 @@ export class VeSync {
147
158
  private _devList: Record<string, VeSyncBaseDevice[]>;
148
159
  private _lastUpdateTs: number | null;
149
160
  private _inProcess: boolean;
161
+ private _excludeConfig: ExcludeConfig | null;
150
162
 
151
163
  username: string;
152
164
  password: string;
@@ -173,6 +185,7 @@ export class VeSync {
173
185
  * @param redact - Optional redact mode flag
174
186
  * @param apiUrl - Optional API base URL override
175
187
  * @param customLogger - Optional custom logger implementation
188
+ * @param excludeConfig - Optional device exclusion configuration
176
189
  */
177
190
  constructor(
178
191
  username: string,
@@ -181,7 +194,8 @@ export class VeSync {
181
194
  debug = false,
182
195
  redact = true,
183
196
  apiUrl?: string,
184
- customLogger?: Logger
197
+ customLogger?: Logger,
198
+ excludeConfig?: ExcludeConfig
185
199
  ) {
186
200
  this._debug = debug;
187
201
  this._redact = redact;
@@ -189,6 +203,7 @@ export class VeSync {
189
203
  this._energyCheck = true;
190
204
  this._lastUpdateTs = null;
191
205
  this._inProcess = false;
206
+ this._excludeConfig = excludeConfig || null;
192
207
 
193
208
  this.username = username;
194
209
  this.password = password;
@@ -351,6 +366,58 @@ export class VeSync {
351
366
  return devices;
352
367
  }
353
368
 
369
+ /**
370
+ * Check if a device should be excluded based on configuration
371
+ */
372
+ private shouldExcludeDevice(device: Record<string, any>): boolean {
373
+ if (!this._excludeConfig) {
374
+ return false;
375
+ }
376
+
377
+ const exclude = this._excludeConfig;
378
+
379
+ // Check device type
380
+ if (exclude.type?.includes(device.deviceType.toLowerCase())) {
381
+ logger.debug(`Excluding device ${device.deviceName} by type: ${device.deviceType}`);
382
+ return true;
383
+ }
384
+
385
+ // Check device model
386
+ if (exclude.model?.some(model => device.deviceType.toUpperCase().includes(model.toUpperCase()))) {
387
+ logger.debug(`Excluding device ${device.deviceName} by model: ${device.deviceType}`);
388
+ return true;
389
+ }
390
+
391
+ // Check exact name match
392
+ if (exclude.name?.includes(device.deviceName.trim())) {
393
+ logger.debug(`Excluding device ${device.deviceName} by exact name match`);
394
+ return true;
395
+ }
396
+
397
+ // Check name patterns
398
+ if (exclude.namePattern) {
399
+ for (const pattern of exclude.namePattern) {
400
+ try {
401
+ const regex = new RegExp(pattern);
402
+ if (regex.test(device.deviceName.trim())) {
403
+ logger.debug(`Excluding device ${device.deviceName} by name pattern: ${pattern}`);
404
+ return true;
405
+ }
406
+ } catch (error) {
407
+ logger.warn(`Invalid regex pattern in exclude config: ${pattern}`);
408
+ }
409
+ }
410
+ }
411
+
412
+ // Check device ID (cid or uuid)
413
+ if (exclude.id?.includes(device.cid) || exclude.id?.includes(device.uuid)) {
414
+ logger.debug(`Excluding device ${device.deviceName} by ID: ${device.cid}/${device.uuid}`);
415
+ return true;
416
+ }
417
+
418
+ return false;
419
+ }
420
+
354
421
  /**
355
422
  * Process devices from API response
356
423
  */
@@ -368,6 +435,11 @@ export class VeSync {
368
435
 
369
436
  // Process each device
370
437
  deviceList.forEach(dev => {
438
+ // Check if device should be excluded
439
+ if (this.shouldExcludeDevice(dev)) {
440
+ return;
441
+ }
442
+
371
443
  const [category, device] = objectFactory(dev, this);
372
444
  // Handle outdoor plug sub-devices
373
445
  if (dev.deviceType === 'ESO15-TB' && dev.subDeviceNo) {
@@ -378,9 +450,12 @@ export class VeSync {
378
450
  subDeviceNo: dev.subDeviceNo,
379
451
  isSubDevice: true,
380
452
  };
381
- const [subCategory, subDevice] = objectFactory(subDeviceDetails, this);
382
- if (subDevice && subCategory in this._devList) {
383
- this._devList[subCategory].push(subDevice);
453
+ // Check if sub-device should be excluded
454
+ if (!this.shouldExcludeDevice(subDeviceDetails)) {
455
+ const [subCategory, subDevice] = objectFactory(subDeviceDetails, this);
456
+ if (subDevice && subCategory in this._devList) {
457
+ this._devList[subCategory].push(subDevice);
458
+ }
384
459
  }
385
460
  } else if (device && category in this._devList) {
386
461
  this._devList[category].push(device);