@switchbot/homebridge-switchbot 3.5.0-beta.9 → 3.5.1-beta.0

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 (177) hide show
  1. package/.vscode/settings.json +4 -1
  2. package/CHANGELOG.md +4 -1
  3. package/config.schema.json +164 -22
  4. package/dist/device/blindtilt.d.ts +21 -96
  5. package/dist/device/blindtilt.d.ts.map +1 -1
  6. package/dist/device/blindtilt.js +457 -866
  7. package/dist/device/blindtilt.js.map +1 -1
  8. package/dist/device/bot.d.ts +27 -72
  9. package/dist/device/bot.d.ts.map +1 -1
  10. package/dist/device/bot.js +851 -913
  11. package/dist/device/bot.js.map +1 -1
  12. package/dist/device/ceilinglight.d.ts +15 -69
  13. package/dist/device/ceilinglight.d.ts.map +1 -1
  14. package/dist/device/ceilinglight.js +316 -742
  15. package/dist/device/ceilinglight.js.map +1 -1
  16. package/dist/device/colorbulb.d.ts +15 -76
  17. package/dist/device/colorbulb.d.ts.map +1 -1
  18. package/dist/device/colorbulb.js +380 -833
  19. package/dist/device/colorbulb.js.map +1 -1
  20. package/dist/device/contact.d.ts +14 -66
  21. package/dist/device/contact.d.ts.map +1 -1
  22. package/dist/device/contact.js +267 -602
  23. package/dist/device/contact.js.map +1 -1
  24. package/dist/device/curtain.d.ts +18 -89
  25. package/dist/device/curtain.d.ts.map +1 -1
  26. package/dist/device/curtain.js +469 -897
  27. package/dist/device/curtain.js.map +1 -1
  28. package/dist/device/device.d.ts +76 -0
  29. package/dist/device/device.d.ts.map +1 -0
  30. package/dist/device/device.js +846 -0
  31. package/dist/device/device.js.map +1 -0
  32. package/dist/device/fan.d.ts +63 -0
  33. package/dist/device/fan.d.ts.map +1 -0
  34. package/dist/device/fan.js +645 -0
  35. package/dist/device/fan.js.map +1 -0
  36. package/dist/device/hub.d.ts +19 -58
  37. package/dist/device/hub.d.ts.map +1 -1
  38. package/dist/device/hub.js +304 -640
  39. package/dist/device/hub.js.map +1 -1
  40. package/dist/device/humidifier.d.ts +11 -66
  41. package/dist/device/humidifier.d.ts.map +1 -1
  42. package/dist/device/humidifier.js +300 -710
  43. package/dist/device/humidifier.js.map +1 -1
  44. package/dist/device/iosensor.d.ts +12 -64
  45. package/dist/device/iosensor.d.ts.map +1 -1
  46. package/dist/device/iosensor.js +225 -643
  47. package/dist/device/iosensor.js.map +1 -1
  48. package/dist/device/lightstrip.d.ts +12 -70
  49. package/dist/device/lightstrip.d.ts.map +1 -1
  50. package/dist/device/lightstrip.js +371 -742
  51. package/dist/device/lightstrip.js.map +1 -1
  52. package/dist/device/lock.d.ts +17 -63
  53. package/dist/device/lock.d.ts.map +1 -1
  54. package/dist/device/lock.js +309 -642
  55. package/dist/device/lock.js.map +1 -1
  56. package/dist/device/meter.d.ts +15 -64
  57. package/dist/device/meter.d.ts.map +1 -1
  58. package/dist/device/meter.js +223 -638
  59. package/dist/device/meter.js.map +1 -1
  60. package/dist/device/meterplus.d.ts +15 -65
  61. package/dist/device/meterplus.d.ts.map +1 -1
  62. package/dist/device/meterplus.js +216 -644
  63. package/dist/device/meterplus.js.map +1 -1
  64. package/dist/device/motion.d.ts +12 -69
  65. package/dist/device/motion.d.ts.map +1 -1
  66. package/dist/device/motion.js +209 -588
  67. package/dist/device/motion.js.map +1 -1
  68. package/dist/device/plug.d.ts +10 -57
  69. package/dist/device/plug.d.ts.map +1 -1
  70. package/dist/device/plug.js +141 -532
  71. package/dist/device/plug.js.map +1 -1
  72. package/dist/device/robotvacuumcleaner.d.ts +13 -63
  73. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  74. package/dist/device/robotvacuumcleaner.js +252 -609
  75. package/dist/device/robotvacuumcleaner.js.map +1 -1
  76. package/dist/device/waterdetector.d.ts +11 -63
  77. package/dist/device/waterdetector.d.ts.map +1 -1
  78. package/dist/device/waterdetector.js +179 -521
  79. package/dist/device/waterdetector.js.map +1 -1
  80. package/dist/homebridge-ui/public/index.html +22 -16
  81. package/dist/homebridge-ui/server.js +1 -1
  82. package/dist/homebridge-ui/server.js.map +1 -1
  83. package/dist/index.d.ts +1 -1
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +2 -2
  86. package/dist/index.js.map +1 -1
  87. package/dist/irdevice/airconditioner.d.ts +10 -50
  88. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  89. package/dist/irdevice/airconditioner.js +337 -482
  90. package/dist/irdevice/airconditioner.js.map +1 -1
  91. package/dist/irdevice/airpurifier.d.ts +8 -39
  92. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  93. package/dist/irdevice/airpurifier.js +108 -333
  94. package/dist/irdevice/airpurifier.js.map +1 -1
  95. package/dist/irdevice/camera.d.ts +7 -36
  96. package/dist/irdevice/camera.d.ts.map +1 -1
  97. package/dist/irdevice/camera.js +47 -299
  98. package/dist/irdevice/camera.js.map +1 -1
  99. package/dist/irdevice/fan.d.ts +7 -43
  100. package/dist/irdevice/fan.d.ts.map +1 -1
  101. package/dist/irdevice/fan.js +95 -364
  102. package/dist/irdevice/fan.js.map +1 -1
  103. package/dist/irdevice/irdevice.d.ts +46 -0
  104. package/dist/irdevice/irdevice.d.ts.map +1 -0
  105. package/dist/irdevice/irdevice.js +393 -0
  106. package/dist/irdevice/irdevice.js.map +1 -0
  107. package/dist/irdevice/light.d.ts +12 -45
  108. package/dist/irdevice/light.d.ts.map +1 -1
  109. package/dist/irdevice/light.js +121 -376
  110. package/dist/irdevice/light.js.map +1 -1
  111. package/dist/irdevice/other.d.ts +19 -48
  112. package/dist/irdevice/other.d.ts.map +1 -1
  113. package/dist/irdevice/other.js +441 -584
  114. package/dist/irdevice/other.js.map +1 -1
  115. package/dist/irdevice/tv.d.ts +8 -40
  116. package/dist/irdevice/tv.d.ts.map +1 -1
  117. package/dist/irdevice/tv.js +94 -353
  118. package/dist/irdevice/tv.js.map +1 -1
  119. package/dist/irdevice/vacuumcleaner.d.ts +7 -36
  120. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  121. package/dist/irdevice/vacuumcleaner.js +48 -299
  122. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  123. package/dist/irdevice/waterheater.d.ts +7 -36
  124. package/dist/irdevice/waterheater.d.ts.map +1 -1
  125. package/dist/irdevice/waterheater.js +50 -305
  126. package/dist/irdevice/waterheater.js.map +1 -1
  127. package/dist/platform.d.ts +22 -8
  128. package/dist/platform.d.ts.map +1 -1
  129. package/dist/platform.js +342 -191
  130. package/dist/platform.js.map +1 -1
  131. package/dist/settings.d.ts +66 -18
  132. package/dist/settings.d.ts.map +1 -1
  133. package/dist/settings.js +16 -552
  134. package/dist/settings.js.map +1 -1
  135. package/dist/utils.d.ts +95 -0
  136. package/dist/utils.d.ts.map +1 -1
  137. package/dist/utils.js +657 -1
  138. package/dist/utils.js.map +1 -1
  139. package/eslint.config.js +96 -0
  140. package/package.json +20 -16
  141. package/src/custom.d.ts +2 -1
  142. package/src/device/blindtilt.ts +488 -937
  143. package/src/device/bot.ts +907 -1016
  144. package/src/device/ceilinglight.ts +330 -798
  145. package/src/device/colorbulb.ts +394 -904
  146. package/src/device/contact.ts +298 -637
  147. package/src/device/curtain.ts +496 -954
  148. package/src/device/device.ts +872 -0
  149. package/src/device/fan.ts +692 -0
  150. package/src/device/hub.ts +338 -671
  151. package/src/device/humidifier.ts +330 -777
  152. package/src/device/iosensor.ts +258 -671
  153. package/src/device/lightstrip.ts +394 -809
  154. package/src/device/lock.ts +345 -700
  155. package/src/device/meter.ts +256 -666
  156. package/src/device/meterplus.ts +248 -672
  157. package/src/device/motion.ts +234 -622
  158. package/src/device/plug.ts +152 -572
  159. package/src/device/robotvacuumcleaner.ts +273 -653
  160. package/src/device/waterdetector.ts +198 -549
  161. package/src/homebridge-ui/public/index.html +22 -16
  162. package/src/homebridge-ui/server.ts +1 -1
  163. package/src/index.ts +4 -3
  164. package/src/irdevice/airconditioner.ts +368 -540
  165. package/src/irdevice/airpurifier.ts +134 -369
  166. package/src/irdevice/camera.ts +60 -324
  167. package/src/irdevice/fan.ts +111 -392
  168. package/src/irdevice/irdevice.ts +406 -0
  169. package/src/irdevice/light.ts +159 -425
  170. package/src/irdevice/other.ts +509 -661
  171. package/src/irdevice/tv.ts +123 -388
  172. package/src/irdevice/vacuumcleaner.ts +61 -324
  173. package/src/irdevice/waterheater.ts +63 -333
  174. package/src/platform.ts +395 -259
  175. package/src/settings.ts +120 -610
  176. package/src/utils.ts +661 -1
  177. package/src/device/waterdetector.json +0 -11
@@ -1,152 +1,108 @@
1
- import { request } from 'undici';
2
- import { sleep } from '../utils.js';
1
+ /* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
2
+ *
3
+ * blindtilt.ts: @switchbot/homebridge-switchbot.
4
+ */
5
+ import { deviceBase } from './device.js';
3
6
  import { interval, Subject } from 'rxjs';
