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