tsvesync 1.0.72 → 1.0.73

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.
@@ -314,6 +314,12 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
314
314
  return false;
315
315
  }
316
316
  }
317
+ // Special handling for Core200S auto mode
318
+ if (this.deviceType.includes('Core200S') && mode === 'auto') {
319
+ // Core200S doesn't support auto mode, so we'll set it to manual mode
320
+ logger_1.logger.warn(`Auto mode not supported for ${this.deviceType}, using manual mode instead`);
321
+ return this.setMode('manual');
322
+ }
317
323
  // Standard implementation for other devices
318
324
  const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
319
325
  ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
@@ -328,20 +334,29 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
328
334
  }
329
335
  }, helpers_1.Helpers.reqHeaderBypass());
330
336
  const success = this.checkResponse([response, status], 'setMode');
331
- if (!success) {
337
+ if (success) {
338
+ this.details.mode = mode;
339
+ return true;
340
+ }
341
+ else {
332
342
  logger_1.logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
343
+ return false;
333
344
  }
334
- return success;
335
345
  }
336
346
  /**
337
347
  * Set display status
338
348
  */
339
349
  async setDisplay(enabled) {
350
+ var _a;
340
351
  if (!this.hasFeature('display')) {
341
352
  const error = 'Display control not supported';
342
353
  logger_1.logger.error(`${error} for device: ${this.deviceName}`);
343
354
  throw new Error(error);
344
355
  }
356
+ // Check if device is in sleep mode - display control may not work in sleep mode
357
+ if (this.details.mode === 'sleep') {
358
+ logger_1.logger.warn(`Device ${this.deviceName} is in sleep mode, display control may not work`);
359
+ }
345
360
  logger_1.logger.debug(`Setting display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
346
361
  // Special handling for LV series
347
362
  if (this.deviceType.startsWith('LV-')) {
@@ -384,23 +399,34 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
384
399
  }
385
400
  }, helpers_1.Helpers.reqHeaderBypass());
386
401
  const success = this.checkResponse([response, status], 'setDisplay');
402
+ // Check for error code 11018000 (operation not supported in current mode)
403
+ if (((_a = response === null || response === void 0 ? void 0 : response.result) === null || _a === void 0 ? void 0 : _a.code) === 11018000) {
404
+ logger_1.logger.warn(`Display control not supported in current mode for device: ${this.deviceName}`);
405
+ return false;
406
+ }
387
407
  if (success) {
388
408
  this.details.screenStatus = enabled ? 'on' : 'off';
409
+ return true;
389
410
  }
390
411
  else {
391
412
  logger_1.logger.error(`Failed to set display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
413
+ return false;
392
414
  }
393
- return success;
394
415
  }
395
416
  /**
396
417
  * Set child lock
397
418
  */
398
419
  async setChildLock(enabled) {
420
+ var _a;
399
421
  if (!this.hasFeature('child_lock')) {
400
422
  const error = 'Child lock not supported';
401
423
  logger_1.logger.error(`${error} for device: ${this.deviceName}`);
402
424
  throw new Error(error);
403
425
  }
426
+ // Check if device is in sleep mode - child lock may not work in sleep mode
427
+ if (this.details.mode === 'sleep') {
428
+ logger_1.logger.warn(`Device ${this.deviceName} is in sleep mode, child lock control may not work`);
429
+ }
404
430
  logger_1.logger.debug(`Setting child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
405
431
  // Special handling for LV series
406
432
  if (this.deviceType.startsWith('LV-')) {
@@ -425,6 +451,11 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
425
451
  return true;
426
452
  }
427
453
  else {
454
+ // Check for error code 11000000 (feature not supported)
455
+ if ((response === null || response === void 0 ? void 0 : response.code) === 11000000) {
456
+ logger_1.logger.warn(`Child lock control not supported via API for device: ${this.deviceName}`);
457
+ return false;
458
+ }
428
459
  logger_1.logger.error(`Failed to set child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
429
460
  return false;
430
461
  }
@@ -443,18 +474,25 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
443
474
  }
444
475
  }, helpers_1.Helpers.reqHeaderBypass());
445
476
  const success = this.checkResponse([response, status], 'setChildLock');
477
+ // Check for error code 11000000 (feature not supported)
478
+ if ((response === null || response === void 0 ? void 0 : response.code) === 11000000 || (((_a = response === null || response === void 0 ? void 0 : response.result) === null || _a === void 0 ? void 0 : _a.code) === 11000000)) {
479
+ logger_1.logger.warn(`Child lock control not supported via API for device: ${this.deviceName}`);
480
+ return false;
481
+ }
446
482
  if (success) {
447
- this.details.child_lock = enabled;
483
+ this.details.childLock = enabled;
484
+ return true;
448
485
  }