4
- import { SwitchBotPlatform } from '../platform.js';
7
+ import { hs2rgb, rgb2hs, m2hs } from '../utils.js';
5
8
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
6
- import { device, devicesConfig, deviceStatus, hs2rgb, rgb2hs, m2hs, serviceData, Devices, SwitchBotPlatformConfig } from '../settings.js';
7
- import {
8
- Service, PlatformAccessory, CharacteristicValue, ControllerConstructor, Controller, ControllerServiceMap, API, Logging, HAP,
9
- } from 'homebridge';
9
+
10
+ import type { SwitchBotPlatform } from '../platform.js';
11
+ import type { device, devicesConfig, serviceData, deviceStatus } from '../settings.js';
12
+ import type { Service, PlatformAccessory, CharacteristicValue, ControllerConstructor, Controller, ControllerServiceMap } from 'homebridge';
10
13
 
11
14
  /**
12
15
  * Platform Accessory
13
16
  * An instance of this class is created for each accessory your platform registers
14
17
  * Each accessory may expose multiple services of different service types.
15
18
  */
16
- export class ColorBulb {
17
- public readonly api: API;
18
- public readonly log: Logging;
19
- public readonly config!: SwitchBotPlatformConfig;
20
- protected readonly hap: HAP;
19
+ export class ColorBulb extends deviceBase {
21
20
  // Services
22
- lightBulbService!: Service;
23
-
24
- // Characteristic Values
25
- On!: CharacteristicValue;
26
- Hue!: CharacteristicValue;
27
- Saturation!: CharacteristicValue;
28
- Brightness!: CharacteristicValue;
29
- FirmwareRevision!: CharacteristicValue;
30
- ColorTemperature?: CharacteristicValue;
31
-
32
- // OpenAPI Status
33
- OpenAPI_On: deviceStatus['power'];
34
- OpenAPI_RGB: deviceStatus['color'];
35
- OpenAPI_Brightness: deviceStatus['brightness'];
36
- OpenAPI_FirmwareRevision: deviceStatus['version'];
37
- OpenAPI_ColorTemperature?: deviceStatus['colorTemperature'];
38
-
39
- // BLE Status
40
- BLE_ColorTemperature: serviceData['color_temperature'];
41
- BLE_Power: serviceData['power'];
42
- BLE_Red: serviceData['red'];
43
- BLE_Blue: serviceData['blue'];
44
- BLE_Green: serviceData['green'];
45
- BLE_On: serviceData['state'];
46
- BLE_Delay: serviceData['delay'];
47
- BLE_WifiRssi: serviceData['wifiRssi'];
48
- BLE_Brightness: serviceData['brightness'];
49
- BLE_Saturation;
50
- BLE_Hue;
51
-
52
- // BLE Others
53
- BLE_IsConnected?: boolean;
54
-
55
- // Config
56
- set_minStep?: number;
57
- scanDuration!: number;
58
- deviceLogging!: string;
59
- deviceRefreshRate!: number;
60
- adaptiveLightingShift?: number;
21
+ private LightBulb: {
22
+ Name: CharacteristicValue;
23
+ Service: Service;
24
+ On: CharacteristicValue;
25
+ Hue: CharacteristicValue;
26
+ Saturation: CharacteristicValue;
27
+ Brightness: CharacteristicValue;
28
+ ColorTemperature?: CharacteristicValue;
29
+ };
61
30
 
62
31
  // Adaptive Lighting
63
32
  AdaptiveLightingController?: ControllerConstructor | Controller<ControllerServiceMap>;
64
- minKelvin!: number;
65
- maxKelvin!: number;
66
-
67
- // Others
68
- cacheKelvin!: number;
33
+ adaptiveLightingShift?: number;
69
34
 
70
35
  // Updates
71
36
  colorBulbUpdateInProgress!: boolean;
72
37
  doColorBulbUpdate!: Subject<void>;
73
38
 
74
- // Connection
75
- private readonly OpenAPI: boolean;
76
- private readonly BLE: boolean;
77
-
78
39
  constructor(
79
- private readonly platform: SwitchBotPlatform,
80
- private accessory: PlatformAccessory,
81
- public device: device & devicesConfig,
40
+ readonly platform: SwitchBotPlatform,
41
+ accessory: PlatformAccessory,
42
+ device: device & devicesConfig,
82
43
  ) {
83
- this.api = this.platform.api;
84
- this.log = this.platform.log;
85
- this.config = this.platform.config;
86
- this.hap = this.api.hap;
87
- // Connection
88
- this.BLE = this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI';
89
- this.OpenAPI = this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI';
44
+ super(platform, accessory, device);
90
45
  // default placeholders
91
- this.deviceLogs(device);
92
- this.scan(device);
93
- this.refreshRate(device);
94
46
  this.adaptiveLighting(device);
95
- this.deviceContext();
96
- this.deviceConfig(device);
97
47
 
98
48
  // this is subject we use to track when we need to POST changes to the SwitchBot API
99
49
  this.doColorBulbUpdate = new Subject();
100
50
  this.colorBulbUpdateInProgress = false;
101
51
 
102
- // Retrieve initial values and updateHomekit
103
- this.refreshStatus();
104
-
105
- // set accessory information
106
- accessory
107
- .getService(this.hap.Service.AccessoryInformation)!
108
- .setCharacteristic(this.hap.Characteristic.Manufacturer, 'SwitchBot')
109
- .setCharacteristic(this.hap.Characteristic.Model, 'W1401400')
110
- .setCharacteristic(this.hap.Characteristic.SerialNumber, device.deviceId)
111
- .setCharacteristic(this.hap.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision);
112
-
113
- // get the Lightbulb service if it exists, otherwise create a new Lightbulb service
114
- // you can create multiple services for each accessory
115
- const lightBulbService = `${accessory.displayName} ${device.deviceType}`;
116
- (this.lightBulbService = accessory.getService(this.hap.Service.Lightbulb)
117
- || accessory.addService(this.hap.Service.Lightbulb)), lightBulbService;
118
-
119
- if (this.adaptiveLightingShift === -1 && this.accessory.context.adaptiveLighting) {
120
- this.accessory.removeService(this.lightBulbService);
121
- this.lightBulbService = this.accessory.addService(this.hap.Service.Lightbulb);
122
- this.accessory.context.adaptiveLighting = false;
123
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLighting: ${this.accessory.context.adaptiveLighting}`);
52
+ // Initialize LightBulb property
53
+ accessory.context.LightBulb = accessory.context.LightBulb ?? {};
54
+ this.LightBulb = {
55
+ Name: accessory.context.LightBulb.Name ?? accessory.displayName,
56
+ Service: accessory.getService(this.hap.Service.Lightbulb) ?? accessory.addService(this.hap.Service.Lightbulb) as Service,
57
+ On: accessory.context.On ?? false,
58
+ Hue: accessory.context.Hue ?? 0,
59
+ Saturation: accessory.context.Saturation ?? 0,
60
+ Brightness: accessory.context.Brightness ?? 0,
61
+ ColorTemperature: accessory.context.ColorTemperature ?? 140,
62
+ };
63
+ accessory.context.LightBulb = this.LightBulb as object;
64
+
65
+ // Adaptive Lighting
66
+ if (this.adaptiveLightingShift === -1 && accessory.context.adaptiveLighting) {
67
+ accessory.removeService(this.LightBulb.Service);
68
+ this.LightBulb.Service = accessory.addService(this.hap.Service.Lightbulb);
69
+ accessory.context.adaptiveLighting = false;
70
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} adaptiveLighting: ${accessory.context.adaptiveLighting}`);
124
71
  }
125
-
126
- this.lightBulbService.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
127
- if (!this.lightBulbService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
128
- this.lightBulbService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
72
+ if (this.adaptiveLightingShift !== -1) {
73
+ this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.LightBulb.Service, {
74
+ customTemperatureAdjustment: this.adaptiveLightingShift,
75
+ });
76
+ accessory.configureController(this.AdaptiveLightingController);
77
+ accessory.context.adaptiveLighting = true;
78
+ this.debugLog(`${device.deviceType}: ${this.accessory.displayName} adaptiveLighting: ${accessory.context.adaptiveLighting},`
79
+ + ` adaptiveLightingShift: ${this.adaptiveLightingShift}`);
129
80
  }
81
+ this.debugLog(`${device.deviceType}: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
130
82
 
131
- // handle on / off events using the On characteristic
132
- this.lightBulbService.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
83
+ // Initialize LightBulb Characteristics
84
+ this.LightBulb.Service
85
+ .setCharacteristic(this.hap.Characteristic.Name, this.LightBulb.Name)
86
+ .getCharacteristic(this.hap.Characteristic.On)
87
+ .onGet(() => {
88
+ return this.LightBulb.On;
89
+ })
90
+ .onSet(this.OnSet.bind(this));
133
91
 
134
- // handle Brightness events using the Brightness characteristic
135
- this.lightBulbService
92
+ this.LightBulb.Service
136
93
  .getCharacteristic(this.hap.Characteristic.Brightness)
137
94
  .setProps({
138
- minStep: this.minStep(device),
95
+ minStep: device.colorbulb?.set_minStep ?? 1,
139
96
  minValue: 0,
140
97
  maxValue: 100,
141
98
  validValueRanges: [0, 100],
142
99
  })
143
100
  .onGet(() => {
144
- return this.Brightness;
101
+ return this.LightBulb.Brightness;
145
102
  })
146
103
  .onSet(this.BrightnessSet.bind(this));
147
104
 
148
- // handle ColorTemperature events using the ColorTemperature characteristic
149
- this.lightBulbService
105
+ this.LightBulb.Service
150
106
  .getCharacteristic(this.hap.Characteristic.ColorTemperature)
151
107
  .setProps({
152
108
  minValue: 140,
@@ -154,12 +110,11 @@ export class ColorBulb {
154
110
  validValueRanges: [140, 500],
155
111
  })
156
112
  .onGet(() => {
157
- return this.ColorTemperature!;
113
+ return this.LightBulb.ColorTemperature!;
158
114
  })
159
115
  .onSet(this.ColorTemperatureSet.bind(this));
160
116
 
161
- // handle Hue events using the Hue characteristic
162
- this.lightBulbService
117
+ this.LightBulb.Service
163
118
  .getCharacteristic(this.hap.Characteristic.Hue)
164
119
  .setProps({
165
120
  minValue: 0,
@@ -167,12 +122,11 @@ export class ColorBulb {
167
122
  validValueRanges: [0, 360],
168
123
  })
169
124
  .onGet(() => {
170
- return this.Hue;
125
+ return this.LightBulb.Hue;
171
126
  })
172
127
  .onSet(this.HueSet.bind(this));
173
128
 
174
- // handle Hue events using the Hue characteristic
175
- this.lightBulbService
129
+ this.LightBulb.Service
176
130
  .getCharacteristic(this.hap.Characteristic.Saturation)
177
131
  .setProps({
178
132
  minValue: 0,
@@ -180,22 +134,12 @@ export class ColorBulb {
180
134
  validValueRanges: [0, 100],
181
135
  })
182
136
  .onGet(() => {
183
- return this.Saturation;
137
+ return this.LightBulb.Saturation;
184
138
  })
185
139
  .onSet(this.SaturationSet.bind(this));
186
140
 
187
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
188
- if (this.adaptiveLightingShift !== -1) {
189
- this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.lightBulbService, {
190
- customTemperatureAdjustment: this.adaptiveLightingShift,
191
- });
192
- this.accessory.configureController(this.AdaptiveLightingController);
193
- this.accessory.context.adaptiveLighting = true;
194
- this.debugLog(
195
- `${this.device.deviceType}: ${this.accessory.displayName} adaptiveLighting: ${this.accessory.context.adaptiveLighting},` +
196
- ` adaptiveLightingShift: ${this.adaptiveLightingShift}`,
197
- );
198
- }
141
+ // Retrieve initial values and updateHomekit
142
+ this.refreshStatus();
199
143
 
200
144
  // Update Homekit
201
145
  this.updateHomeKitCharacteristics();
@@ -208,60 +152,7 @@ export class ColorBulb {
208
152
  });
209
153
 
210
154
  //regisiter webhook event handler
211
- if (this.device.webhook) {
212
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} is listening webhook.`);
213
- this.platform.webhookEventHandler[this.device.deviceId] = async (context) => {
214
- try {
215
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
216
- const { powerState, brightness, color, colorTemperature } = context;
217
- const { On, Brightness, Hue, Saturation, ColorTemperature } = this;
218
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
219
- '(powerState, brightness, color, colorTemperature) = ' +
220
- `Webhook:(${powerState}, ${brightness}, ${color}, ${colorTemperature}), ` +
221
- `current:(${On}, ${Brightness}, ${Hue}, ${Saturation}, ${ColorTemperature})`);
222
- this.On = powerState === 'ON' ? true : false;
223
- this.Brightness = brightness;
224
-
225
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} color: ${JSON.stringify(color)}`);
226
- const [red, green, blue] = color!.split(':');
227
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} red: ${JSON.stringify(red)}`);
228
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} green: ${JSON.stringify(green)}`);
229
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} blue: ${JSON.stringify(blue)}`);
230
-
231
- const [hue, saturation] = rgb2hs(Number(red), Number(green), Number(blue));
232
- this.debugLog(
233
- `${this.device.deviceType}: ${this.accessory.displayName}` + ` hs: ${JSON.stringify(rgb2hs(Number(red), Number(green), Number(blue)))}`,
234
- );
235
-
236
- // Hue
237
- this.Hue = hue;
238
- if (this.accessory.context.Hue !== this.Hue) {
239
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.Hue}`);
240
- } else {
241
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.Hue}`);
242
- }
243
-
244
- // Saturation
245
- this.Saturation = saturation;
246
- if (this.accessory.context.Saturation !== this.Saturation) {
247
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
248
- } else {
249
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
250
- }
251
-
252
- this.ColorTemperature = colorTemperature;
253
- if (this.accessory.context.ColorTemperature !== this.ColorTemperature) {
254
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
255
- } else {
256
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
257
- }
258
- this.updateHomeKitCharacteristics();
259
- } catch (e: any) {
260
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
261
- + `failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
262
- }
263
- };
264
- }
155
+ this.registerWebhook(accessory, device);
265
156
 
266
157
  // Watch for Bulb change events
267
158
  // We put in a debounce of 100ms so we don't make duplicate calls
@@ -270,138 +161,130 @@ export class ColorBulb {
270
161
  tap(() => {
271
162
  this.colorBulbUpdateInProgress = true;
272
163
  }),
273
- debounceTime(this.platform.config.options!.pushRate! * 1000),
164
+ debounceTime(this.devicePushRate * 1000),
274
165
  )
275
166
  .subscribe(async () => {
276
167
  try {
277
168
  await this.pushChanges();
278
169
  } catch (e: any) {
279
170
  this.apiError(e);
280
- this.errorLog(
281
- `${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,` +
282
- ` Error Message: ${JSON.stringify(e.message)}`,
283
- );
171
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
172
+ + ` Error Message: ${JSON.stringify(e.message)}`);
284
173
  }
285
174
  this.colorBulbUpdateInProgress = false;
286
175
  });
287
176
  }
288
177
 
289
178
  /**
290
- * Parse the device status from the SwitchBot api
179
+ * Parse the device status from the SwitchBotBLE API
291
180
  */
292
- async parseStatus(): Promise<void> {
293
- if (!this.device.enableCloudService && this.OpenAPI) {
294
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} parseStatus enableCloudService: ${this.device.enableCloudService}`);
295
- } else if (this.BLE) {
296
- await this.BLEparseStatus();
297
- } else if (this.OpenAPI && this.platform.config.credentials?.token) {
298
- await this.openAPIparseStatus();
299
- } else {
300
- await this.offlineOff();
301
- this.debugWarnLog(
302
- `${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` + ` ${this.device.connectionType}, parseStatus will not happen.`,
303
- );
304
- }
305
- }
306
-
307
- async BLEparseStatus(): Promise<void> {
181
+ async BLEparseStatus(serviceData: serviceData): Promise<void> {
308
182
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
309
183
  // State
310
- switch (this.BLE_On) {
184
+ switch (serviceData.power) {
311
185
  case true:
312
- this.On = true;
186
+ this.LightBulb.On = true;
313
187
  break;
314
188
  default:
315
- this.On = false;
189
+ this.LightBulb.On = false;
316
190
  }
317
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
191
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LightBulb.On}`);
318
192
 
319
193
  // Brightness
320
- this.Brightness = Number(this.BLE_Brightness);
321
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
194
+ this.LightBulb.Brightness = Number(serviceData.brightness);
195
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.LightBulb.Brightness}`);
322
196
 
323
197
  // Color, Hue & Brightness
324
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} red: ${this.BLE_Red}`);
325
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} green: ${this.BLE_Green}`);
326
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} blue: ${this.BLE_Blue}`);
327
-
328
- const [hue, saturation] = rgb2hs(Number(this.BLE_Red), Number(this.BLE_Green), Number(this.BLE_Blue));
329
- this.debugLog(
330
- `${this.device.deviceType}: ${this.accessory.displayName}` +
331
- ` hs: ${JSON.stringify(rgb2hs(Number(this.BLE_Red), Number(this.BLE_Green), Number(this.BLE_Blue)))}`,
332
- );
333
- this.BLE_Hue = hue;
334
- this.BLE_Saturation = saturation;
198
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} red: ${serviceData.red}`);
199
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} green: ${serviceData.green}`);
200
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} blue: ${serviceData.blue}`);
201
+
202
+ const [hue, saturation] = rgb2hs(Number(serviceData.red), Number(serviceData.green), Number(serviceData.blue));
203
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
204
+ + ` hs: ${JSON.stringify(rgb2hs(Number(serviceData.red), Number(serviceData.green), Number(serviceData.blue)))}`);
335
205
 
