@switchbot/homebridge-switchbot 3.6.1-beta.3 → 3.6.1-beta.5

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.
Files changed (41) hide show
  1. package/dist/device/ceilinglight.d.ts +3 -2
  2. package/dist/device/ceilinglight.d.ts.map +1 -1
  3. package/dist/device/ceilinglight.js +21 -13
  4. package/dist/device/ceilinglight.js.map +1 -1
  5. package/dist/device/colorbulb.d.ts +3 -2
  6. package/dist/device/colorbulb.d.ts.map +1 -1
  7. package/dist/device/colorbulb.js +20 -19
  8. package/dist/device/colorbulb.js.map +1 -1
  9. package/dist/device/device.d.ts +9 -0
  10. package/dist/device/device.d.ts.map +1 -1
  11. package/dist/device/device.js +29 -2
  12. package/dist/device/device.js.map +1 -1
  13. package/dist/device/hub.d.ts.map +1 -1
  14. package/dist/device/hub.js +2 -2
  15. package/dist/device/hub.js.map +1 -1
  16. package/dist/device/iosensor.d.ts.map +1 -1
  17. package/dist/device/iosensor.js +2 -2
  18. package/dist/device/iosensor.js.map +1 -1
  19. package/dist/device/lightstrip.d.ts +4 -3
  20. package/dist/device/lightstrip.d.ts.map +1 -1
  21. package/dist/device/lightstrip.js +22 -15
  22. package/dist/device/lightstrip.js.map +1 -1
  23. package/dist/device/meter.d.ts.map +1 -1
  24. package/dist/device/meter.js +2 -2
  25. package/dist/device/meter.js.map +1 -1
  26. package/dist/device/meterplus.js +2 -2
  27. package/dist/device/meterplus.js.map +1 -1
  28. package/dist/utils.d.ts +8 -2
  29. package/dist/utils.d.ts.map +1 -1
  30. package/dist/utils.js +13 -7
  31. package/dist/utils.js.map +1 -1
  32. package/package.json +1 -1
  33. package/src/device/ceilinglight.ts +21 -14
  34. package/src/device/colorbulb.ts +20 -21
  35. package/src/device/device.ts +35 -2
  36. package/src/device/hub.ts +2 -2
  37. package/src/device/iosensor.ts +2 -2
  38. package/src/device/lightstrip.ts +24 -17
  39. package/src/device/meter.ts +2 -2
  40. package/src/device/meterplus.ts +2 -2
  41. package/src/utils.ts +13 -9
@@ -42,8 +42,9 @@ export class CeilingLight extends deviceBase {
42
42
  serviceData!: ceilingLightServiceData | ceilingLightProServiceData;
43
43
 
44
44
  // Adaptive Lighting
45
+ adaptiveLighting!: boolean;
46
+ adaptiveLightingShift!: number;
45
47
  AdaptiveLightingController?: ControllerConstructor | Controller<ControllerServiceMap>;
46
- adaptiveLightingShift?: number;
47
48
 
48
49
  // Updates
49
50
  ceilingLightUpdateInProgress!: boolean;
@@ -59,7 +60,7 @@ export class CeilingLight extends deviceBase {
59
60
  accessory.category = this.hap.Categories.LIGHTBULB;
60
61
 
61
62
  // default placeholders
62
- this.adaptiveLighting(device);
63
+ this.getAdaptiveLightingSettings(accessory, device);
63
64
 
64
65
  // this is subject we use to track when we need to POST changes to the SwitchBot API
65
66
  this.doCeilingLightUpdate = new Subject();
@@ -78,23 +79,24 @@ export class CeilingLight extends deviceBase {
78
79
  };
79
80
  accessory.context.LightBulb = this.LightBulb as object;
80
81
 
81
- // Adaptive Lighting
82
- if (this.adaptiveLightingShift === -1 && accessory.context.adaptiveLighting) {
82
+ if (this.adaptiveLighting && this.adaptiveLightingShift === -1 && this.LightBulb) {
83
83
  accessory.removeService(this.LightBulb.Service);
84
84
  this.LightBulb.Service = accessory.addService(this.hap.Service.Lightbulb);
85
85
  accessory.context.adaptiveLighting = false;
86
- this.debugLog(`adaptiveLighting: ${accessory.context.adaptiveLighting}`);
87
- }
88
- if (this.adaptiveLightingShift !== -1) {
86
+ this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}`);
87
+ } else if (this.adaptiveLighting && this.adaptiveLightingShift >= 0 && this.LightBulb) {
89
88
  this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.LightBulb.Service, {
89
+ controllerMode: this.hap.AdaptiveLightingControllerMode.AUTOMATIC,
90
90
  customTemperatureAdjustment: this.adaptiveLightingShift,
91
91
  });
92
- this.accessory.configureController(this.AdaptiveLightingController);
93
- this.accessory.context.adaptiveLighting = true;
94
- this.debugLog(`adaptiveLighting: ${this.accessory.context.adaptiveLighting},`
95
- + ` adaptiveLightingShift: ${this.adaptiveLightingShift}`);
92
+ accessory.configureController(this.AdaptiveLightingController);
93
+ accessory.context.adaptiveLighting = true;
94
+ this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}, adaptiveLightingShift: ${this.adaptiveLightingShift}`,
95
+ );
96
+ } else {
97
+ accessory.context.adaptiveLighting = false;
98
+ this.debugLog(`adaptiveLighting: ${accessory.context.adaptiveLighting}`);
96
99
  }
97
- this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
98
100
 
99
101
  // Initialize LightBulb Characteristics
100
102
  this.LightBulb.Service
@@ -700,13 +702,18 @@ export class CeilingLight extends deviceBase {
700
702
  this.LightBulb.Saturation, 'Saturation');
701
703
  }
