@switchbot/homebridge-switchbot 3.6.1-beta.1 → 3.6.1-beta.11

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 (136) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/device/blindtilt.d.ts.map +1 -1
  3. package/dist/device/blindtilt.js +44 -17
  4. package/dist/device/blindtilt.js.map +1 -1
  5. package/dist/device/bot.d.ts +1 -2
  6. package/dist/device/bot.d.ts.map +1 -1
  7. package/dist/device/bot.js +220 -397
  8. package/dist/device/bot.js.map +1 -1
  9. package/dist/device/ceilinglight.d.ts +3 -2
  10. package/dist/device/ceilinglight.d.ts.map +1 -1
  11. package/dist/device/ceilinglight.js +59 -31
  12. package/dist/device/ceilinglight.js.map +1 -1
  13. package/dist/device/colorbulb.d.ts +3 -2
  14. package/dist/device/colorbulb.d.ts.map +1 -1
  15. package/dist/device/colorbulb.js +57 -29
  16. package/dist/device/colorbulb.js.map +1 -1
  17. package/dist/device/contact.d.ts.map +1 -1
  18. package/dist/device/contact.js +47 -18
  19. package/dist/device/contact.js.map +1 -1
  20. package/dist/device/curtain.d.ts.map +1 -1
  21. package/dist/device/curtain.js +16 -5
  22. package/dist/device/curtain.js.map +1 -1
  23. package/dist/device/device.d.ts +9 -0
  24. package/dist/device/device.d.ts.map +1 -1
  25. package/dist/device/device.js +30 -3
  26. package/dist/device/device.js.map +1 -1
  27. package/dist/device/fan.d.ts.map +1 -1
  28. package/dist/device/fan.js +44 -18
  29. package/dist/device/fan.js.map +1 -1
  30. package/dist/device/hub.d.ts.map +1 -1
  31. package/dist/device/hub.js +46 -18
  32. package/dist/device/hub.js.map +1 -1
  33. package/dist/device/humidifier.d.ts.map +1 -1
  34. package/dist/device/humidifier.js +45 -20
  35. package/dist/device/humidifier.js.map +1 -1
  36. package/dist/device/iosensor.d.ts.map +1 -1
  37. package/dist/device/iosensor.js +46 -18
  38. package/dist/device/iosensor.js.map +1 -1
  39. package/dist/device/lightstrip.d.ts +4 -3
  40. package/dist/device/lightstrip.d.ts.map +1 -1
  41. package/dist/device/lightstrip.js +60 -31
  42. package/dist/device/lightstrip.js.map +1 -1
  43. package/dist/device/lock.d.ts.map +1 -1
  44. package/dist/device/lock.js +48 -17
  45. package/dist/device/lock.js.map +1 -1
  46. package/dist/device/meter.d.ts.map +1 -1
  47. package/dist/device/meter.js +46 -18
  48. package/dist/device/meter.js.map +1 -1
  49. package/dist/device/meterplus.d.ts.map +1 -1
  50. package/dist/device/meterplus.js +46 -18
  51. package/dist/device/meterplus.js.map +1 -1
  52. package/dist/device/motion.d.ts.map +1 -1
  53. package/dist/device/motion.js +45 -17
  54. package/dist/device/motion.js.map +1 -1
  55. package/dist/device/plug.d.ts.map +1 -1
  56. package/dist/device/plug.js +40 -18
  57. package/dist/device/plug.js.map +1 -1
  58. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  59. package/dist/device/robotvacuumcleaner.js +42 -17
  60. package/dist/device/robotvacuumcleaner.js.map +1 -1
  61. package/dist/device/waterdetector.d.ts.map +1 -1
  62. package/dist/device/waterdetector.js +41 -16
  63. package/dist/device/waterdetector.js.map +1 -1
  64. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  65. package/dist/irdevice/airconditioner.js +8 -1
  66. package/dist/irdevice/airconditioner.js.map +1 -1
  67. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  68. package/dist/irdevice/airpurifier.js +6 -0
  69. package/dist/irdevice/airpurifier.js.map +1 -1
  70. package/dist/irdevice/camera.d.ts.map +1 -1
  71. package/dist/irdevice/camera.js +3 -0
  72. package/dist/irdevice/camera.js.map +1 -1
  73. package/dist/irdevice/fan.d.ts.map +1 -1
  74. package/dist/irdevice/fan.js +3 -0
  75. package/dist/irdevice/fan.js.map +1 -1
  76. package/dist/irdevice/irdevice.d.ts +9 -0
  77. package/dist/irdevice/irdevice.d.ts.map +1 -1
  78. package/dist/irdevice/irdevice.js +29 -2
  79. package/dist/irdevice/irdevice.js.map +1 -1
  80. package/dist/irdevice/light.d.ts.map +1 -1
  81. package/dist/irdevice/light.js +9 -0
  82. package/dist/irdevice/light.js.map +1 -1
  83. package/dist/irdevice/other.d.ts +1 -0
  84. package/dist/irdevice/other.d.ts.map +1 -1
  85. package/dist/irdevice/other.js +216 -228
  86. package/dist/irdevice/other.js.map +1 -1
  87. package/dist/irdevice/tv.d.ts.map +1 -1
  88. package/dist/irdevice/tv.js +9 -0
  89. package/dist/irdevice/tv.js.map +1 -1
  90. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  91. package/dist/irdevice/vacuumcleaner.js +3 -0
  92. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  93. package/dist/irdevice/waterheater.js +1 -1
  94. package/dist/irdevice/waterheater.js.map +1 -1
  95. package/dist/platform.d.ts.map +1 -1
  96. package/dist/platform.js +11 -2
  97. package/dist/platform.js.map +1 -1
  98. package/dist/types/bledevicestatus.d.ts +1 -0
  99. package/dist/types/bledevicestatus.d.ts.map +1 -1
  100. package/dist/utils.d.ts +8 -0
  101. package/dist/utils.d.ts.map +1 -1
  102. package/dist/utils.js +16 -0
  103. package/dist/utils.js.map +1 -1
  104. package/package.json +6 -6
  105. package/src/device/blindtilt.ts +44 -17
  106. package/src/device/bot.ts +224 -407
  107. package/src/device/ceilinglight.ts +57 -33
  108. package/src/device/colorbulb.ts +55 -31
  109. package/src/device/contact.ts +48 -19
  110. package/src/device/curtain.ts +19 -6
  111. package/src/device/device.ts +36 -3
  112. package/src/device/fan.ts +44 -19
  113. package/src/device/hub.ts +46 -18
  114. package/src/device/humidifier.ts +44 -20
  115. package/src/device/iosensor.ts +46 -18
  116. package/src/device/lightstrip.ts +60 -33
  117. package/src/device/lock.ts +49 -17
  118. package/src/device/meter.ts +46 -18
  119. package/src/device/meterplus.ts +46 -18
  120. package/src/device/motion.ts +46 -18
  121. package/src/device/plug.ts +38 -18
  122. package/src/device/robotvacuumcleaner.ts +41 -17
  123. package/src/device/waterdetector.ts +40 -16
  124. package/src/irdevice/airconditioner.ts +11 -2
  125. package/src/irdevice/airpurifier.ts +8 -0
  126. package/src/irdevice/camera.ts +4 -0
  127. package/src/irdevice/fan.ts +4 -0
  128. package/src/irdevice/irdevice.ts +35 -2
  129. package/src/irdevice/light.ts +12 -0
  130. package/src/irdevice/other.ts +254 -283
  131. package/src/irdevice/tv.ts +12 -0
  132. package/src/irdevice/vacuumcleaner.ts +4 -0
  133. package/src/irdevice/waterheater.ts +1 -1
  134. package/src/platform.ts +11 -2
  135. package/src/types/bledevicestatus.ts +1 -0
  136. package/src/utils.ts +15 -0