336
206
  // Hue
337
- this.Hue = this.BLE_Hue;
338
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.Hue}`);
207
+ this.LightBulb.Hue = hue;
208
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.LightBulb.Hue}`);
339
209
 
340
210
  // Saturation
341
- this.Saturation = this.BLE_Saturation;
342
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
211
+ this.LightBulb.Saturation = saturation;
212
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${this.LightBulb.Saturation}`);
343
213
 
344
214
  // ColorTemperature
345
- if (this.BLE_ColorTemperature) {
346
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.BLE_ColorTemperature}`);
347
- this.ColorTemperature = this.BLE_ColorTemperature!;
215
+ if (serviceData.color_temperature) {
216
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${serviceData.color_temperature}`);
217
+ this.LightBulb.ColorTemperature = serviceData.color_temperature!;
348
218
 
349
- this.ColorTemperature = Math.max(Math.min(this.ColorTemperature, 500), 140);
350
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
219
+ this.LightBulb.ColorTemperature = Math.max(Math.min(this.LightBulb.ColorTemperature, 500), 140);
220
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.LightBulb.ColorTemperature}`);
351
221
  }
352
222
  }
353
223
 
354
- async openAPIparseStatus() {
224
+ /**
225
+ * Parse the device status from the SwitchBot OpenAPI
226
+ */
227
+ async openAPIparseStatus(deviceStatus: deviceStatus): Promise<void> {
355
228
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
356
- switch (this.OpenAPI_On) {
229
+ switch (deviceStatus.body.power) {
357
230
  case 'on':
358
- this.On = true;
231
+ this.LightBulb.On = true;
359
232
  break;
360
233
  default:
361
- this.On = false;
234
+ this.LightBulb.On = false;
362
235
  }
363
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
236
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LightBulb.On}`);
364
237
 
365
238
  // Brightness
366
- this.Brightness = Number(this.OpenAPI_Brightness);
367
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
239
+ this.LightBulb.Brightness = Number(deviceStatus.body.brightness);
240
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.LightBulb.Brightness}`);
368
241
 
369
242
  // Color, Hue & Brightness
370
- if (this.OpenAPI_RGB) {
371
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} color: ${JSON.stringify(this.OpenAPI_RGB)}`);
372
- const [red, green, blue] = this.OpenAPI_RGB!.split(':');
243
+ if (deviceStatus.body.color) {
244
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} color: ${JSON.stringify(deviceStatus.body.color)}`);
245
+ const [red, green, blue] = deviceStatus.body.color!.split(':');
373
246
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} red: ${JSON.stringify(red)}`);
374
247
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} green: ${JSON.stringify(green)}`);
375
248
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} blue: ${JSON.stringify(blue)}`);
376
249
 
377
250
  const [hue, saturation] = rgb2hs(Number(red), Number(green), Number(blue));
378
- this.debugLog(
379
- `${this.device.deviceType}: ${this.accessory.displayName}` + ` hs: ${JSON.stringify(rgb2hs(Number(red), Number(green), Number(blue)))}`,
380
- );
251
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
252
+ + ` hs: ${JSON.stringify(rgb2hs(Number(red), Number(green), Number(blue)))}`);
381
253
 
382
254
  // Hue
383
- this.Hue = hue;
384
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.Hue}`);
255
+ this.LightBulb.Hue = hue;
256
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.LightBulb.Hue}`);
385
257
 
386
258
  // Saturation
387
- this.Saturation = saturation;
388
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
259
+ this.LightBulb.Saturation = saturation;
260
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${this.LightBulb.Saturation}`);
389
261
  }