702
704
 
703
- async adaptiveLighting(device: device & devicesConfig): Promise<void> {
705
+ async getAdaptiveLightingSettings(accessory: PlatformAccessory, device: device & devicesConfig): Promise<void> {
706
+ // Adaptive Lighting
707
+ this.adaptiveLighting = accessory.context.adaptiveLighting ?? true;
708
+ await this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}`);
709
+ // Adaptive Lighting Shift
704
710
  if (device.ceilinglight?.adaptiveLightingShift) {
705
711
  this.adaptiveLightingShift = device.ceilinglight.adaptiveLightingShift;
712
+ this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
706
713
  } else {
707
714
  this.adaptiveLightingShift = 0;
715
+ this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
708
716
  }
709
- await this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
710
717
  }
711
718
 
712
719
  async BLEPushConnection() {
@@ -3,7 +3,7 @@
3
3
  * blindtilt.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import { deviceBase } from './device.js';
6
- import { hs2rgb, rgb2hs, m2hs, checkName } from '../utils.js';
6
+ import { hs2rgb, rgb2hs, m2hs } from '../utils.js';
7
7
  import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot';
8
8
  import { Subject, debounceTime, interval, skipWhile, take, tap } from 'rxjs';
9
9
 
@@ -42,8 +42,9 @@ export class ColorBulb extends deviceBase {
42
42
  serviceData!: colorBulbServiceData;
43
43
 
44
44
  // Adaptive Lighting
45
+ adaptiveLighting!: boolean;
46
+ adaptiveLightingShift!: number;
45
47
  AdaptiveLightingController?: ControllerConstructor | Controller<ControllerServiceMap>;
46
- adaptiveLightingShift?: number;
47
48
 
48
49
  // Updates
49
50
  colorBulbUpdateInProgress!: boolean;
@@ -59,13 +60,12 @@ export class ColorBulb extends deviceBase {
59
60
  accessory.category = this.hap.Categories.LIGHTBULB;
60
61
 
61
62
  // default placeholders
62
- this.adaptiveLighting(device);
63
+ this.getAdaptiveLightingSettings(accessory, device);
63
64
 
64
65
  // this is subject we use to track when we need to POST changes to the SwitchBot API
65
66
  this.doColorBulbUpdate = new Subject();
66
67
  this.colorBulbUpdateInProgress = false;
67
68
 
68
-
69
69
  // Initialize LightBulb property
70
70
  accessory.context.LightBulb = accessory.context.LightBulb ?? {};
71
71
  this.LightBulb = {
@@ -79,30 +79,24 @@ export class ColorBulb extends deviceBase {
79
79
  };
80
80
  accessory.context.LightBulb = this.LightBulb as object;
81
81
 
82
- const check = checkName(accessory.context.LightBulb.Name, 'Name', accessory.context.LightBulb.Name);
83
- if (check !== 'false') {
84
- accessory.context.LightBulb.Name = device.deviceName ?? accessory.displayName;
85
- } else {
86
- this.warnLog(check);
87
- }
88
-
89
- // Adaptive Lighting
90
- if (this.adaptiveLightingShift === -1 && accessory.context.adaptiveLighting) {
82
+ if (this.adaptiveLighting && this.adaptiveLightingShift === -1 && this.LightBulb) {
91
83
  accessory.removeService(this.LightBulb.Service);
92
84
  this.LightBulb.Service = accessory.addService(this.hap.Service.Lightbulb);
93
85
  accessory.context.adaptiveLighting = false;
94
- this.debugLog(`adaptiveLighting: ${accessory.context.adaptiveLighting}`);
95
- }
96
- if (this.adaptiveLightingShift !== -1) {
86
+ this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}`);
87
+ } else if (this.adaptiveLighting && this.adaptiveLightingShift >= 0 && this.LightBulb) {
97
88
  this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.LightBulb.Service, {
89
+ controllerMode: this.hap.AdaptiveLightingControllerMode.AUTOMATIC,
98
90
  customTemperatureAdjustment: this.adaptiveLightingShift,
99
91
  });