449
486
  else {
450
487
  logger_1.logger.error(`Failed to set child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
488
+ return false;
451
489
  }
452
- return success;
453
490
  }
454
491
  /**
455
492
  * Set timer
456
493
  */
457
494
  async setTimer(hours) {
495
+ var _a, _b;
458
496
  if (!this.hasFeature('timer')) {
459
497
  const error = 'Timer not supported';
460
498
  logger_1.logger.error(`${error} for device: ${this.deviceName}`);
@@ -480,10 +518,14 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
480
518
  'tz': this.manager.timeZone
481
519
  });
482
520
  const success = this.checkResponse([response, status], 'setTimer');
483
- if (!success) {
521
+ if (success) {
522
+ this.timer = { duration: hours * 3600, action: 'off' };
523
+ return true;
524
+ }
525
+ else {
484
526
  logger_1.logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
527
+ return false;
485
528
  }
486
- return success;
487
529
  }
488
530
  // Standard implementation for other devices
489
531
  const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
@@ -500,20 +542,37 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
500
542
  }
501
543
  }, helpers_1.Helpers.reqHeaderBypass());
502
544
  const success = this.checkResponse([response, status], 'setTimer');
503
- if (!success) {
545
+ // Check for successful response with timer ID
546
+ if (success && ((_b = (_a = response === null || response === void 0 ? void 0 : response.result) === null || _a === void 0 ? void 0 : _a.result) === null || _b === void 0 ? void 0 : _b.id)) {
547
+ this.timer = { duration: hours * 3600, action: 'off' };
548
+ return true;
549
+ }
550
+ else if (success) {
551
+ // API call succeeded but no timer ID returned
552
+ logger_1.logger.warn(`Timer API call succeeded but no timer ID returned for device: ${this.deviceName}`);
553
+ this.timer = { duration: hours * 3600, action: 'off' };
554
+ return true;
555
+ }
556
+ else {
504
557
  logger_1.logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
558
+ return false;
505
559
  }
506
- return success;
507
560
  }
508
561
  /**
509
562
  * Clear timer
510
563
  */
511
564
  async clearTimer() {
565
+ var _a;
512
566
  if (!this.hasFeature('timer')) {
513
567
  const error = 'Timer not supported';
514
568
  logger_1.logger.error(`${error} for device: ${this.deviceName}`);
515
569
  throw new Error(error);
516
570
  }
571
+ // If no timer is set, return success
572
+ if (!this.timer) {
573
+ logger_1.logger.debug(`No timer to clear for device: ${this.deviceName}`);
574
+ return true;
575
+ }
517
576
  logger_1.logger.debug(`Clearing timer for device: ${this.deviceName}`);
518
577
  // Special handling for LV series
519
578
  if (this.deviceType.startsWith('LV-')) {
@@ -532,10 +591,14 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
532
591
  'tz': this.manager.timeZone
533
592
  });
534
593
  const success = this.checkResponse([response, status], 'clearTimer');
535
- if (!success) {
594
+ if (success) {
595
+ this.timer = null;
596
+ return true;
597
+ }
598
+ else {
536
599
  logger_1.logger.error(`Failed to clear timer for device: ${this.deviceName}`);
600
+ return false;
537
601
  }
538
- return success;
539
602
  }
540
603
  // Standard implementation for other devices
541
604
  const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
@@ -549,10 +612,20 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
549
612
  }
550
613
  }, helpers_1.Helpers.reqHeaderBypass());
551
614
  const success = this.checkResponse([response, status], 'clearTimer');
552
- if (!success) {
615
+ // Check for error code 11000000 (feature not supported or no timer to clear)
616
+ if ((response === null || response === void 0 ? void 0 : response.code) === 11000000 || (((_a = response === null || response === void 0 ? void 0 : response.result) === null || _a === void 0 ? void 0 : _a.code) === 11000000)) {
617
+ logger_1.logger.warn(`No timer to clear or timer control not supported via API for device: ${this.deviceName}`);
618
+ this.timer = null;
619
+ return true;
620
+ }
621
+ if (success) {
622
+ this.timer = null;
623
+ return true;
624
+ }
625
+ else {
553
626
  logger_1.logger.error(`Failed to clear timer for device: ${this.deviceName}`);
627
+ return false;
554
628
  }
555
- return success;
556
629
  }
557
630
  /**
558
631
  * Turn automatic stop on
@@ -44,6 +44,14 @@ export declare abstract class VeSyncFan extends VeSyncBaseDevice {
44
44
  * Check if feature is supported
45
45
  */
46
46
  hasFeature(feature: string): boolean;
47
+ /**
48
+ * Check if feature is supported in current mode
49
+ */
50
+ isFeatureSupportedInCurrentMode(feature: string): boolean;
51
+ /**
52
+ * Get maximum fan speed level
53
+ */
54
+ getMaxFanSpeed(): number;
47
55
  /**
48
56
  * Get current mode
49
57
  */
@@ -322,6 +322,40 @@ class VeSyncFan extends vesyncBaseDevice_1.VeSyncBaseDevice {
322
322
  hasFeature(feature) {
323
323
  return this.config.features.includes(feature);
324
324
  }
325
+ /**
326
+ * Check if feature is supported in current mode
327
+ */
328
+ isFeatureSupportedInCurrentMode(feature) {
329
+ // First check if the feature is supported at all
330
+ if (!this.hasFeature(feature)) {
331
+ return false;
332
+ }
333
+ // Check mode-specific restrictions
334
+ const currentMode = this.mode;
335
+ // Some features are not supported in sleep mode
336
+ if (currentMode === 'sleep') {
337
+ // Display and child lock are not supported in sleep mode
338
+ if (feature === 'display' || feature === 'child_lock') {
339
+ return false;
340
+ }
341
+ }
342
+ // Fan speed is only supported in manual mode for some devices
343
+ if (feature === 'fan_speed' && this.deviceType.startsWith('LV-')) {
344
+ return currentMode === 'manual';
345
+ }
346
+ // Auto mode is not supported on Core200S
347
+ if (feature === 'auto_mode' && this.deviceType.includes('Core200S')) {
348
+ return false;
349
+ }
350
+ // Feature is supported in current mode
351
+ return true;
352
+ }
353
+ /**
354
+ * Get maximum fan speed level
355
+ */
356
+ getMaxFanSpeed() {
357
+ return this.config.levels ? Math.max(...this.config.levels) : 3;
358
+ }
325
359
  /**
326
360
  * Get current mode
327
361
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsvesync",
3
- "version": "1.0.72",
3
+ "version": "1.0.73",
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",
@@ -388,6 +388,13 @@ export class VeSyncAirBypass extends VeSyncFan {
388
388
  }
389
389
  }
390
390
 
391
+ // Special handling for Core200S auto mode
392
+ if (this.deviceType.includes('Core200S') && mode === 'auto') {
393
+ // Core200S doesn't support auto mode, so we'll set it to manual mode
394
+ logger.warn(`Auto mode not supported for ${this.deviceType}, using manual mode instead`);
395
+ return this.setMode('manual');
396
+ }
397
+
391
398
  // Standard implementation for other devices
392
399
  const [response, status] = await this.callApi(
393
400
  '/cloud/v2/deviceManaged/bypassV2',
@@ -408,10 +415,13 @@ export class VeSyncAirBypass extends VeSyncFan {
408
415
  );
409
416
 
410
417
  const success = this.checkResponse([response, status], 'setMode');
411
- if (!success) {
418
+ if (success) {
419
+ this.details.mode = mode;
420
+ return true;
421
+ } else {
412
422
  logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
423
+ return false;
413
424
  }
414
- return success;
415
425
  }
416
426
 
417
427
  /**
@@ -424,6 +434,11 @@ export class VeSyncAirBypass extends VeSyncFan {
424
434
  throw new Error(error);
425
435
  }
426
436
 
437
+ // Check if device is in sleep mode - display control may not work in sleep mode
438
+ if (this.details.mode === 'sleep') {
439
+ logger.warn(`Device ${this.deviceName} is in sleep mode, display control may not work`);
440
+ }
441
+
427
442
  logger.debug(`Setting display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
428
443
 
429
444
  // Special handling for LV series
@@ -479,12 +494,20 @@ export class VeSyncAirBypass extends VeSyncFan {
479
494
  );
480
495
 
481
496
  const success = this.checkResponse([response, status], 'setDisplay');
497
+
498
+ // Check for error code 11018000 (operation not supported in current mode)
499
+ if (response?.result?.code === 11018000) {
500
+ logger.warn(`Display control not supported in current mode for device: ${this.deviceName}`);
501
+ return false;
502
+ }
503
+
482
504
  if (success) {
483
505
  this.details.screenStatus = enabled ? 'on' : 'off';
506
+ return true;
484
507
  } else {
485
508
  logger.error(`Failed to set display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
509
+ return false;
486
510
  }
487
- return success;
488
511
  }
489
512
 
490
513
  /**
@@ -497,6 +520,11 @@ export class VeSyncAirBypass extends VeSyncFan {
497
520
  throw new Error(error);
498
521
  }
499
522
 
523
+ // Check if device is in sleep mode - child lock may not work in sleep mode
524
+ if (this.details.mode === 'sleep') {
525
+ logger.warn(`Device ${this.deviceName} is in sleep mode, child lock control may not work`);
526
+ }
527
+
500
528
  logger.debug(`Setting child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
501
529
 
502
530
  // Special handling for LV series
@@ -527,6 +555,11 @@ export class VeSyncAirBypass extends VeSyncFan {
527
555
  this.details.childLock = enabled;
528
556
  return true;
529
557
  } else {
558
+ // Check for error code 11000000 (feature not supported)
559
+ if (response?.code === 11000000) {
560
+ logger.warn(`Child lock control not supported via API for device: ${this.deviceName}`);
561
+ return false;
562
+ }
530
563
  logger.error(`Failed to set child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
531
564
  return false;
532
565
  }
@@ -552,12 +585,20 @@ export class VeSyncAirBypass extends VeSyncFan {
552
585
  );
553
586
 
554
587
  const success = this.checkResponse([response, status], 'setChildLock');
588
+
589
+ // Check for error code 11000000 (feature not supported)
590
+ if (response?.code === 11000000 || (response?.result?.code === 11000000)) {
591
+ logger.warn(`Child lock control not supported via API for device: ${this.deviceName}`);
592
+ return false;
593
+ }
594
+
555
595
  if (success) {
556
- this.details.child_lock = enabled;
596
+ this.details.childLock = enabled;
597
+ return true;
557
598
  } else {
558
599
  logger.error(`Failed to set child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
600
+ return false;
559
601
  }
560
- return success;
561
602
  }
562
603
 
563
604
  /**
@@ -597,10 +638,13 @@ export class VeSyncAirBypass extends VeSyncFan {
597
638
  );
598
639
 
599
640
  const success = this.checkResponse([response, status], 'setTimer');
600
- if (!success) {
641
+ if (success) {
642
+ this.timer = { duration: hours * 3600, action: 'off' };
643
+ return true;
644
+ } else {
601
645
  logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
646
+ return false;
602
647
  }
603
- return success;
604
648
  }
605
649
 
606
650
  // Standard implementation for other devices
@@ -624,10 +668,20 @@ export class VeSyncAirBypass extends VeSyncFan {
624
668
  );
625
669
 
626
670
  const success = this.checkResponse([response, status], 'setTimer');
627
- if (!success) {
671
+
672
+ // Check for successful response with timer ID
673
+ if (success && response?.result?.result?.id) {
674
+ this.timer = { duration: hours * 3600, action: 'off' };
675
+ return true;
676
+ } else if (success) {
677
+ // API call succeeded but no timer ID returned
678
+ logger.warn(`Timer API call succeeded but no timer ID returned for device: ${this.deviceName}`);
679
+ this.timer = { duration: hours * 3600, action: 'off' };
680
+ return true;
681
+ } else {
628
682
  logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
683
+ return false;
629
684
  }
630
- return success;
631
685
  }
632
686
 
633
687
  /**
@@ -640,6 +694,12 @@ export class VeSyncAirBypass extends VeSyncFan {
640
694
  throw new Error(error);
641
695
  }
642
696
 
697
+ // If no timer is set, return success
698
+ if (!this.timer) {
699
+ logger.debug(`No timer to clear for device: ${this.deviceName}`);
700
+ return true;
701
+ }
702
+
643
703
  logger.debug(`Clearing timer for device: ${this.deviceName}`);
644
704
 
645
705
  // Special handling for LV series
@@ -665,10 +725,13 @@ export class VeSyncAirBypass extends VeSyncFan {
665
725
  );
666
726
 
667
727
  const success = this.checkResponse([response, status], 'clearTimer');
668
- if (!success) {
728
+ if (success) {
729
+ this.timer = null;
730
+ return true;
731
+ } else {
669
732
  logger.error(`Failed to clear timer for device: ${this.deviceName}`);
733
+ return false;
670
734
  }
671
- return success;
672
735
  }
673
736
 
674
737
  // Standard implementation for other devices
@@ -689,10 +752,21 @@ export class VeSyncAirBypass extends VeSyncFan {
689
752
  );
690
753
 
691
754
  const success = this.checkResponse([response, status], 'clearTimer');
692
- if (!success) {
755
+
756
+ // Check for error code 11000000 (feature not supported or no timer to clear)
757
+ if (response?.code === 11000000 || (response?.result?.code === 11000000)) {
758
+ logger.warn(`No timer to clear or timer control not supported via API for device: ${this.deviceName}`);
759
+ this.timer = null;
760
+ return true;
761
+ }
762
+
763
+ if (success) {
764
+ this.timer = null;
765
+ return true;
766
+ } else {
693
767
  logger.error(`Failed to clear timer for device: ${this.deviceName}`);
768
+ return false;
694
769
  }
695
- return success;
696
770
  }
697
771
 
698
772
  /**