390
262
 
391
263
  // ColorTemperature
392
- if (!Number.isNaN(this.OpenAPI_ColorTemperature)) {
393
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.OpenAPI_ColorTemperature}`);
394
- const mired = Math.round(1000000 / this.OpenAPI_ColorTemperature!);
264
+ if (!Number.isNaN(deviceStatus.body.colorTemperature)) {
265
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${deviceStatus.body.colorTemperature}`);
266
+ const mired = Math.round(1000000 / deviceStatus.body.colorTemperature!);
395
267
 
396
- this.ColorTemperature = Number(mired);
268
+ this.LightBulb.ColorTemperature = Number(mired);
397
269
 
398
- this.ColorTemperature = Math.max(Math.min(this.ColorTemperature, 500), 140);
399
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
270
+ this.LightBulb.ColorTemperature = Math.max(Math.min(this.LightBulb.ColorTemperature, 500), 140);
271
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.LightBulb.ColorTemperature}`);
400
272
  }
401
273
 
402
- // FirmwareRevision
403
- this.FirmwareRevision = this.OpenAPI_FirmwareRevision!;
404
- this.accessory.context.FirmwareRevision = this.FirmwareRevision;
274
+ // Firmware Version
275
+ const version = deviceStatus.body.version?.toString();
276
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
277
+ if (deviceStatus.body.version) {
278
+ const deviceVersion = version?.replace(/^V|-.*$/g, '') ?? '0.0.0';
279
+ this.accessory
280
+ .getService(this.hap.Service.AccessoryInformation)!
281
+ .setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
282
+ .setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
283
+ .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
284
+ .updateValue(deviceVersion);
285
+ this.accessory.context.deviceVersion = deviceVersion;
286
+ this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceVersion: ${this.accessory.context.deviceVersion}`);
287
+ }
405
288
  }
406
289
 
407
290
  /**
@@ -416,144 +299,124 @@ export class ColorBulb {
416
299
  await this.openAPIRefreshStatus();
417
300
  } else {
418
301
  await this.offlineOff();
419
- this.debugWarnLog(
420
- `${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` +
421
- ` ${this.device.connectionType}, refreshStatus will not happen.`,
422
- );
302
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
303
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
423
304
  }
424
305
  }
425
306
 
426
307
  async BLERefreshStatus(): Promise<void> {
427
308
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
428
- const switchbot = await this.platform.connectBLE();
429
- // Convert to BLE Address
430
- this.device.bleMac = this.device
431
- .deviceId!.match(/.{1,2}/g)!
432
- .join(':')
433
- .toLowerCase();
434
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
435
- this.getCustomBLEAddress(switchbot);
309
+ const switchbot = await this.switchbotBLE();
310
+
311
+ if (switchbot === undefined) {
312
+ await this.BLERefreshConnection(switchbot);
313
+ } else {
436
314
  // Start to monitor advertisement packets
437
- (async () => {
315
+ (async () => {
438
316
  // Start to monitor advertisement packets
439
- await switchbot.startScan({
440
- model: 'u',
441
- id: this.device.bleMac,
442
- });
443
- // Set an event handler
444
- switchbot.onadvertisement = (ad: any) => {
445
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
446
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.serviceData.model}`);
447
- if (this.device.bleMac === ad.address && ad.serviceData.model === 'u') {
448
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
449
- this.BLE_ColorTemperature = ad.serviceData.color_temperature;
450
- this.BLE_Power = ad.serviceData.power;
451
- this.BLE_On = ad.serviceData.state;
452
- this.BLE_Red = ad.serviceData.red;
453
- this.BLE_Green = ad.serviceData.green;
454
- this.BLE_Blue = ad.serviceData.blue;
455
- this.BLE_Brightness = ad.serviceData.brightness;
456
- this.BLE_Delay = ad.serviceData.delay;
317
+ const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
318
+ // Update HomeKit
319
+ if (serviceData.model !== '' && serviceData.modelName !== '') {
320
+ await this.BLEparseStatus(serviceData);
321
+ await this.updateHomeKitCharacteristics();
457
322
  } else {
458
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
459
- }
460
- };
461
- // Wait 1 seconds
462
- await switchbot.wait(this.scanDuration * 1000);
463
- // Stop to monitor
464
- await switchbot.stopScan();
465
- // Update HomeKit
466
- await this.BLEparseStatus();
467
- await this.updateHomeKitCharacteristics();
468
- })();
469
- /*if (switchbot !== false) {
470
- switchbot
471
- .startScan({
472
- model: 'u',
473
- id: this.device.bleMac,
474
- })
475
- .then(async () => {
476
- // Set an event handler
477
- switchbot.onadvertisement = async (ad: ad) => {
478
- this.debugLog(
479
- `${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},` +
480
- ` BLE Address Found: ${ad.address}`,
481
- );
482
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
483
- this.BLE_Power = ad.serviceData.power;
484
- this.BLE_On = ad.serviceData.state;
485
- this.BLE_Red = ad.serviceData.red;
486
- this.BLE_Green = ad.serviceData.green;
487
- this.BLE_Blue = ad.serviceData.blue;
488
- this.BLE_ColorTemperature = ad.serviceData.color_temperature;
489
- this.BLE_Brightness = ad.serviceData.brightness;
490
- this.BLE_Delay = ad.serviceData.delay;
491
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
492
- this.debugLog(
493
- `${this.device.deviceType}: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
494
- `delay: ${ad.serviceData.delay}, timer: ${ad.serviceData.timer}, syncUtcTime: ${ad.serviceData.syncUtcTime} ` +
495
- `wifiRssi: ${ad.serviceData.wifiRssi}, overload: ${ad.serviceData.overload}, currentPower: ${ad.serviceData.currentPower}`,
496
- );
497
-
498
- if (ad.serviceData) {
499
- this.BLE_IsConnected = true;
500
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
501
- await this.stopScanning(switchbot);
502
- } else {
503
- this.BLE_IsConnected = false;
504
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
505
- }
506
- };
507
- // Wait
508
- return await sleep(this.scanDuration * 1000);
509
- })
510
- .then(async () => {
511
- // Stop to monitor
512
- await this.stopScanning(switchbot);
513
- })
514
- .catch(async (e: any) => {
515
- this.apiError(e);
516
- this.errorLog(
517
- `${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}` +
518
- ` Connection, Error Message: ${JSON.stringify(e.message)}`,
519
- );
323
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
520
324
  await this.BLERefreshConnection(switchbot);
521
- });
522
- } else {
523
- await this.BLERefreshConnection(switchbot);
524
- }*/
325
+ }
326
+ })();
327
+ }
525
328
  }
526
329
 
527
- async openAPIRefreshStatus() {
330
+ async openAPIRefreshStatus(): Promise<void> {
528
331
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
529
332
  try {
530
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
531
- headers: this.platform.generateHeaders(),
532
- });
533
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
333
+ const { body, statusCode } = await this.deviceRefreshStatus();
534
334
  const deviceStatus: any = await body.json();
535
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
536
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
335
+ await this.refreshStatusCodes(statusCode, deviceStatus);;
537
336
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
538
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
539
- + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
540
- this.OpenAPI_On = deviceStatus.body.power;
541
- this.OpenAPI_RGB = deviceStatus.body.color;
542
- this.OpenAPI_Brightness = deviceStatus.body.brightness;
543
- this.OpenAPI_ColorTemperature = deviceStatus.body.colorTemperature;
544
- this.OpenAPI_FirmwareRevision = deviceStatus.body.version;
545
- this.openAPIparseStatus();
546
- this.updateHomeKitCharacteristics();
337
+ await this.successfulRefreshStatus(statusCode, deviceStatus);
338
+ await this.openAPIparseStatus(deviceStatus);
339
+ await this.updateHomeKitCharacteristics();
547
340
  } else {
548
- this.statusCode(statusCode);
549
- this.statusCode(deviceStatus.statusCode);
341
+ await this.statusCodes(statusCode, deviceStatus);
550
342
  }
551
343
  } catch (e: any) {
552
344
  this.apiError(e);
553
- this.errorLog(
554
- `${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}` +
555
- ` Connection, Error Message: ${JSON.stringify(e.message)}`,
556
- );
345
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
346
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
347
+ }
348
+ }
349
+
350
+ async registerWebhook(accessory: PlatformAccessory, device: device & devicesConfig) {
351
+ if (device.webhook) {
352
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
353
+ this.platform.webhookEventHandler[device.deviceId] = async (context) => {
354
+ try {
355
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
356
+ const { powerState, brightness, color, colorTemperature } = context;
357
+ const { On, Brightness, Hue, Saturation, ColorTemperature } = this.LightBulb;
358
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} ` +
359
+ '(powerState, brightness, color, colorTemperature) = ' +
360
+ `Webhook:(${powerState}, ${brightness}, ${color}, ${colorTemperature}), `
361
+ + `current:(${On}, ${Brightness}, ${Hue}, ${Saturation}, ${ColorTemperature})`);
362
+
363
+ // On
364
+ this.LightBulb.On = powerState === 'ON' ? true : false;
365
+ if (accessory.context.Brightness !== this.LightBulb.On) {
366
+ this.infoLog(`${device.deviceType}: ${accessory.displayName} On: ${this.LightBulb.On}`);
367
+ } else {
368
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} On: ${this.LightBulb.On}`);
369
+ }
370
+
371
+ // Brightness
372
+ this.LightBulb.Brightness = brightness;
373
+ if (accessory.context.Brightness !== this.LightBulb.Brightness) {
374
+ this.infoLog(`${device.deviceType}: ${accessory.displayName} Brightness: ${this.LightBulb.Brightness}`);
375
+ } else {
376
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} Brightness: ${this.LightBulb.Brightness}`);
377
+ }
378
+
379
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} color: ${JSON.stringify(color)}`);
380
+ const [red, green, blue] = color!.split(':');
381
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} red: ${JSON.stringify(red)}`);
382
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} green: ${JSON.stringify(green)}`);
383
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} blue: ${JSON.stringify(blue)}`);
384
+
385
+ const [hue, saturation] = rgb2hs(Number(red), Number(green), Number(blue));
386
+ this.debugLog(
387
+ `${device.deviceType}: ${accessory.displayName}`
388
+ + ` hs: ${JSON.stringify(rgb2hs(Number(red), Number(green), Number(blue)))}`);
389
+
390
+ // Hue
391
+ this.LightBulb.Hue = hue;
392
+ if (accessory.context.Hue !== this.LightBulb.Hue) {
393
+ this.infoLog(`${device.deviceType}: ${accessory.displayName} Hue: ${this.LightBulb.Hue}`);
394
+ } else {
395
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} Hue: ${this.LightBulb.Hue}`);
396
+ }
397
+
398
+ // Saturation
399
+ this.LightBulb.Saturation = saturation;
400
+ if (accessory.context.Saturation !== this.LightBulb.Saturation) {
401
+ this.infoLog(`${device.deviceType}: ${accessory.displayName} Saturation: ${this.LightBulb.Saturation}`);
402
+ } else {
403
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} Saturation: ${this.LightBulb.Saturation}`);
404
+ }
405
+
406
+ this.LightBulb.ColorTemperature = colorTemperature;
407
+ if (accessory.context.ColorTemperature !== this.LightBulb.ColorTemperature) {
408
+ this.infoLog(`${device.deviceType}: ${accessory.displayName} ColorTemperature: ${this.LightBulb.ColorTemperature}`);
409
+ } else {
410
+ this.debugLog(`${device.deviceType}: ${accessory.displayName} ColorTemperature: ${this.LightBulb.ColorTemperature}`);
411
+ }
412
+ this.updateHomeKitCharacteristics();
413
+ } catch (e: any) {
414
+ this.errorLog(`${device.deviceType}: ${accessory.displayName} `
415
+ + `failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
416
+ }
417
+ };
418
+ } else {
419
+ this.debugWarnLog(`${device.deviceType}: ${accessory.displayName} is not listening webhook.`);
557
420
  }