100
92
  accessory.configureController(this.AdaptiveLightingController);
101
93
  accessory.context.adaptiveLighting = true;
102
- this.debugLog(`adaptiveLighting: ${accessory.context.adaptiveLighting},`
103
- + ` adaptiveLightingShift: ${this.adaptiveLightingShift}`);
94
+ this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}, adaptiveLightingShift: ${this.adaptiveLightingShift}`,
95
+ );
96
+ } else {
97
+ accessory.context.adaptiveLighting = false;
98
+ this.debugLog(`adaptiveLighting: ${accessory.context.adaptiveLighting}`);
104
99
  }
105
- this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
106
100
 
107
101
  // Initialize LightBulb Characteristics
108
102
  this.LightBulb.Service
@@ -841,13 +835,18 @@ export class ColorBulb extends deviceBase {
841
835
  this.LightBulb.Saturation, 'Saturation');
842
836
  }
843
837
 
844
- async adaptiveLighting(device: device & devicesConfig): Promise<void> {
838
+ async getAdaptiveLightingSettings(accessory: PlatformAccessory, device: device & devicesConfig): Promise<void> {
839
+ // Adaptive Lighting
840
+ this.adaptiveLighting = accessory.context.adaptiveLighting ?? true;
841
+ await this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}`);
842
+ // Adaptive Lighting Shift
845
843
  if (device.colorbulb?.adaptiveLightingShift) {
846
844
  this.adaptiveLightingShift = device.colorbulb.adaptiveLightingShift;
845
+ this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
847
846
  } else {
848
847
  this.adaptiveLightingShift = 0;
848
+ this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
849
849
  }
850
- await this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
851
850
  }
852
851
 