@@ -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';
@@ -65,6 +65,10 @@ export class Meter extends deviceBase {
65
65
 
66
66
  // Initialize Battery Service
67
67
  accessory.context.Battery = accessory.context.Battery ?? {};
68
+ if (accessory.context.Battery.Name) {
69
+ accessory.context.Battery.Name = this.validateAndCleanString(accessory.context.Battery.Name,
70
+ 'Battery Name', accessory.context.Battery.Name);
71
+ }
68
72
  this.Battery = {
69
73
  Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
70
74
  Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
@@ -97,6 +101,10 @@ export class Meter extends deviceBase {
97
101
  }
98
102
  } else {
99
103
  accessory.context.TemperatureSensor = accessory.context.TemperatureSensor ?? {};
104
+ if (accessory.context.TemperatureSensor.Name) {
105
+ accessory.context.TemperatureSensor.Name = this.validateAndCleanString(accessory.context.TemperatureSensor.Name,
106
+ 'TemperatureSensor Name', accessory.context.TemperatureSensor.Name);
107
+ }
100
108
  this.TemperatureSensor = {
101
109
  Name: accessory.context.TemperatureSensor.Name ?? `${accessory.displayName} Temperature Sensor`,
102
110
  Service: accessory.getService(this.hap.Service.TemperatureSensor) ?? this.accessory.addService(this.hap.Service.TemperatureSensor) as Service,
@@ -128,6 +136,10 @@ export class Meter extends deviceBase {
128
136
  }
129
137
  } else {
130
138
  accessory.context.HumiditySensor = accessory.context.HumiditySensor ?? {};
139
+ if (accessory.context.HumiditySensor.Name) {
140
+ accessory.context.HumiditySensor.Name = this.validateAndCleanString(accessory.context.HumiditySensor.Name,
141
+ 'HumiditySensor Name', accessory.context.HumiditySensor.Name);
142
+ }
131
143
  this.HumiditySensor = {
132
144
  Name: accessory.context.HumiditySensorName ?? `${accessory.displayName} Humidity Sensor`,
133
145
  Service: accessory.getService(this.hap.Service.HumiditySensor) ?? this.accessory.addService(this.hap.Service.HumiditySensor) as Service,
@@ -170,7 +182,7 @@ export class Meter extends deviceBase {
170
182
 
171
183
  // CurrentRelativeHumidity
172
184
  if (!this.device.iosensor?.hide_humidity && this.HumiditySensor?.Service) {
173
- this.HumiditySensor.CurrentRelativeHumidity = this.serviceData.humidity;
185
+ this.HumiditySensor.CurrentRelativeHumidity = validHumidity(this.serviceData.humidity, 0, 100);
174
186
  await this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`);
175
187
  }
176
188
 
@@ -277,25 +289,41 @@ export class Meter extends deviceBase {
277
289
 
278
290
  async BLERefreshStatus(): Promise<void> {
279
291
  await this.debugLog('BLERefreshStatus');
280
- const switchbot = await this.switchbotBLE();
281
-
282
- if (switchbot === undefined) {
283
- await this.BLERefreshConnection(switchbot);
284
- } else {
285
- // Start to monitor advertisement packets
286
- (async () => {
287
- // Start to monitor advertisement packets
288
- const serviceData = await this.monitorAdvertisementPackets(switchbot) as meterServiceData;
289
- // Update HomeKit
290
- if (serviceData.model === SwitchBotBLEModel.Meter && serviceData.modelName === SwitchBotBLEModelName.Meter) {
291
- this.serviceData = serviceData;
292
+ if (this.config.options?.BLE) {
293
+ await this.debugLog('is listening to Platform BLE.');
294
+ this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
295
+ await this.debugLog(`bleMac: ${this.device.bleMac}`);
296
+ this.platform.bleEventHandler[this.device.bleMac] = async (context: meterServiceData) => {
297
+ try {
298
+ await this.debugLog(`received BLE: ${JSON.stringify(context)}`);
299
+ this.serviceData = context;
292
300
  await this.BLEparseStatus();
293
301
  await this.updateHomeKitCharacteristics();
294
- } else {
295
- await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
296
- await this.BLERefreshConnection(switchbot);
302
+ } catch (e: any) {
303
+ await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`);
297
304
  }
298
- })();
305
+ };
306
+ } else {
307
+ await this.debugLog('is using Device BLE Scanning.');
308
+ const switchbot = await this.switchbotBLE();
309
+ if (switchbot === undefined) {
310
+ await this.BLERefreshConnection(switchbot);
311
+ } else {
312
+ // Start to monitor advertisement packets
313
+ (async () => {
314
+ // Start to monitor advertisement packets
315
+ const serviceData = await this.monitorAdvertisementPackets(switchbot) as meterServiceData;
316
+ // Update HomeKit
317
+ if (serviceData.model === SwitchBotBLEModel.Meter && serviceData.modelName === SwitchBotBLEModelName.Meter) {
318
+ this.serviceData = serviceData;
319
+ await this.BLEparseStatus();
320
+ await this.updateHomeKitCharacteristics();
321
+ } else {
322
+ await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
323
+ await this.BLERefreshConnection(switchbot);
324
+ }
325
+ })();
326
+ }
299
327
  }