558
421
  }
559
422
 
@@ -571,15 +434,14 @@ export class ColorBulb {
571
434
  async pushChanges(): Promise<void> {
572
435
  if (!this.device.enableCloudService && this.OpenAPI) {
573
436
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} pushChanges enableCloudService: ${this.device.enableCloudService}`);
574
- /*} else if (this.BLE) {
575
- await this.BLEpushChanges();*/
437
+ } else if (this.BLE) {
438
+ await this.BLEpushChanges();
576
439
  } else if (this.OpenAPI && this.platform.config.credentials?.token) {
577
440
  await this.openAPIpushChanges();
578
441
  } else {
579
442
  await this.offlineOff();
580
- this.debugWarnLog(
581
- `${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` + ` ${this.device.connectionType}, pushChanges will not happen.`,
582
- );
443
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
444
+ + ` ${this.device.connectionType}, pushChanges will not happen.`);
583
445
  }
584
446
  // Refresh the status from the API
585
447
  interval(15000)
@@ -592,26 +454,20 @@ export class ColorBulb {
592
454
 
593
455
  async BLEpushChanges(): Promise<void> {
594
456
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
595
- if (this.On !== this.accessory.context.On) {
596
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges On: ${this.On} OnCached: ${this.accessory.context.On}`);
457
+ if (this.LightBulb.On !== this.accessory.context.On) {
458
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`
459
+ + ` On: ${this.LightBulb.On}, OnCached: ${this.accessory.context.On}`);
597
460
  const switchbot = await this.platform.connectBLE();
598
461
  // Convert to BLE Address
599
- this.device.bleMac = this.device
600
- .deviceId!.match(/.{1,2}/g)!
601
- .join(':')
602
- .toLowerCase();
603
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
462
+ await this.convertBLEAddress();
604
463
  switchbot
605
- .discover({
606
- model: 'u',
607
- id: this.device.bleMac,
608
- })
464
+ .discover({ model: this.device.bleModel, id: this.device.bleMac })
609
465
  .then(async (device_list: any) => {
610
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
611
- return await this.retry({
612
- max: this.maxRetry(),
466
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LightBulb.On}`);
467
+ return await this.retryBLE({
468
+ max: await this.maxRetryBLE(),
613
469
  fn: async () => {
614
- if (this.On) {
470
+ if (this.LightBulb.On) {
615
471
  return await device_list[0].turnOn({ id: this.device.bleMac });
616
472
  } else {
617
473
  return await device_list[0].turnOff({ id: this.device.bleMac });
@@ -621,164 +477,129 @@ export class ColorBulb {
621
477
  })
622
478
  .then(() => {
623
479
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
624
- this.On = false;
480
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
481
+ + `On: ${this.LightBulb.On} sent over BLE, sent successfully`);
482
+ this.LightBulb.On = false;
625
483
  })
626
484
  .catch(async (e: any) => {
627
485
  this.apiError(e);
628
- this.errorLog(
629
- `${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}` +
630
- ` Connection, Error Message: ${JSON.stringify(e.message)}`,
631
- );
486
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
487
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
632
488
  await this.BLEPushConnection();
633
489
  });
634
490
  // Push Brightness Update
635
- if (this.On) {
491
+ if (this.LightBulb.On) {
636
492
  await this.BLEpushBrightnessChanges();
637
493
  }
638
494
  // Push ColorTemperature Update
639
- if (this.On) {
495
+ if (this.LightBulb.On) {
640
496
  await this.BLEpushColorTemperatureChanges();
641
497
  }
642
498
  // Push Hue & Saturation Update
643
- if (this.On) {
499
+ if (this.LightBulb.On) {
644
500
  await this.BLEpushRGBChanges();
645
501
  }
646
502
  } else {
647
- this.debugLog(
648
- `${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `On: ${this.On}, ` + `OnCached: ${this.accessory.context.On}`,
649
- );
503
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, On: ${this.LightBulb.On},`
504
+ + ` OnCached: ${this.accessory.context.On}`);
650
505
  }
651
506
  }
652
507
 
653
508
  async BLEpushBrightnessChanges(): Promise<void> {
654
509
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushBrightnessChanges`);
655
- if (this.Brightness !== this.accessory.context.Brightness) {
510
+ if (this.LightBulb.Brightness !== this.accessory.context.Brightness) {
656
511
  const switchbot = await this.platform.connectBLE();
657
512
  // Convert to BLE Address
658
- this.device.bleMac = this.device
659
- .deviceId!.match(/.{1,2}/g)!
660
- .join(':')
661
- .toLowerCase();
662
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
513
+ await this.convertBLEAddress();
663
514
  switchbot
664
- .discover({
665
- model: 'u',
666
- id: this.device.bleMac,
667
- })
515
+ .discover({ model: this.device.bleModel, id: this.device.bleMac })
668
516
  .then(async (device_list: any) => {
669
- this.infoLog(`${this.accessory.displayName} Target Brightness: ${this.Brightness}`);
670
- return await device_list[0].setBrightness(this.Brightness);
517
+ this.infoLog(`${this.accessory.displayName} Target Brightness: ${this.LightBulb.Brightness}`);
518
+ return await device_list[0].setBrightness(this.LightBulb.Brightness);
671
519
  })
672
520
  .then(() => {
673
521
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
674
- this.On = false;
522
+ this.LightBulb.On = false;
675
523
  })
676
524
  .catch(async (e: any) => {
677
525
  this.apiError(e);
678
- this.errorLog(
679
- `${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushBrightnessChanges with ${this.device.connectionType}` +
680
- ` Connection, Error Message: ${JSON.stringify(e.message)}`,
681
- );
526
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushBrightnessChanges with ${this.device.connectionType}`
527
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
682
528
  await this.BLEPushConnection();
683
529
  });
684
530
  } else {
685
- this.debugLog(
686
- `${this.device.deviceType}: ${this.accessory.displayName} No BLEpushBrightnessChanges.` +
687
- `Brightness: ${this.Brightness}, ` +
688
- `BrightnessCached: ${this.accessory.context.Brightness}`,
689
- );
531
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushBrightnessChanges.`
532
+ + `Brightness: ${this.LightBulb.Brightness}, BrightnessCached: ${this.accessory.context.Brightness}`);
690
533
  }
691
534
  }
692
535
 
693
536
  async BLEpushColorTemperatureChanges(): Promise<void> {
694
537
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushColorTemperatureChanges`);
695
- if (this.ColorTemperature !== this.accessory.context.ColorTemperature) {
538
+ if (this.LightBulb.ColorTemperature !== this.accessory.context.ColorTemperature) {
696
539
  const switchbot = await this.platform.connectBLE();
697
540
  // Convert to BLE Address
698
- this.device.bleMac = this.device
699
- .deviceId!.match(/.{1,2}/g)!
700
- .join(':')
701
- .toLowerCase();
702
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
541
+ await this.convertBLEAddress();
703
542
  switchbot
704
- .discover({
705
- model: 'u',
706
- id: this.device.bleMac,
707
- })
543
+ .discover({ model: this.device.bleModel, id: this.device.bleMac })
708
544
  .then(async (device_list: any) => {
709
- this.infoLog(`${this.accessory.displayName} Target ColorTemperature: ${this.ColorTemperature}`);
710
- return await device_list[0].setColorTemperature(this.ColorTemperature);
545
+ this.infoLog(`${this.accessory.displayName} Target ColorTemperature: ${this.LightBulb.ColorTemperature}`);
546
+ return await device_list[0].setColorTemperature(this.LightBulb.ColorTemperature);
711
547
  })
712
548
  .then(() => {
713
549
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
714
- this.On = false;
550
+ this.LightBulb.On = false;
715
551
  })
716
552
  .catch(async (e: any) => {
717
553
  this.apiError(e);
718
- this.errorLog(
719
- `${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushColorTemperatureChanges with ` +
720
- `${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`,
721
- );
554
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushColorTemperatureChanges with `
555
+ + `${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`);
722
556
  await this.BLEPushConnection();
723
557
  });
724
558
  } else {
725
- this.debugLog(
726
- `${this.device.deviceType}: ${this.accessory.displayName} No BLEpushColorTemperatureChanges.` +
727
- `ColorTemperature: ${this.ColorTemperature}, ColorTemperatureCached: ${this.accessory.context.ColorTemperature}`,
728
- );
559
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushColorTemperatureChanges.`
560
+ + `ColorTemperature: ${this.LightBulb.ColorTemperature}, ColorTemperatureCached: ${this.accessory.context.ColorTemperature}`);
729
561
  }
730
562
  }
731
563
 
732
564
  async BLEpushRGBChanges(): Promise<void> {
733
565
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushRGBChanges`);
734
- if (this.Hue !== this.accessory.context.Hue || this.Saturation !== this.accessory.context.Saturation) {
735
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${JSON.stringify(this.Hue)}`);
736
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${JSON.stringify(this.Saturation)}`);
566
+ if (this.LightBulb.Hue !== this.accessory.context.Hue || this.LightBulb.Saturation !== this.accessory.context.Saturation) {
567
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${JSON.stringify(this.LightBulb.Hue)}`);
568
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${JSON.stringify(this.LightBulb.Saturation)}`);
737
569
 
738
- const [red, green, blue] = hs2rgb(Number(this.Hue), Number(this.Saturation));
570
+ const [red, green, blue] = hs2rgb(Number(this.LightBulb.Hue), Number(this.LightBulb.Saturation));
739
571
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} rgb: ${JSON.stringify([red, green, blue])}`);
740
572
 
741
573
  const switchbot = await this.platform.connectBLE();
742
574
  // Convert to BLE Address
743
- this.device.bleMac = this.device
744
- .deviceId!.match(/.{1,2}/g)!
745
- .join(':')
746
- .toLowerCase();
747
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
575
+ await this.convertBLEAddress();
748
576
  switchbot
749
- .discover({
750
- model: 'u',
751
- id: this.device.bleMac,
752
- })
577
+ .discover({ model: this.device.bleModel, id: this.device.bleMac })
753
578
  .then(async (device_list: any) => {
754
- this.infoLog(`${this.accessory.displayName} Target RGB: ${(this.Brightness, red, green, blue)}`);
755
- return await device_list[0].setRGB(this.Brightness, red, green, blue);
579
+ this.infoLog(`${this.accessory.displayName} Target RGB: ${(this.LightBulb.Brightness, red, green, blue)}`);
580
+ return await device_list[0].setRGB(this.LightBulb.Brightness, red, green, blue);
756
581
  })
757
582
  .then(() => {
758
583
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
759
- this.On = false;
584
+ this.LightBulb.On = false;
760
585
  })
761
586
  .catch(async (e: any) => {
762
587
  this.apiError(e);
763
- this.errorLog(
764
- `${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushRGBChanges with ${this.device.connectionType}` +
765
- ` Connection, Error Message: ${JSON.stringify(e.message)}`,
766
- );
588
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushRGBChanges with ${this.device.connectionType}`
589
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
767
590
  await this.BLEPushConnection();
768
591
  });
769
592
  } else {
770
- this.debugLog(
771
- `${this.device.deviceType}: ${this.accessory.displayName} No BLEpushRGBChanges. Hue: ${this.Hue}, ` +
772
- `HueCached: ${this.accessory.context.Hue}, Saturation: ${this.Saturation}, SaturationCached: ${this.accessory.context.Saturation}`,
773
- );
593
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushRGBChanges. Hue: ${this.LightBulb.Hue}, HueCached: `
594
+ + `${this.accessory.context.Hue}, Saturation: ${this.LightBulb.Saturation}, SaturationCached: ${this.accessory.context.Saturation}`);
774
595
  }
775
596
  }
776
597
 
777
598
  async openAPIpushChanges(): Promise<void> {
778
599
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
779
- if (this.On !== this.accessory.context.On) {
600
+ if (this.LightBulb.On !== this.accessory.context.On) {
780
601
  let command = '';
781
- if (this.On) {
602
+ if (this.LightBulb.On) {
782
603
  command = 'turnOn';
783
604
  } else {
784
605
  command = 'turnOff';
@@ -790,57 +611,47 @@ export class ColorBulb {
790
611
  });
791
612
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
792
613
  try {
793
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
794
- body: bodyChange,
795
- method: 'POST',
796
- headers: this.platform.generateHeaders(),
797
- });
798
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
614
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
799
615
  const deviceStatus: any = await body.json();
800
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
801
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
802
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
616
+ await this.pushStatusCodes(statusCode, deviceStatus);
803
617
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
804
618
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
805
619
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
620
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
621
+ + `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
806
622
  } else {
807
623
  this.statusCode(statusCode);
808
624
  this.statusCode(deviceStatus.statusCode);
809
625
  }
810
626
  } catch (e: any) {
811
627
  this.apiError(e);
812
- this.errorLog(
813
- `${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}` +
814
- ` Connection, Error Message: ${JSON.stringify(e.message)}`,
815
- );
628
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
629
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
816
630
  }
817
631
  } else {
818
- this.debugLog(
819
- `${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` +
820
- `On: ${this.On}, ` +
821
- `OnCached: ${this.accessory.context.On}`,
822
- );
632
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges,`
633
+ + `On: ${this.LightBulb.On}, OnCached: ${this.accessory.context.On}`);
823
634
  }
824
635
  // Push Hue & Saturation Update
825
- if (this.On) {
636
+ if (this.LightBulb.On) {
826
637
  await this.pushHueSaturationChanges();
827
638
  }
828
639
  // Push ColorTemperature Update
829
- if (this.On) {
640
+ if (this.LightBulb.On) {
830
641
  await this.pushColorTemperatureChanges();
831
642
  }
832
643
  // Push Brightness Update
833
- if (this.On) {
644
+ if (this.LightBulb.On) {
834
645
  await this.pushBrightnessChanges();
835
646
  }
836
647
  }
837
648
 
838
649
  async pushHueSaturationChanges(): Promise<void> {
839
650
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges`);
840
- if (this.Hue !== this.accessory.context.Hue || this.Saturation !== this.accessory.context.Saturation) {
841
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${JSON.stringify(this.Hue)}`);
842
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${JSON.stringify(this.Saturation)}`);
843
- const [red, green, blue] = hs2rgb(Number(this.Hue), Number(this.Saturation));
651
+ if (this.LightBulb.Hue !== this.accessory.context.Hue || this.LightBulb.Saturation !== this.accessory.context.Saturation) {
652
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${JSON.stringify(this.LightBulb.Hue)}`);
653
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${JSON.stringify(this.LightBulb.Saturation)}`);
654
+ const [red, green, blue] = hs2rgb(Number(this.LightBulb.Hue), Number(this.LightBulb.Saturation));
844
655
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} rgb: ${JSON.stringify([red, green, blue])}`);
845
656
  const bodyChange = JSON.stringify({
846
657
  command: 'setColor',
@@ -849,43 +660,34 @@ export class ColorBulb {
849
660
  });
850
661
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
851
662
  try {
852
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
853
- body: bodyChange,
854
- method: 'POST',
855
- headers: this.platform.generateHeaders(),
856
- });
857
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
663
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
858
664
  const deviceStatus: any = await body.json();
859
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
860
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
861
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
665
+ await this.pushStatusCodes(statusCode, deviceStatus);
862
666
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
863
667
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
864
668
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
669
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
670
+ + `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
865
671
  } else {
866
672
  this.statusCode(statusCode);
867
673
  this.statusCode(deviceStatus.statusCode);
868
674
  }
869
675
  } catch (e: any) {
870
676
  this.apiError(e);
871
- this.errorLog(
872
- `${this.device.deviceType}: ${this.accessory.displayName} failed pushHueSaturationChanges with ${this.device.connectionType}` +
873
- ` Connection, Error Message: ${JSON.stringify(e.message)}`,
874
- );
677
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushHueSaturationChanges with ${this.device.connectionType}`
678
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
875
679
  }
876
680
  } else {
877
- this.debugLog(
878
- `${this.device.deviceType}: ${this.accessory.displayName} No pushHueSaturationChanges. Hue: ${this.Hue}, ` +
879
- `HueCached: ${this.accessory.context.Hue}, Saturation: ${this.Saturation}, SaturationCached: ${this.accessory.context.Saturation}`,
880
- );
681
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushHueSaturationChanges. Hue: ${this.LightBulb.Hue}, HueCached: `
682
+ + `${this.accessory.context.Hue}, Saturation: ${this.LightBulb.Saturation}, SaturationCached: ${this.accessory.context.Saturation}`);
881
683
  }
882
684
  }
883
685
 
884
686
  async pushColorTemperatureChanges(): Promise<void> {
885
687
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushColorTemperatureChanges`);
886
- if (this.ColorTemperature !== this.accessory.context.ColorTemperature) {
887
- const kelvin = Math.round(1000000 / Number(this.ColorTemperature));
888
- this.cacheKelvin = kelvin;
688
+ if (this.LightBulb.ColorTemperature !== this.accessory.context.ColorTemperature) {
689
+ const kelvin = Math.round(1000000 / Number(this.LightBulb.ColorTemperature));
690
+ this.accessory.context.kelvin = kelvin;
889
691
  const bodyChange = JSON.stringify({
890
692
  command: 'setColorTemperature',
891
693
  parameter: `${kelvin}`,
@@ -893,78 +695,59 @@ export class ColorBulb {
893
695
  });
894
696
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
895
697
  try {
896
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
897
- body: bodyChange,
898
- method: 'POST',
899
- headers: this.platform.generateHeaders(),
900
- });
901
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
698
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
902
699
  const deviceStatus: any = await body.json();
903
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
904
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
905
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
700
+ await this.pushStatusCodes(statusCode, deviceStatus);
906
701
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
907
702
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
908
703
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
704
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
705
+ + `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
909
706
  } else {
910
707
  this.statusCode(statusCode);
911
708
  this.statusCode(deviceStatus.statusCode);
912
709
  }
913
710
  } catch (e: any) {
914
711
  this.apiError(e);
915
- this.errorLog(
916
- `${this.device.deviceType}: ${this.accessory.displayName} failed pushColorTemperatureChanges with ${this.device.connectionType}` +
917
- ` Connection, Error Message: ${JSON.stringify(e.message)}`,
918
- );
712
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushColorTemperatureChanges with ${this.device.connectionType}`
713
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
919
714
  }
920
715
  } else {
921
- this.debugLog(
922
- `${this.device.deviceType}: ${this.accessory.displayName} No pushColorTemperatureChanges.` +
923
- `ColorTemperature: ${this.ColorTemperature}, ColorTemperatureCached: ${this.accessory.context.ColorTemperature}`,
924
- );
716
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushColorTemperatureChanges.`
717
+ + `ColorTemperature: ${this.LightBulb.ColorTemperature}, ColorTemperatureCached: ${this.accessory.context.ColorTemperature}`);
925
718
  }
926
719
  }
927
720
 
928
721
  async pushBrightnessChanges(): Promise<void> {
929
722
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges`);
930
- if (this.Brightness !== this.accessory.context.Brightness) {
723
+ if (this.LightBulb.Brightness !== this.accessory.context.Brightness) {
931
724
  const bodyChange = JSON.stringify({
932
725
  command: 'setBrightness',
933
- parameter: `${this.Brightness}`,
726
+ parameter: `${this.LightBulb.Brightness}`,
934
727
  commandType: 'command',
935
728
  });
936
729
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
937
730
  try {
938
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/commands`, {
939
- body: bodyChange,
940
- method: 'POST',
941
- headers: this.platform.generateHeaders(),
942
- });
943
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
731
+ const { body, statusCode } = await this.pushChangeRequest(bodyChange);
944
732
  const deviceStatus: any = await body.json();
945
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
946
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
947
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
733
+ await this.pushStatusCodes(statusCode, deviceStatus);
948
734
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
949
735
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
950
736
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
737
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
738
+ + `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
951
739
  } else {
952
740
  this.statusCode(statusCode);
953
741
  this.statusCode(deviceStatus.statusCode);
954
742
  }
955
743
  } catch (e: any) {
956
744
  this.apiError(e);
957
- this.errorLog(
958
- `${this.device.deviceType}: ${this.accessory.displayName} failed pushBrightnessChanges with ${this.device.connectionType}` +
959
- ` Connection, Error Message: ${JSON.stringify(e.message)}`,
960
- );
745
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushBrightnessChanges with ${this.device.connectionType}`
746
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
961
747
  }
962
748
  } else {
963
- this.debugLog(
964
- `${this.device.deviceType}: ${this.accessory.displayName} No pushBrightnessChanges.` +
965
- `Brightness: ${this.Brightness}, ` +
966
- `BrightnessCached: ${this.accessory.context.Brightness}`,
967
- );
749
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushBrightnessChanges.`
750
+ + `Brightness: ${this.LightBulb.Brightness}, BrightnessCached: ${this.accessory.context.Brightness}`);
968
751
  }
969
752
  }
970
753
 
@@ -972,13 +755,13 @@ export class ColorBulb {
972
755
  * Handle requests to set the value of the "On" characteristic
973
756
  */
974
757
  async OnSet(value: CharacteristicValue): Promise<void> {
975
- if (this.On === this.accessory.context.On) {
758
+ if (this.LightBulb.On === this.accessory.context.On) {
976
759
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set On: ${value}`);
977
760
  } else {
978
761
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set On: ${value}`);
979
762
  }
980
763
 
981
- this.On = value;
764
+ this.LightBulb.On = value;
982
765
  this.doColorBulbUpdate.next();
983
766
  }
984
767
 
@@ -986,15 +769,15 @@ export class ColorBulb {
986
769
  * Handle requests to set the value of the "Brightness" characteristic
987
770
  */
988
771
  async BrightnessSet(value: CharacteristicValue): Promise<void> {
989
- if (this.Brightness === this.accessory.context.Brightness) {
772
+ if (this.LightBulb.Brightness === this.accessory.context.Brightness) {
990
773
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set Brightness: ${value}`);
991
- } else if (this.On) {
774
+ } else if (this.LightBulb.On) {
992
775
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Brightness: ${value}`);
993
776
  } else {
994
777
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Brightness: ${value}`);
995
778
  }
996
779
 
997
- this.Brightness = value;
780
+ this.LightBulb.Brightness = value;
998
781
  this.doColorBulbUpdate.next();
999
782
  }
1000
783
 
@@ -1002,30 +785,32 @@ export class ColorBulb {
1002
785
  * Handle requests to set the value of the "ColorTemperature" characteristic
1003
786
  */
1004
787
  async ColorTemperatureSet(value: CharacteristicValue): Promise<void> {
1005
- if (this.ColorTemperature === this.accessory.context.ColorTemperature) {
788
+ if (this.LightBulb.ColorTemperature === this.accessory.context.ColorTemperature) {
1006
789
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set ColorTemperature: ${value}`);
1007
- } else if (this.On) {
790
+ } else if (this.LightBulb.On) {
1008
791
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set ColorTemperature: ${value}`);
1009
792
  } else {
1010
793
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Set ColorTemperature: ${value}`);
1011
794
  }
1012
795
 
796
+ const minKelvin = 2000;
797
+ const maxKelvin = 9000;
1013
798
  // Convert mired to kelvin to nearest 100 (SwitchBot seems to need this)
1014
799
  const kelvin = Math.round(1000000 / Number(value) / 100) * 100;
1015
800
 
1016
801
  // Check and increase/decrease kelvin to range of device
1017
- const k = Math.min(Math.max(kelvin, this.minKelvin), this.maxKelvin);
802
+ const k = Math.min(Math.max(kelvin, minKelvin), maxKelvin);
1018
803
 
1019
- if (!this.accessory.context.On || this.cacheKelvin === k) {
804
+ if (!this.accessory.context.On || this.accessory.context.kelvin === k) {
1020
805
  return;
1021
806
  }
1022
807
 
1023
808
  // Updating the hue/sat to the corresponding values mimics native adaptive lighting
1024
809
  const hs = m2hs(value);
1025
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.Hue, hs[0]);
1026
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.Saturation, hs[1]);
810
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.Hue, hs[0]);
811
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.Saturation, hs[1]);
1027
812
 
1028
- this.ColorTemperature = value;
813
+ this.LightBulb.ColorTemperature = value;
1029
814
  this.doColorBulbUpdate.next();
1030
815
  }