853
852
  async BLEPushConnection() {
@@ -79,13 +79,20 @@ export abstract class deviceBase {
79
79
  .getService(this.hap.Service.AccessoryInformation)!
80
80
  .setCharacteristic(this.hap.Characteristic.Manufacturer, 'SwitchBot')
81
81
  .setCharacteristic(this.hap.Characteristic.AppMatchingIdentifier, 'id1087374760')
82
- .setCharacteristic(this.hap.Characteristic.Name, device.configDeviceName ?? device.deviceName ?? accessory.displayName)
83
- .setCharacteristic(this.hap.Characteristic.ConfiguredName, device.configDeviceName ?? device.deviceName ?? accessory.displayName)
82
+ .setCharacteristic(this.hap.Characteristic.Name, this.validName(accessory, device))
83
+ .setCharacteristic(this.hap.Characteristic.ConfiguredName, this.validName(accessory, device))
84
84
  .setCharacteristic(this.hap.Characteristic.Model, device.model ?? accessory.context.model)
85
85
  .setCharacteristic(this.hap.Characteristic.ProductData, device.deviceId ?? accessory.context.deviceId)
86
86
  .setCharacteristic(this.hap.Characteristic.SerialNumber, device.deviceId);
87
87
  }
88
88
 
89
+ public validName(accessory: PlatformAccessory, device: device & devicesConfig) {
90
+ const Name = device.configDeviceName ?? device.deviceName ?? accessory.displayName;
91
+ const NameOfName = device.configDeviceName ? 'configDeviceName' : device.deviceName ? 'deviceName' : 'displayName';
92
+ const validName = this.validateAndCleanString(Name, NameOfName, Name);
93
+ return validName;
94
+ }
95
+
89
96
  async getDeviceLogSettings(accessory: PlatformAccessory, device: device & devicesConfig): Promise<void> {
90
97
  this.deviceLogging = this.platform.debugMode ? 'debugMode' : device.logging ?? this.config.logging ?? 'standard';
91
98
  const logging = this.platform.debugMode ? 'Debug Mode' : device.logging ? 'Device Config' : this.config.logging ? 'Platform Config' : 'Default';
@@ -765,6 +772,32 @@ export abstract class deviceBase {
765
772
  }
766
773
  }
767
774
 
775
+ /**
776
+ * Validate and clean a string value for a Name Characteristic.
777
+ * @param displayName
778
+ * @param name
779
+ * @param value
780
+ * @returns string value
781
+ */
782
+ validateAndCleanString(displayName: string, name: string, value: string): string {
783
+ const validPattern = /^[a-zA-Z0-9][a-zA-Z0-9 ']*[a-zA-Z0-9]$/;
784
+ const invalidCharsPattern = /[^a-zA-Z0-9 ']/g;
785
+
786
+ if (!validPattern.test(value)) {
787
+ this.warnLog(`WARNING: The accessory '${displayName}' has an invalid '${name}' characteristic ('${value}'). Please use only alphanumeric,`
788
+ + ' space, and apostrophe characters. Ensure it starts and ends with an alphabetic or numeric character, and avoid emojis. This may'
789
+ + ' prevent the accessory from being added in the Home App or cause unresponsiveness.');
790
+
791
+ // Remove invalid characters
792
+ value = value.replace(invalidCharsPattern, '');
793
+
794
+ // Ensure it starts and ends with an alphanumeric character
795
+ value = value.replace(/^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$/g, '');
796
+ }
797
+
798
+ return value;
799
+ }
800
+
768
801
  /**
769
802
  * Logging for Device
770
803
  */
package/src/device/hub.ts CHANGED
@@ -4,8 +4,8 @@
4
4
  */
5
5
  import { Units } from 'homebridge';
6
6
  import { deviceBase } from './device.js';
7
- import { convertUnits } from '../utils.js';
8
7
  import { Subject, interval, skipWhile} from 'rxjs';
8
+ import { validHumidity, convertUnits } from '../utils.js';
9
9
  import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot';
10
10
 
11
11
  import type { devicesConfig } from '../settings.js';
@@ -181,7 +181,7 @@ export class Hub extends deviceBase {
181
181
 
182
182
  // CurrentRelativeHumidity
183
183
  if (!this.device.hub?.hide_humidity && this.HumiditySensor?.Service) {
184
- this.HumiditySensor!.CurrentRelativeHumidity = this.serviceData.humidity;
184
+ this.HumiditySensor!.CurrentRelativeHumidity = validHumidity(this.serviceData.humidity, 0, 100);
185
185
  await this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`);
186
186
  }
187
187
 
@@ -4,8 +4,8 @@
4
4
  */
5
5
  import { Units } from 'homebridge';
6
6
  import { deviceBase } from './device.js';
7
- import { convertUnits } from '../utils.js';
8
7
  import { Subject, interval, skipWhile } from 'rxjs';
8
+ import { convertUnits, validHumidity } from '../utils.js';
9
9
  import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot';
10
10
 
11
11
  import type { devicesConfig } from '../settings.js';
@@ -187,7 +187,7 @@ export class IOSensor extends deviceBase {
187
187
 
188
188
  // CurrentRelativeHumidity
189
189
  if (!this.device.iosensor?.hide_humidity && this.HumiditySensor?.Service) {
190
- this.HumiditySensor.CurrentRelativeHumidity = this.serviceData.humidity;
190
+ this.HumiditySensor.CurrentRelativeHumidity = validHumidity(this.serviceData.humidity, 0, 100);
191
191
  await this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`);
192
192
  }
193
193
 
@@ -10,8 +10,8 @@ import { Subject, debounceTime, interval, skipWhile, take, tap } from 'rxjs';
10
10
  import type { devicesConfig } from '../settings.js';
11
11
  import type { device } from '../types/devicelist.js';
12
12
  import type { SwitchBotPlatform } from '../platform.js';
13
- import type { stripLightServiceData } from '../types/bledevicestatus.js';
14
13
  import type { stripLightStatus } from '../types/devicestatus.js';
14
+ import type { stripLightServiceData } from '../types/bledevicestatus.js';
15
15
  import type { stripLightWebhookContext } from '../types/devicewebhookstatus.js';
16
16
  import type { Service, PlatformAccessory, CharacteristicValue, ControllerConstructor, Controller, ControllerServiceMap } from 'homebridge';
17
17
 
@@ -42,8 +42,9 @@ export class StripLight extends deviceBase {
42
42
  serviceData!: stripLightServiceData;
43
43
 
44
44
  // Adaptive Lighting
45
+ adaptiveLighting!: boolean;
46
+ adaptiveLightingShift!: number;
45
47
  AdaptiveLightingController?: ControllerConstructor | Controller<ControllerServiceMap>;
46
- adaptiveLightingShift?: number;
47
48
 
48
49
  // Updates
49
50
  stripLightUpdateInProgress!: boolean;
@@ -59,7 +60,8 @@ export class StripLight extends deviceBase {
59
60
  accessory.category = this.hap.Categories.LIGHTBULB;
60
61
 
61
62
  // Adaptive Lighting
62
- this.adaptiveLighting(device);
63
+ this.getAdaptiveLightingSettings(accessory, device);
64
+
63
65
  // this is subject we use to track when we need to POST changes to the SwitchBot API
64
66
  this.doStripLightUpdate = new Subject();
65
67
  this.stripLightUpdateInProgress = false;
@@ -77,23 +79,24 @@ export class StripLight extends deviceBase {
77
79
  };
78
80
  accessory.context.LightBulb = this.LightBulb as object;
79
81
 
80
- // Adaptive Lighting
81
- if (this.adaptiveLightingShift === -1 && this.accessory.context.adaptiveLighting) {
82
- this.accessory.removeService(this.LightBulb.Service);
83
- this.LightBulb.Service = this.accessory.addService(this.hap.Service.Lightbulb);
84
- this.accessory.context.adaptiveLighting = false;
85
- this.debugLog(`adaptiveLighting: ${this.accessory.context.adaptiveLighting}`);
86
- }
87
- if (this.adaptiveLightingShift !== -1) {
82
+ if (this.adaptiveLighting && this.adaptiveLightingShift === -1 && this.LightBulb) {
83
+ accessory.removeService(this.LightBulb.Service);
84
+ this.LightBulb.Service = accessory.addService(this.hap.Service.Lightbulb);
85
+ accessory.context.adaptiveLighting = false;
86
+ this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}`);
87
+ } else if (this.adaptiveLighting && this.adaptiveLightingShift >= 0 && this.LightBulb) {
88
88
  this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.LightBulb.Service, {
89
+ controllerMode: this.hap.AdaptiveLightingControllerMode.AUTOMATIC,
89
90
  customTemperatureAdjustment: this.adaptiveLightingShift,
90
91
  });
91
- this.accessory.configureController(this.AdaptiveLightingController);
92
- this.accessory.context.adaptiveLighting = true;
93
- this.debugLog(`adaptiveLighting: ${this.accessory.context.adaptiveLighting},`
94
- + ` adaptiveLightingShift: ${this.adaptiveLightingShift}`);
92
+ accessory.configureController(this.AdaptiveLightingController);
93
+ accessory.context.adaptiveLighting = true;
94
+ this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}, adaptiveLightingShift: ${this.adaptiveLightingShift}`,
95
+ );
96
+ } else {
97
+ accessory.context.adaptiveLighting = false;
98
+ this.debugLog(`adaptiveLighting: ${accessory.context.adaptiveLighting}`);
95
99
  }
96
- this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
97
100
 
98
101
  // Initialize LightBulb Characteristics
99
102
  this.LightBulb.Service
@@ -773,7 +776,11 @@ export class StripLight extends deviceBase {
773
776
  this.LightBulb.Saturation, 'Saturation');
774
777
  }
775
778
 
776
- async adaptiveLighting(device: device & devicesConfig): Promise<void> {
779
+ async getAdaptiveLightingSettings(accessory: PlatformAccessory, device: device & devicesConfig): Promise<void> {
780
+ // Adaptive Lighting
781
+ this.adaptiveLighting = accessory.context.adaptiveLighting ?? true;
782
+ await this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}`);
783
+ // Adaptive Lighting Shift
777
784
  if (device.striplight?.adaptiveLightingShift) {
778
785
  this.adaptiveLightingShift = device.striplight.adaptiveLightingShift;
779
786
  this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
@@ -4,8 +4,8 @@
4
4
  */
5
5
  import { Units } from 'homebridge';
6
6
  import { deviceBase } from './device.js';
7
- import { convertUnits } from '../utils.js';
8
7
  import { Subject, interval, skipWhile } from 'rxjs';
8
+ import { convertUnits, validHumidity } from '../utils.js';
9
9
  import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot';
10
10
 
11
11
  import type { devicesConfig } from '../settings.js';
@@ -170,7 +170,7 @@ export class Meter extends deviceBase {
170
170
 
171
171
  // CurrentRelativeHumidity
172
172
  if (!this.device.iosensor?.hide_humidity && this.HumiditySensor?.Service) {
173
- this.HumiditySensor.CurrentRelativeHumidity = this.serviceData.humidity;
173
+ this.HumiditySensor.CurrentRelativeHumidity = validHumidity(this.serviceData.humidity, 0, 100);
174
174
  await this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`);
175
175
  }
176
176
 
@@ -5,9 +5,9 @@
5
5
  import { Units } from 'homebridge';
6
6
  import { deviceBase } from './device.js';
7
7
  import { Subject, interval, skipWhile } from 'rxjs';
8
+ import { convertUnits, validHumidity } from '../utils.js';
8
9
  import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot';
9
10
 
10
- import { convertUnits } from '../utils.js';
11
11
  import type { devicesConfig } from '../settings.js';
12
12
  import type { device } from '../types/devicelist.js';
13
13
  import type { SwitchBotPlatform } from '../platform.js';
@@ -175,7 +175,7 @@ export class MeterPlus extends deviceBase {
175
175
 
176
176
  // CurrentRelativeHumidity
177
177
  if (!this.device.iosensor?.hide_humidity && this.HumiditySensor?.Service) {
178
- this.HumiditySensor.CurrentRelativeHumidity = this.serviceData.humidity;
178
+ this.HumiditySensor.CurrentRelativeHumidity = validHumidity(this.serviceData.humidity, 0, 100);
179
179
  await this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`);
180
180
  }
181
181
  // Current Temperature
package/src/utils.ts CHANGED
@@ -115,7 +115,6 @@ export enum BlindTiltMappingMode {
115
115
  UseTiltForDirection = 'use_tilt_for_direction',
116
116
  }
117
117
 
118
- import type { Nullable, CharacteristicValue } from 'homebridge';
119
118
  import type { devicesConfig } from './settings.js';
120
119
  import type { blindTilt, curtain, curtain3, device } from './types/devicelist.js';
121
120
 
@@ -130,15 +129,20 @@ export function isBlindTiltDevice(device: device & devicesConfig): device is bli
130
129
  export function sleep(ms: number): Promise<void> {
131
130
  return new Promise((resolve) => setTimeout(resolve, ms));
132
131
  }
133
-
134
- export function checkName(displayName: string, name: string, value: Nullable<CharacteristicValue>): string {
135
- if (typeof value === 'string' && !(new RegExp(/^[\p{L}\p{N}][\p{L}\p{N} ']*[\p{L}\p{N}]$/u)).test(value)) {
136
- return `WARNING: The accessory '${displayName}' has an invalid '${name}' characteristic ('${value}'). Please use only alphanumeric, space, and`
137
- + ' apostrophe characters. Ensure it starts and ends with an alphabetic or numeric character, and avoid emojis. This may prevent the accessory '
138
- + 'from being added in the Home App or cause unresponsiveness.';
139
- } else {
140
- return 'false';
132
+ /**
133
+ * Check if the humidity is within the min and max range
134
+ * @param humidity - The humidity value
135
+ * @param min - The minimum humidity value
136
+ * @param max - The maximum humidity value
137
+ * @returns The humidity value
138
+ **/
139
+ export function validHumidity(humidity: number, min?: number, max?: number): number {
140
+ if (humidity < (min || 0)) {
141
+ return min ?? 0;
142
+ } else if (humidity > (max || 100)) {
143
+ return max ?? 100;
141
144
  }
145
+ return humidity;
142
146
  }
143
147
 
144
148
  /**