300
328
  }
301
329
 
@@ -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';
@@ -70,6 +70,10 @@ export class MeterPlus extends deviceBase {
70
70
 
71
71
  // Initialize Battery Service
72
72
  accessory.context.Battery = accessory.context.Battery ?? {};
73
+ if (accessory.context.Battery.Name) {
74
+ accessory.context.Battery.Name = this.validateAndCleanString(accessory.context.Battery.Name,
75
+ 'Battery Name', accessory.context.Battery.Name);
76
+ }
73
77
  this.Battery = {
74
78
  Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
75
79
  Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
@@ -102,6 +106,10 @@ export class MeterPlus extends deviceBase {
102
106
  }
103
107
  } else {
104
108
  accessory.context.TemperatureSensor = accessory.context.TemperatureSensor ?? {};
109
+ if (accessory.context.TemperatureSensor.Name) {
110
+ accessory.context.TemperatureSensor.Name = this.validateAndCleanString(accessory.context.TemperatureSensor.Name,
111
+ 'TemperatureSensor Name', accessory.context.TemperatureSensor.Name);
112
+ }
105
113
  this.TemperatureSensor = {
106
114
  Name: accessory.context.TemperatureSensor.Name ?? `${accessory.displayName} Temperature Sensor`,
107
115
  Service: accessory.getService(this.hap.Service.TemperatureSensor) ?? this.accessory.addService(this.hap.Service.TemperatureSensor) as Service,
@@ -133,6 +141,10 @@ export class MeterPlus extends deviceBase {
133
141
  }
134
142
  } else {
135
143
  accessory.context.HumiditySensor = accessory.context.HumiditySensor ?? {};
144
+ if (accessory.context.HumiditySensor.Name) {
145
+ accessory.context.HumiditySensor.Name = this.validateAndCleanString(accessory.context.HumiditySensor.Name,
146
+ 'HumiditySensor Name', accessory.context.HumiditySensor.Name);
147
+ }
136
148
  this.HumiditySensor = {
137
149
  Name: accessory.context.HumiditySensor.Name ?? `${accessory.displayName} Humidity Sensor`,
138
150
  Service: accessory.getService(this.hap.Service.HumiditySensor) ?? this.accessory.addService(this.hap.Service.HumiditySensor) as Service,
@@ -175,7 +187,7 @@ export class MeterPlus extends deviceBase {
175
187
 
176
188
  // CurrentRelativeHumidity
177
189
  if (!this.device.iosensor?.hide_humidity && this.HumiditySensor?.Service) {
178
- this.HumiditySensor.CurrentRelativeHumidity = this.serviceData.humidity;
190
+ this.HumiditySensor.CurrentRelativeHumidity = validHumidity(this.serviceData.humidity, 0, 100);
179
191
  await this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`);
180
192
  }
181
193
  // Current Temperature
@@ -278,25 +290,41 @@ export class MeterPlus extends deviceBase {
278
290
 
279
291
  async BLERefreshStatus(): Promise<void> {
280
292
  await this.debugLog('BLERefreshStatus');
281
- const switchbot = await this.switchbotBLE();
282
-
283
- if (switchbot === undefined) {
284
- await this.BLERefreshConnection(switchbot);
285
- } else {
286
- // Start to monitor advertisement packets
287
- (async () => {
288
- // Start to monitor advertisement packets
289
- const serviceData = await this.monitorAdvertisementPackets(switchbot) as meterPlusServiceData;
290
- // Update HomeKit
291
- if (serviceData.model === SwitchBotBLEModel.MeterPlus && serviceData.modelName === SwitchBotBLEModelName.MeterPlus) {
292
- this.serviceData = serviceData;
293
+ if (this.config.options?.BLE) {
294
+ await this.debugLog('is listening to Platform BLE.');
295
+ this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
296
+ await this.debugLog(`bleMac: ${this.device.bleMac}`);
297
+ this.platform.bleEventHandler[this.device.bleMac] = async (context: meterPlusServiceData) => {
298
+ try {
299
+ await this.debugLog(`received BLE: ${JSON.stringify(context)}`);
300
+ this.serviceData = context;
293
301
  await this.BLEparseStatus();
294
302
  await this.updateHomeKitCharacteristics();
295
- } else {
296
- await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
297
- await this.BLERefreshConnection(switchbot);
303
+ } catch (e: any) {
304
+ await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`);
298
305
  }
299
- })();
306
+ };
307
+ } else {
308
+ await this.debugLog('is using Device BLE Scanning.');
309
+ const switchbot = await this.switchbotBLE();
310
+ if (switchbot === undefined) {
311
+ await this.BLERefreshConnection(switchbot);
312
+ } else {
313
+ // Start to monitor advertisement packets
314
+ (async () => {
315
+ // Start to monitor advertisement packets
316
+ const serviceData = await this.monitorAdvertisementPackets(switchbot) as meterPlusServiceData;
317
+ // Update HomeKit
318
+ if (serviceData.model === SwitchBotBLEModel.MeterPlus && serviceData.modelName === SwitchBotBLEModelName.MeterPlus) {
319
+ this.serviceData = serviceData;
320
+ await this.BLEparseStatus();
321
+ await this.updateHomeKitCharacteristics();
322
+ } else {
323
+ await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
324
+ await this.BLERefreshConnection(switchbot);
325
+ }
326
+ })();
327
+ }
300
328
  }