1031
816
 
@@ -1033,17 +818,17 @@ export class ColorBulb {
1033
818
  * Handle requests to set the value of the "Hue" characteristic
1034
819
  */
1035
820
  async HueSet(value: CharacteristicValue): Promise<void> {
1036
- if (this.Hue === this.accessory.context.Hue) {
821
+ if (this.LightBulb.Hue === this.accessory.context.Hue) {
1037
822
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set Hue: ${value}`);
1038
- } else if (this.On) {
823
+ } else if (this.LightBulb.On) {
1039
824
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Hue: ${value}`);
1040
825
  } else {
1041
826
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Hue: ${value}`);
1042
827
  }
1043
828
 
1044
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.ColorTemperature, 140);
829
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.ColorTemperature, 140);
1045
830
 
1046
- this.Hue = value;
831
+ this.LightBulb.Hue = value;
1047
832
  this.doColorBulbUpdate.next();
1048
833
  }
1049
834
 
@@ -1051,60 +836,61 @@ export class ColorBulb {
1051
836
  * Handle requests to set the value of the "Saturation" characteristic
1052
837
  */
1053
838
  async SaturationSet(value: CharacteristicValue): Promise<void> {
1054
- if (this.Saturation === this.accessory.context.Saturation) {
839
+ if (this.LightBulb.Saturation === this.accessory.context.Saturation) {
1055
840
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set Saturation: ${value}`);
1056
- } else if (this.On) {
841
+ } else if (this.LightBulb.On) {
1057
842
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Saturation: ${value}`);
1058
843
  } else {
1059
844
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Saturation: ${value}`);
1060
845
  }
1061
846
 
1062
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.ColorTemperature, 140);
847
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.ColorTemperature, 140);
1063
848
 
1064
- this.Saturation = value;
849
+ this.LightBulb.Saturation = value;
1065
850
  this.doColorBulbUpdate.next();
1066
851
  }
1067
852
 
1068
853
  async updateHomeKitCharacteristics(): Promise<void> {
1069
854
  // On
1070
- if (this.On === undefined) {
1071
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
855
+ if (this.LightBulb.On === undefined) {
856
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LightBulb.On}`);
1072
857
  } else {
1073
- this.accessory.context.On = this.On;
1074
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.On, this.On);
1075
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
858
+ this.accessory.context.On = this.LightBulb.On;
859
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.On, this.LightBulb.On);
860
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.LightBulb.On}`);
1076
861
  }
1077
862
  // Brightness
1078
- if (this.Brightness === undefined) {
1079
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
863
+ if (this.LightBulb.Brightness === undefined) {
864
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.LightBulb.Brightness}`);
1080
865
  } else {
1081
- this.accessory.context.Brightness = this.Brightness;
1082
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.Brightness, this.Brightness);
1083
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Brightness: ${this.Brightness}`);
866
+ this.accessory.context.Brightness = this.LightBulb.Brightness;
867
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.Brightness, this.LightBulb.Brightness);
868
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Brightness: ${this.LightBulb.Brightness}`);
1084
869
  }
1085
870
  // ColorTemperature
1086
- if (this.ColorTemperature === undefined) {
1087
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
871
+ if (this.LightBulb.ColorTemperature === undefined) {
872
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.LightBulb.ColorTemperature}`);
1088
873
  } else {
1089
- this.accessory.context.ColorTemperature = this.ColorTemperature;
1090
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.ColorTemperature, this.ColorTemperature);
1091
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic ColorTemperature: ${this.ColorTemperature}`);
874
+ this.accessory.context.ColorTemperature = this.LightBulb.ColorTemperature;
875
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.ColorTemperature, this.LightBulb.ColorTemperature);
876
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
877
+ + ` ColorTemperature: ${this.LightBulb.ColorTemperature}`);
1092
878
  }
1093
879
  // Hue
1094
- if (this.Hue === undefined) {
1095
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.Hue}`);
880
+ if (this.LightBulb.Hue === undefined) {
881
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.LightBulb.Hue}`);
1096
882
  } else {
1097
- this.accessory.context.Hue = this.Hue;
1098
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.Hue, this.Hue);
1099
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Hue: ${this.Hue}`);
883
+ this.accessory.context.Hue = this.LightBulb.Hue;
884
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.Hue, this.LightBulb.Hue);
885
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Hue: ${this.LightBulb.Hue}`);
1100
886
  }
1101
887
  // Saturation
1102
- if (this.Saturation === undefined) {
1103
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
888
+ if (this.LightBulb.Saturation === undefined) {
889
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${this.LightBulb.Saturation}`);
1104
890
  } else {
1105
- this.accessory.context.Saturation = this.Saturation;
1106
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.Saturation, this.Saturation);
1107
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Saturation: ${this.Saturation}`);
891
+ this.accessory.context.Saturation = this.LightBulb.Saturation;
892
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.Saturation, this.LightBulb.Saturation);
893
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Saturation: ${this.LightBulb.Saturation}`);
1108
894
  }
1109
895
  }
1110
896
 
@@ -1118,35 +904,6 @@ export class ColorBulb {
1118
904
  }
1119
905
  }
1120
906
 