301
329
  }
302
330
 
@@ -69,6 +69,10 @@ export class Motion extends deviceBase {
69
69
 
70
70
  // Initialize Motion Sensor property
71
71
  accessory.context.MotionSensor = accessory.context.MotionSensor ?? {};
72
+ if (accessory.context.MotionSensor.Name) {
73
+ accessory.context.MotionSensor.Name = this.validateAndCleanString(accessory.context.MotionSensor.Name,
74
+ 'MotionSensor Name', accessory.context.MotionSensor.Name);
75
+ }
72
76
  this.MotionSensor = {
73
77
  Name: accessory.context.MotionSensor.Name ?? `${accessory.displayName} Motion Sensor`,
74
78
  Service: accessory.getService(this.hap.Service.MotionSensor) ?? accessory.addService(this.hap.Service.MotionSensor) as Service,
@@ -78,7 +82,7 @@ export class Motion extends deviceBase {
78
82
 
79
83
  // Initialize Motion Sensor Characteristics
80
84
  this.MotionSensor.Service
81
- .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
85
+ .setCharacteristic(this.hap.Characteristic.Name, this.MotionSensor.Name)
82
86
  .setCharacteristic(this.hap.Characteristic.StatusActive, true)
83
87
  .getCharacteristic(this.hap.Characteristic.MotionDetected)
84
88
  .onGet(() => {
@@ -88,6 +92,10 @@ export class Motion extends deviceBase {
88
92
 
89
93
  // Initialize Battery Service
90
94
  accessory.context.Battery = accessory.context.Battery ?? {};
95
+ if (accessory.context.Battery.Name) {
96
+ accessory.context.Battery.Name = this.validateAndCleanString(accessory.context.Battery.Name,
97
+ 'Battery Name', accessory.context.Battery.Name);
98
+ }
91
99
  this.Battery = {
92
100
  Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
93
101
  Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
@@ -121,6 +129,10 @@ export class Motion extends deviceBase {
121
129
  }
122
130
  } else {
123
131
  accessory.context.LightSensor = accessory.context.LightSensor ?? {};
132
+ if (accessory.context.LightSensor.Name) {
133
+ accessory.context.LightSensor.Name = this.validateAndCleanString(accessory.context.LightSensor.Name,
134
+ 'LightSensor Name', accessory.context.LightSensor.Name);
135
+ }
124
136
  this.LightSensor = {
125
137
  Name: accessory.context.LightSensor.Name ?? `${accessory.displayName} Light Sensor`,
126
138
  Service: accessory.getService(this.hap.Service.LightSensor) ?? this.accessory.addService(this.hap.Service.LightSensor) as Service,
@@ -130,7 +142,7 @@ export class Motion extends deviceBase {
130
142
 
131
143
  // Initialize LightSensor Characteristics
132
144
  this.LightSensor!.Service
133
- .setCharacteristic(this.hap.Characteristic.Name, this.LightSensor!.Name)
145
+ .setCharacteristic(this.hap.Characteristic.Name, this.LightSensor.Name)
134
146
  .setCharacteristic(this.hap.Characteristic.StatusActive, true)
135
147
  .getCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel)
136
148
  .onGet(() => {
@@ -249,25 +261,41 @@ export class Motion extends deviceBase {
249
261
 
250
262
  async BLERefreshStatus(): Promise<void> {
251
263
  await this.debugLog('BLERefreshStatus');
252
- const switchbot = await this.switchbotBLE();
253
-
254
- if (switchbot === undefined) {
255
- await this.BLERefreshConnection(switchbot);
256
- } else {
257
- // Start to monitor advertisement packets
258
- (async () => {
259
- // Start to monitor advertisement packets
260
- const serviceData = await this.monitorAdvertisementPackets(switchbot) as motionSensorServiceData;
261
- // Update HomeKit
262
- if (serviceData.model === SwitchBotBLEModel.MotionSensor && serviceData.modelName === SwitchBotBLEModelName.MotionSensor) {
263
- this.serviceData = serviceData;
264
+ if (this.config.options?.BLE) {
265
+ await this.debugLog('is listening to Platform BLE.');
266
+ this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
267
+ await this.debugLog(`bleMac: ${this.device.bleMac}`);
268
+ this.platform.bleEventHandler[this.device.bleMac] = async (context: motionSensorServiceData) => {
269
+ try {
270
+ await this.debugLog(`received BLE: ${JSON.stringify(context)}`);
271
+ this.serviceData = context;
264
272
  await this.BLEparseStatus();
265
273
  await this.updateHomeKitCharacteristics();
266
- } else {
267
- await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
268
- await this.BLERefreshConnection(switchbot);
274
+ } catch (e: any) {
275
+ await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`);
269
276
  }
270
- })();
277
+ };
278
+ } else {
279
+ await this.debugLog('is using Device BLE Scanning.');
280
+ const switchbot = await this.switchbotBLE();
281
+ if (switchbot === undefined) {
282
+ await this.BLERefreshConnection(switchbot);
283
+ } else {
284
+ // Start to monitor advertisement packets
285
+ (async () => {
286
+ // Start to monitor advertisement packets
287
+ const serviceData = await this.monitorAdvertisementPackets(switchbot) as motionSensorServiceData;
288
+ // Update HomeKit
289
+ if (serviceData.model === SwitchBotBLEModel.MotionSensor && serviceData.modelName === SwitchBotBLEModelName.MotionSensor) {
290
+ this.serviceData = serviceData;
291
+ await this.BLEparseStatus();
292
+ await this.updateHomeKitCharacteristics();
293
+ } else {
294
+ await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
295
+ await this.BLERefreshConnection(switchbot);
296
+ }
297
+ })();
298
+ }
271
299
  }
272
300
  }
273
301
 
@@ -49,6 +49,10 @@ export class Plug extends deviceBase {
49
49
 
50
50
  // Initialize Outlet Service
51
51
  accessory.context.Outlet = accessory.context.Outlet ?? {};
52
+ if (accessory.context.Outlet.Name) {
53
+ accessory.context.Outlet.Name = this.validateAndCleanString(accessory.context.Outlet.Name,
54
+ 'Outlet Name', accessory.context.Outlet.Name);
55
+ }
52
56
  this.Outlet = {
53
57
  Name: accessory.context.Outlet.Name ?? accessory.displayName,
54
58
  Service: accessory.getService(this.hap.Service.Outlet) ?? accessory.addService(this.hap.Service.Outlet) as Service,
@@ -58,7 +62,7 @@ export class Plug extends deviceBase {
58
62
 
59
63
  // Initialize Outlet Characteristics
60
64
  this.Outlet.Service
61
- .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
65
+ .setCharacteristic(this.hap.Characteristic.Name, this.Outlet.Name)
62
66
  .getCharacteristic(this.hap.Characteristic.On)
63
67
  .onGet(() => {
64
68
  return this.Outlet.On;
@@ -160,26 +164,42 @@ export class Plug extends deviceBase {
160
164
 
161
165
  async BLERefreshStatus(): Promise<void> {
162
166
  await this.debugLog('BLERefreshStatus');
163
- const switchbot = await this.switchbotBLE();
164
-
165
- if (switchbot === undefined) {
166
- await this.BLERefreshConnection(switchbot);
167
- } else {
168
- // Start to monitor advertisement packets
169
- (async () => {
170
- // Start to monitor advertisement packets
171
- const serviceData = await this.monitorAdvertisementPackets(switchbot) as plugMiniUSServiceData | plugMiniJPServiceData;
172
- // Update HomeKit
173
- if ((serviceData.model === SwitchBotBLEModel.PlugMiniUS || SwitchBotBLEModel.PlugMiniJP)
174
- && serviceData.modelName === (SwitchBotBLEModelName.PlugMini || SwitchBotBLEModelName.PlugMini)) {
175
- this.serviceData = serviceData;
167
+ if (this.config.options?.BLE) {
168
+ await this.debugLog('is listening to Platform BLE.');
169
+ this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
170
+ await this.debugLog(`bleMac: ${this.device.bleMac}`);
171
+ this.platform.bleEventHandler[this.device.bleMac] = async (context: plugMiniUSServiceData | plugMiniJPServiceData) => {
172
+ try {
173
+ await this.debugLog(`received BLE: ${JSON.stringify(context)}`);
174
+ this.serviceData = context;
176
175
  await this.BLEparseStatus();
177
176
  await this.updateHomeKitCharacteristics();
178
- } else {
179
- await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
180
- await this.BLERefreshConnection(switchbot);
177
+ } catch (e: any) {
178
+ await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`);
181
179
  }
182
- })();
180
+ };
181
+ } else {
182
+ await this.debugLog('is using Device BLE Scanning.');
183
+ const switchbot = await this.switchbotBLE();
184
+ if (switchbot === undefined) {
185
+ await this.BLERefreshConnection(switchbot);
186
+ } else {
187
+ // Start to monitor advertisement packets
188
+ (async () => {
189
+ // Start to monitor advertisement packets
190
+ const serviceData = await this.monitorAdvertisementPackets(switchbot) as plugMiniUSServiceData | plugMiniJPServiceData;
191
+ // Update HomeKit
192
+ if ((serviceData.model === SwitchBotBLEModel.PlugMiniUS || SwitchBotBLEModel.PlugMiniJP)
193
+ && serviceData.modelName === (SwitchBotBLEModelName.PlugMini || SwitchBotBLEModelName.PlugMini)) {
194
+ this.serviceData = serviceData;
195
+ await this.BLEparseStatus();
196
+ await this.updateHomeKitCharacteristics();
197
+ } else {
198
+ await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
199
+ await this.BLERefreshConnection(switchbot);
200
+ }
201
+ })();
202
+ }
183
203
  }
184
204
  }
185
205
 
@@ -63,6 +63,10 @@ export class RobotVacuumCleaner extends deviceBase {
63
63
 
64
64
  // Initialize Lightbulb Service
65
65
  accessory.context.LightBulb = accessory.context.LightBulb ?? {};
66
+ if (accessory.context.LightBulb.Name) {
67
+ accessory.context.LightBulb.Name = this.validateAndCleanString(accessory.context.LightBulb.Name,
68
+ 'LightBulb Name', accessory.context.LightBulb.Name);
69
+ }
66
70
  this.LightBulb = {
67
71
  Name: accessory.context.LightBulb.Name ?? accessory.displayName,
68
72
  Service: accessory.getService(this.hap.Service.Lightbulb) ?? accessory.addService(this.hap.Service.Lightbulb) as Service,
@@ -73,7 +77,7 @@ export class RobotVacuumCleaner extends deviceBase {
73
77
 
74
78
  // Initialize LightBulb Characteristics
75
79
  this.LightBulb.Service
76
- .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
80
+ .setCharacteristic(this.hap.Characteristic.Name, this.LightBulb.Name)
77
81
  .getCharacteristic(this.hap.Characteristic.On)
78
82
  .onGet(() => {
79
83
  return this.LightBulb.On;
@@ -97,6 +101,10 @@ export class RobotVacuumCleaner extends deviceBase {
97
101
 
98
102
  // Initialize Battery Service
99
103
  accessory.context.Battery = accessory.context.Battery ?? {};
104
+ if (accessory.context.Battery.Name) {
105
+ accessory.context.Battery.Name = this.validateAndCleanString(accessory.context.Battery.Name,
106
+ 'Battery Name', accessory.context.Battery.Name);
107
+ }
100
108
  this.Battery = {
101
109
  Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
102
110
  Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
@@ -261,25 +269,41 @@ export class RobotVacuumCleaner extends deviceBase {
261
269
 
262
270
  async BLERefreshStatus(): Promise<void> {
263
271
  await this.debugLog('BLERefreshStatus');
264
- const switchbot = await this.switchbotBLE();
265
-
266
- if (switchbot === undefined) {
267
- await this.BLERefreshConnection(switchbot);
268
- } else {
269
- // Start to monitor advertisement packets
270
- (async () => {
271
- // Start to monitor advertisement packets
272
- const serviceData = await this.monitorAdvertisementPackets(switchbot) as unknown as robotVacuumCleanerServiceData;
273
- // Update HomeKit
274
- if (serviceData.model === SwitchBotBLEModel.Unknown && serviceData.modelName === SwitchBotBLEModelName.Unknown) {
275
- this.serviceData = serviceData;
272
+ if (this.config.options?.BLE) {
273
+ await this.debugLog('is listening to Platform BLE.');
274
+ this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
275
+ await this.debugLog(`bleMac: ${this.device.bleMac}`);
276
+ this.platform.bleEventHandler[this.device.bleMac] = async (context: robotVacuumCleanerServiceData) => {
277
+ try {
278
+ await this.debugLog(`received BLE: ${JSON.stringify(context)}`);
279
+ this.serviceData = context;
276
280
  await this.BLEparseStatus();
277
281
  await this.updateHomeKitCharacteristics();
278
- } else {
279
- await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
280
- await this.BLERefreshConnection(switchbot);
282
+ } catch (e: any) {
283
+ await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`);
281
284
  }
282
- })();
285
+ };
286
+ } else {
287
+ await this.debugLog('is using Device BLE Scanning.');
288
+ const switchbot = await this.switchbotBLE();
289
+ if (switchbot === undefined) {
290
+ await this.BLERefreshConnection(switchbot);
291
+ } else {
292
+ // Start to monitor advertisement packets
293
+ (async () => {
294
+ // Start to monitor advertisement packets
295
+ const serviceData = await this.monitorAdvertisementPackets(switchbot) as unknown as robotVacuumCleanerServiceData;
296
+ // Update HomeKit
297
+ if (serviceData.model === SwitchBotBLEModel.Unknown && serviceData.modelName === SwitchBotBLEModelName.Unknown) {
298
+ this.serviceData = serviceData;
299
+ await this.BLEparseStatus();
300
+ await this.updateHomeKitCharacteristics();
301
+ } else {
302
+ await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
303
+ await this.BLERefreshConnection(switchbot);
304
+ }
305
+ })();
306
+ }
283
307
  }
284
308
  }
285
309
 
@@ -64,6 +64,10 @@ export class WaterDetector extends deviceBase {
64
64
 
65
65
  // Initialize Battery Service
66
66
  accessory.context.Battery = accessory.context.Battery ?? {};
67
+ if (accessory.context.Battery.Name) {
68
+ accessory.context.Battery.Name = this.validateAndCleanString(accessory.context.Battery.Name,
69
+ 'Battery Name', accessory.context.Battery.Name);
70
+ }
67
71
  this.Battery = {
68
72
  Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
69
73
  Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
@@ -99,6 +103,10 @@ export class WaterDetector extends deviceBase {
99
103
  }
100
104
  } else {
101
105
  accessory.context.LeakSensor = accessory.context.LeakSensor ?? {};
106
+ if (accessory.context.LeakSensor.Name) {
107
+ accessory.context.LeakSensor.Name = this.validateAndCleanString(accessory.context.LeakSensor.Name,
108
+ 'LeakSensor Name', accessory.context.LeakSensor.Name);
109
+ }
102
110
  this.LeakSensor = {
103
111
  Name: accessory.context.LeakSensor.Name ?? `${accessory.displayName} Leak Sensor`,
104
112
  Service: accessory.getService(this.hap.Service.LeakSensor) ?? this.accessory.addService(this.hap.Service.LeakSensor) as Service,
@@ -246,25 +254,41 @@ export class WaterDetector extends deviceBase {
246
254
 
247
255
  async BLERefreshStatus(): Promise<void> {
248
256
  await this.debugLog('BLERefreshStatus');
249
- const switchbot = await this.switchbotBLE();
250
-
251
- if (switchbot === undefined) {
252
- await this.BLERefreshConnection(switchbot);
253
- } else {
254
- // Start to monitor advertisement packets
255
- (async () => {
256
- // Start to monitor advertisement packets
257
- const serviceData = await this.monitorAdvertisementPackets(switchbot) as waterLeakDetectorServiceData;
258
- // Update HomeKit
259
- if (serviceData.model === SwitchBotBLEModel.Unknown && serviceData.modelName === SwitchBotBLEModelName.Unknown) {
260
- this.serviceData = serviceData;
257
+ if (this.config.options?.BLE) {
258
+ await this.debugLog('is listening to Platform BLE.');
259
+ this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
260
+ await this.debugLog(`bleMac: ${this.device.bleMac}`);
261
+ this.platform.bleEventHandler[this.device.bleMac] = async (context: waterLeakDetectorServiceData) => {
262
+ try {
263
+ await this.debugLog(`received BLE: ${JSON.stringify(context)}`);
264
+ this.serviceData = context;
261
265
  await this.BLEparseStatus();
262
266
  await this.updateHomeKitCharacteristics();
263
- } else {
264
- await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
265
- await this.BLERefreshConnection(switchbot);
267
+ } catch (e: any) {
268
+ await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`);
266
269
  }
267
- })();
270
+ };
271
+ } else {
272
+ await this.debugLog('is using Device BLE Scanning.');
273
+ const switchbot = await this.switchbotBLE();
274
+ if (switchbot === undefined) {
275
+ await this.BLERefreshConnection(switchbot);
276
+ } else {
277
+ // Start to monitor advertisement packets
278
+ (async () => {
279
+ // Start to monitor advertisement packets
280
+ const serviceData = await this.monitorAdvertisementPackets(switchbot) as waterLeakDetectorServiceData;
281
+ // Update HomeKit
282
+ if (serviceData.model === SwitchBotBLEModel.Unknown && serviceData.modelName === SwitchBotBLEModelName.Unknown) {
283
+ this.serviceData = serviceData;
284
+ await this.BLEparseStatus();
285
+ await this.updateHomeKitCharacteristics();
286
+ } else {
287
+ await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
288
+ await this.BLERefreshConnection(switchbot);
289
+ }
290
+ })();
291
+ }
268
292
  }
269
293
  }
270
294
 
@@ -66,6 +66,10 @@ export class AirConditioner extends irdeviceBase {
66
66
 
67
67
  // Initialize HeaterCooler Service
68
68
  accessory.context.HeaterCooler = accessory.context.HeaterCooler ?? {};
69
+ if (accessory.context.HeaterCooler.Name) {
70
+ accessory.context.HeaterCooler.Name = this.validateAndCleanString(accessory.context.HeaterCooler.Name,
71
+ 'HeaterCooler Name', accessory.context.HeaterCooler.Name);
72
+ }
69
73
  this.HeaterCooler = {
70
74
  Name: accessory.context.HeaterCooler.Name ?? `${accessory.displayName} ${device.remoteType}`,
71
75
  Service: accessory.getService(this.hap.Service.HeaterCooler) ?? accessory.addService(this.hap.Service.HeaterCooler) as Service,
@@ -151,6 +155,10 @@ export class AirConditioner extends irdeviceBase {
151
155
  const meterUuid = this.platform.api.hap.uuid.generate(`${this.device.irair.meterId}-${this.device.irair.meterType}`);
152
156
  this.meter = this.platform.accessories.find((accessory) => accessory.UUID === meterUuid);
153
157
  accessory.context.HumiditySensor = accessory.context.HumiditySensor ?? {};
158
+ if (accessory.context.HumiditySensor.Name) {
159
+ accessory.context.HumiditySensor.Name = this.validateAndCleanString(accessory.context.HumiditySensor.Name,
160
+ 'HumiditySensor Name', accessory.context.HumiditySensor.Name);
161
+ }
154
162
  this.HumiditySensor = {
155
163
  Name: accessory.context.HumiditySensor ?? this.meter!.displayName,
156
164
  Service: this.meter!.getService(this.hap.Service.HumiditySensor) ?? this.meter!.addService(this.hap.Service.HumiditySensor) as Service,
@@ -164,8 +172,9 @@ export class AirConditioner extends irdeviceBase {
164
172
  this.meter = this.platform.accessories.find((accessory) => accessory.UUID === meterUuid);
165
173
  }
166
174
 
167
- if (this.meter) {
168
- this.HumiditySensor!.Service
175
+ if (this.meter && this.HumiditySensor) {
176
+ this.HumiditySensor.Service
177
+ .setCharacteristic(this.hap.Characteristic.Name, this.HumiditySensor.Name)
169
178
  .getCharacteristic(this.hap.Characteristic.CurrentRelativeHumidity)
170
179
  .onGet(async () => {
171
180
  return await this.CurrentRelativeHumidityGet();
@@ -59,6 +59,10 @@ export class AirPurifier extends irdeviceBase {
59
59
 
60
60
  // Initialize AirPurifier Service
61
61
  accessory.context.AirPurifier = accessory.context.AirPurifier ?? {};
62
+ if (accessory.context.AirPurifier.Name) {
63
+ accessory.context.AirPurifier.Name = this.validateAndCleanString(accessory.context.AirPurifier.Name,
64
+ 'AirPurifier Name', accessory.context.AirPurifier.Name);
65
+ }
62
66
  this.AirPurifier = {
63
67
  Name: accessory.context.AirPurifier.Name ?? `${accessory.displayName} Air Purifier`,
64
68
  Service: accessory.getService(this.hap.Service.AirPurifier) ?? accessory.addService(this.hap.Service.AirPurifier) as Service,
@@ -93,6 +97,10 @@ export class AirPurifier extends irdeviceBase {
93
97
 
94
98
  // Initialize TemperatureSensor Service
95
99
  accessory.context.TemperatureSensor = accessory.context.TemperatureSensor ?? {};
100
+ if (accessory.context.TemperatureSensor.Name) {
101
+ accessory.context.TemperatureSensor.Name = this.validateAndCleanString(accessory.context.TemperatureSensor.Name,
102
+ 'TemperatureSensor Name', accessory.context.TemperatureSensor.Name);
103
+ }
96
104
  this.TemperatureSensor = {
97
105
  Name: accessory.context.TemperatureSensor.Name ?? `${accessory.displayName} Temperature Sensor`,
98
106
  Service: accessory.getService(this.hap.Service.TemperatureSensor) ?? accessory.addService(this.hap.Service.TemperatureSensor) as Service,
@@ -33,6 +33,10 @@ export class Camera extends irdeviceBase {
33
33
 
34
34
  // Initialize Switch Service
35
35
  accessory.context.Switch = accessory.context.Switch ?? {};
36
+ if (accessory.context.Switch.Name) {
37
+ accessory.context.Switch.Name = this.validateAndCleanString(accessory.context.Switch.Name,
38
+ 'Switch Name', accessory.context.Switch.Name);
39
+ }
36
40
  this.Switch = {
37
41
  Name: accessory.context.Switch.Name ?? `${accessory.displayName} Camera`,
38
42
  Service: accessory.getService(this.hap.Service.Switch) ?? accessory.addService(this.hap.Service.Switch) as Service,
@@ -36,6 +36,10 @@ export class IRFan extends irdeviceBase {
36
36
 
37
37
  // Initialize Switch Service
38
38
  accessory.context.Fan = accessory.context.Fan ?? {};
39
+ if (accessory.context.Fan.Name) {
40
+ accessory.context.Fan.Name = this.validateAndCleanString(accessory.context.Fan.Name,
41
+ 'Fan Name', accessory.context.Fan.Name);
42
+ }
39
43
  this.Fan = {
40
44
  Name: accessory.context.Fan.Name ?? `${accessory.displayName} Fan`,
41
45
  Service: accessory.getService(this.hap.Service.Fanv2) ?? accessory.addService(this.hap.Service.Fanv2) as Service,