1121
- async stopScanning(switchbot: any) {
1122
- switchbot.stopScan();
1123
- if (this.BLE_IsConnected) {
1124
- await this.BLEparseStatus();
1125
- await this.updateHomeKitCharacteristics();
1126
- } else {
1127
- await this.BLERefreshConnection(switchbot);
1128
- }
1129
- }
1130
-
1131
- async getCustomBLEAddress(switchbot: any) {
1132
- if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
1133
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} customBLEaddress: ${this.device.customBLEaddress}`);
1134
- (async () => {
1135
- // Start to monitor advertisement packets
1136
- await switchbot.startScan({
1137
- model: 'u',
1138
- });
1139
- // Set an event handler
1140
- switchbot.onadvertisement = (ad: any) => {
1141
- this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
1142
- };
1143
- await sleep(10000);
1144
- // Stop to monitor
1145
- switchbot.stopScan();
1146
- })();
1147
- }
1148
- }
1149
-
1150
907
  async BLEPushConnection() {
1151
908
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
1152
909
  this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
@@ -1163,284 +920,17 @@ export class ColorBulb {
1163
920
  }
1164
921
  }
1165
922
 
1166
- async retry({ max, fn }: { max: number; fn: { (): any; (): Promise<any> } }): Promise<null> {
1167
- return fn().catch(async (e: any) => {
1168
- if (max === 0) {
1169
- throw e;
1170
- }
1171
- this.infoLog(e);
1172
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Retrying`);
1173
- await sleep(1000);
1174
- return this.retry({ max: max - 1, fn });
1175
- });
1176
- }
1177
-
1178
- maxRetry(): number {
1179
- if (this.device.maxRetry) {
1180
- return this.device.maxRetry;
1181
- } else {
1182
- return 5;
1183
- }
1184
- }
1185
-
1186
- minStep(device: device & devicesConfig): number {
1187
- if (device.colorbulb?.set_minStep) {
1188
- this.set_minStep = device.colorbulb?.set_minStep;
1189
- } else {
1190
- this.set_minStep = 1;
1191
- }
1192
- return this.set_minStep;
1193
- }
1194
-
1195
- async scan(device: device & devicesConfig): Promise<void> {
1196
- if (device.scanDuration) {
1197
- this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
1198
- if (this.BLE) {
1199
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
1200
- }
1201
- } else {
1202
- this.scanDuration = this.accessory.context.scanDuration = 1;
1203
- if (this.BLE) {
1204
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
1205
- }
1206
- }
1207
- }
1208
-
1209
- async statusCode(statusCode: number): Promise<void> {
1210
- switch (statusCode) {
1211
- case 151:
1212
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
1213
- break;
1214
- case 152:
1215
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
1216
- break;
1217
- case 160:
1218
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
1219
- break;
1220
- case 161:
1221
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
1222
- this.offlineOff();
1223
- break;
1224
- case 171:
1225
- this.errorLog(
1226
- `${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
1227
- `Hub: ${this.device.hubDeviceId}`,
1228
- );
1229
- this.offlineOff();
1230
- break;
1231
- case 190:
1232
- this.errorLog(
1233
- `${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
1234
- ` Or command format is invalid, statusCode: ${statusCode}`,
1235
- );
1236
- break;
1237
- case 100:
1238
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
1239
- break;
1240
- case 200:
1241
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
1242
- break;
1243
- case 400:
1244
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bad Request, The client has issued an invalid request. `
1245
- + `This is commonly used to specify validation errors in a request payload, statusCode: ${statusCode}`);
1246
- break;
1247
- case 401:
1248
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unauthorized, Authorization for the API is required, `
1249
- + `but the request has not been authenticated, statusCode: ${statusCode}`);
1250
- break;
1251
- case 403:
1252
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Forbidden, The request has been authenticated but does not `
1253
- + `have appropriate permissions, or a requested resource is not found, statusCode: ${statusCode}`);
1254
- break;
1255
- case 404:
1256
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Found, Specifies the requested path does not exist, `
1257
- + `statusCode: ${statusCode}`);
1258
- break;
1259
- case 406:
1260
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Acceptable, The client has requested a MIME type via `
1261
- + `the Accept header for a value not supported by the server, statusCode: ${statusCode}`);
1262
- break;
1263
- case 415:
1264
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unsupported Media Type, The client has defined a contentType `
1265
- + `header that is not supported by the server, statusCode: ${statusCode}`);
1266
- break;
1267
- case 422:
1268
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unprocessable Entity, The client has made a valid request, `
1269
- + `but the server cannot process it. This is often used for APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
1270
- break;
1271
- case 429:
1272
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Too Many Requests, The client has exceeded the number of `
1273
- + `requests allowed for a given time window, statusCode: ${statusCode}`);
1274
- break;
1275
- case 500:
1276
- this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Internal Server Error, An unexpected error on the SmartThings `
1277
- + `servers has occurred. These errors should be rare, statusCode: ${statusCode}`);
1278
- break;
1279
- default:
1280
- this.infoLog(
1281
- `${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: ` +
1282
- `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`,
1283
- );
1284
- }
1285
- }
1286
-
1287
923
  async offlineOff(): Promise<void> {
1288
924
  if (this.device.offline) {
1289
- await this.deviceContext();
1290
- await this.updateHomeKitCharacteristics();
925
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.On, false);
1291
926
  }
1292
927
  }
1293
928
 
1294
929
  apiError(e: any): void {
1295
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.On, e);
1296
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.Hue, e);
1297
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.Brightness, e);
1298
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.Saturation, e);
1299
- this.lightBulbService.updateCharacteristic(this.hap.Characteristic.ColorTemperature, e);
1300
- }
1301
-
1302
- async deviceContext(): Promise<void> {
1303
- if (this.On === undefined) {
1304
- this.On = false;
1305
- } else {
1306
- this.On = this.accessory.context.On;
1307
- }
1308
- if (this.Hue === undefined) {
1309
- this.Hue = 0;
1310
- } else {
1311
- this.Hue = this.accessory.context.Hue;
1312
- }
1313
- if (this.Brightness === undefined) {
1314
- this.Brightness = 0;
1315
- } else {
1316
- this.Brightness = this.accessory.context.Brightness;
1317
- }
1318
- if (this.Saturation === undefined) {
1319
- this.Saturation = 0;
1320
- } else {
1321
- this.Saturation = this.accessory.context.Saturation;
1322
- }
1323
- if (this.ColorTemperature === undefined) {
1324
- this.ColorTemperature = 140;
1325
- } else {
1326
- this.ColorTemperature = this.accessory.context.ColorTemperature;
1327
- }
1328
- this.minKelvin = 2000;
1329
- this.maxKelvin = 9000;
1330
- if (this.FirmwareRevision === undefined) {
1331
- this.FirmwareRevision = this.platform.version;
1332
- this.accessory.context.FirmwareRevision = this.FirmwareRevision;
1333
- }
1334
- }
1335
-
1336
- async refreshRate(device: device & devicesConfig): Promise<void> {
1337
- if (device.refreshRate) {
1338
- this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
1339
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
1340
- } else if (this.platform.config.options!.refreshRate) {
1341
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
1342
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
1343
- }
1344
- }
1345
-
1346
- async deviceConfig(device: device & devicesConfig): Promise<void> {
1347
- let config = {};
1348
- if (device.colorbulb) {
1349
- config = device.colorbulb;
1350
- }
1351
- if (device.connectionType !== undefined) {
1352
- config['connectionType'] = device.connectionType;
1353
- }
1354
- if (device.external !== undefined) {
1355
- config['external'] = device.external;
1356
- }
1357
- if (device.logging !== undefined) {
1358
- config['logging'] = device.logging;
1359
- }
1360
- if (device.refreshRate !== undefined) {
1361
- config['refreshRate'] = device.refreshRate;
1362
- }
1363
- if (device.scanDuration !== undefined) {
1364
- config['scanDuration'] = device.scanDuration;
1365
- }
1366
- if (device.offline !== undefined) {
1367
- config['offline'] = device.offline;
1368
- }
1369
- if (device.maxRetry !== undefined) {
1370
- config['maxRetry'] = device.maxRetry;
1371
- }
1372
- if (device.webhook !== undefined) {
1373
- config['webhook'] = device.webhook;
1374
- }
1375
- if (Object.entries(config).length !== 0) {
1376
- this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
1377
- }
1378
- }
1379
-
1380
- async deviceLogs(device: device & devicesConfig): Promise<void> {
1381
- if (this.platform.debugMode) {
1382
- this.deviceLogging = this.accessory.context.logging = 'debugMode';
1383
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
1384
- } else if (device.logging) {
1385
- this.deviceLogging = this.accessory.context.logging = device.logging;
1386
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
1387
- } else if (this.platform.config.options?.logging) {
1388
- this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
1389
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
1390
- } else {
1391
- this.deviceLogging = this.accessory.context.logging = 'standard';
1392
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
1393
- }
1394
- }
1395
-
1396
- /**
1397
- * Logging for Device
1398
- */
1399
- infoLog(...log: any[]): void {
1400
- if (this.enablingDeviceLogging()) {
1401
- this.platform.log.info(String(...log));
1402
- }
1403
- }
1404
-
1405
- warnLog(...log: any[]): void {
1406
- if (this.enablingDeviceLogging()) {
1407
- this.platform.log.warn(String(...log));
1408
- }
1409
- }
1410
-
1411
- debugWarnLog(...log: any[]): void {
1412
- if (this.enablingDeviceLogging()) {
1413
- if (this.deviceLogging?.includes('debug')) {
1414
- this.platform.log.warn('[DEBUG]', String(...log));
1415
- }
1416
- }
1417
- }
1418
-
1419
- errorLog(...log: any[]): void {
1420
- if (this.enablingDeviceLogging()) {
1421
- this.platform.log.error(String(...log));
1422
- }
1423
- }
1424
-
1425
- debugErrorLog(...log: any[]): void {
1426
- if (this.enablingDeviceLogging()) {
1427
- if (this.deviceLogging?.includes('debug')) {
1428
- this.platform.log.error('[DEBUG]', String(...log));
1429
- }
1430
- }
1431
- }
1432
-
1433
- debugLog(...log: any[]): void {
1434
- if (this.enablingDeviceLogging()) {
1435
- if (this.deviceLogging === 'debug') {
1436
- this.platform.log.info('[DEBUG]', String(...log));
1437
- } else {
1438
- this.platform.log.debug(String(...log));
1439
- }
1440
- }
1441
- }
1442
-
1443
- enablingDeviceLogging(): boolean {
1444
- return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
930
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.On, e);
931
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.Hue, e);
932
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.Brightness, e);
933
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.Saturation, e);
934
+ this.LightBulb.Service.updateCharacteristic(this.hap.Characteristic.ColorTemperature, e);
1445
935
  }
1446
936
  }