@switchbot/homebridge-switchbot 2.0.0-beta.8 → 2.0.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.
- package/CHANGELOG.md +10 -1
- package/README.md +3 -2
- package/config.schema.json +91 -19
- package/dist/device/bot.d.ts +34 -28
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +657 -648
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +137 -0
- package/dist/device/ceilinglight.d.ts.map +1 -0
- package/dist/device/ceilinglight.js +1127 -0
- package/dist/device/ceilinglight.js.map +1 -0
- package/dist/device/colorbulb.d.ts +36 -19
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +486 -309
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +18 -8
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +306 -237
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +23 -16
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +566 -502
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/humidifier.d.ts +24 -18
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +453 -369
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/lock.d.ts +27 -8
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +305 -148
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +22 -16
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +367 -267
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +24 -12
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +381 -213
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +18 -8
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +279 -216
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +27 -17
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +295 -251
- package/dist/device/plug.js.map +1 -1
- package/dist/device/striplight.d.ts +43 -19
- package/dist/device/striplight.d.ts.map +1 -1
- package/dist/device/striplight.js +506 -262
- package/dist/device/striplight.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +9 -12
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +278 -230
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +5 -3
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +154 -104
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +11 -8
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +133 -86
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +10 -7
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +160 -109
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/light.d.ts +11 -8
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +137 -103
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +11 -8
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +145 -98
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +12 -9
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +143 -93
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +9 -10
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +132 -89
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +8 -9
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +132 -89
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +13 -12
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +524 -418
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +19 -11
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/homebridge-ui/public/index.html +1 -0
- package/package.json +11 -9
- package/src/device/bot.ts +656 -659
- package/src/device/ceilinglight.ts +1208 -0
- package/src/device/colorbulb.ts +490 -344
- package/src/device/contact.ts +309 -241
- package/src/device/curtain.ts +571 -516
- package/src/device/humidifier.ts +456 -403
- package/src/device/lock.ts +314 -149
- package/src/device/meter.ts +378 -280
- package/src/device/meterplus.ts +391 -219
- package/src/device/motion.ts +285 -222
- package/src/device/plug.ts +299 -260
- package/src/device/striplight.ts +522 -289
- package/src/irdevice/airconditioner.ts +282 -241
- package/src/irdevice/airpurifier.ts +151 -103
- package/src/irdevice/camera.ts +131 -85
- package/src/irdevice/fan.ts +157 -106
- package/src/irdevice/light.ts +135 -103
- package/src/irdevice/other.ts +143 -97
- package/src/irdevice/tv.ts +142 -93
- package/src/irdevice/vacuumcleaner.ts +131 -89
- package/src/irdevice/waterheater.ts +130 -89
- package/src/platform.ts +522 -446
- package/src/settings.ts +20 -11
- package/.github/npm-version-script.js +0 -81
package/src/device/colorbulb.ts
CHANGED
|
@@ -2,9 +2,10 @@ import https from 'https';
|
|
|
2
2
|
import crypto from 'crypto';
|
|
3
3
|
import { Context } from 'vm';
|
|
4
4
|
import { IncomingMessage } from 'http';
|
|
5
|
+
import superStringify from 'super-stringify';
|
|
5
6
|
import { interval, Subject } from 'rxjs';
|
|
6
7
|
import { SwitchBotPlatform } from '../platform';
|
|
7
|
-
import { debounceTime, skipWhile, tap } from 'rxjs/operators';
|
|
8
|
+
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
8
9
|
import { Service, PlatformAccessory, CharacteristicValue, ControllerConstructor, Controller, ControllerServiceMap } from 'homebridge';
|
|
9
10
|
import { device, devicesConfig, deviceStatus, switchbot, hs2rgb, rgb2hs, m2hs, serviceData, ad, HostDomain, DevicePath } from '../settings';
|
|
10
11
|
|
|
@@ -19,15 +20,10 @@ export class ColorBulb {
|
|
|
19
20
|
|
|
20
21
|
// Characteristic Values
|
|
21
22
|
On!: CharacteristicValue;
|
|
22
|
-
OnCached!: CharacteristicValue;
|
|
23
23
|
Hue!: CharacteristicValue;
|
|
24
|
-
HueCached!: CharacteristicValue;
|
|
25
24
|
Saturation!: CharacteristicValue;
|
|
26
|
-
SaturationCached!: CharacteristicValue;
|
|
27
25
|
Brightness!: CharacteristicValue;
|
|
28
|
-
BrightnessCached!: CharacteristicValue;
|
|
29
26
|
ColorTemperature?: CharacteristicValue;
|
|
30
|
-
ColorTemperatureCached?: CharacteristicValue;
|
|
31
27
|
|
|
32
28
|
// OpenAPI Others
|
|
33
29
|
power: deviceStatus['power'];
|
|
@@ -40,7 +36,6 @@ export class ColorBulb {
|
|
|
40
36
|
connected?: boolean;
|
|
41
37
|
switchbot!: switchbot;
|
|
42
38
|
address!: ad['address'];
|
|
43
|
-
SwitchToOpenAPI?: boolean;
|
|
44
39
|
serviceData!: serviceData;
|
|
45
40
|
state: serviceData['state'];
|
|
46
41
|
delay: serviceData['delay'];
|
|
@@ -65,6 +60,10 @@ export class ColorBulb {
|
|
|
65
60
|
colorBulbUpdateInProgress!: boolean;
|
|
66
61
|
doColorBulbUpdate!: Subject<void>;
|
|
67
62
|
|
|
63
|
+
// Connection
|
|
64
|
+
private readonly BLE = (this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI');
|
|
65
|
+
private readonly OpenAPI = (this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI');
|
|
66
|
+
|
|
68
67
|
constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
|
|
69
68
|
// default placeholders
|
|
70
69
|
this.logs(device);
|
|
@@ -72,17 +71,7 @@ export class ColorBulb {
|
|
|
72
71
|
this.refreshRate(device);
|
|
73
72
|
this.adaptiveLighting(device);
|
|
74
73
|
this.config(device);
|
|
75
|
-
|
|
76
|
-
this.On = false;
|
|
77
|
-
} else {
|
|
78
|
-
this.On = this.accessory.context.On;
|
|
79
|
-
}
|
|
80
|
-
this.Hue = 0;
|
|
81
|
-
this.Brightness = 0;
|
|
82
|
-
this.Saturation = 0;
|
|
83
|
-
this.ColorTemperature = 140;
|
|
84
|
-
this.minKelvin = 2000;
|
|
85
|
-
this.maxKelvin = 9000;
|
|
74
|
+
this.context();
|
|
86
75
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
87
76
|
this.doColorBulbUpdate = new Subject();
|
|
88
77
|
this.colorBulbUpdateInProgress = false;
|
|
@@ -109,7 +98,7 @@ export class ColorBulb {
|
|
|
109
98
|
this.accessory.removeService(this.lightBulbService);
|
|
110
99
|
this.lightBulbService = this.accessory.addService(this.platform.Service.Lightbulb);
|
|
111
100
|
this.accessory.context.adaptiveLighting = false;
|
|
112
|
-
this.debugLog(
|
|
101
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLighting: ${this.accessory.context.adaptiveLighting}`);
|
|
113
102
|
}
|
|
114
103
|
|
|
115
104
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
@@ -138,7 +127,6 @@ export class ColorBulb {
|
|
|
138
127
|
.onSet(this.BrightnessSet.bind(this));
|
|
139
128
|
|
|
140
129
|
// handle ColorTemperature events using the ColorTemperature characteristic
|
|
141
|
-
this.debugLog(`Color Bulb: ${accessory.displayName} Add ColorTemperature Characteristic`);
|
|
142
130
|
this.lightBulbService
|
|
143
131
|
.getCharacteristic(this.platform.Characteristic.ColorTemperature)
|
|
144
132
|
.setProps({
|
|
@@ -177,7 +165,7 @@ export class ColorBulb {
|
|
|
177
165
|
})
|
|
178
166
|
.onSet(this.SaturationSet.bind(this));
|
|
179
167
|
|
|
180
|
-
this.debugLog(
|
|
168
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
181
169
|
if (this.adaptiveLightingShift !== -1) {
|
|
182
170
|
this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.lightBulbService, {
|
|
183
171
|
customTemperatureAdjustment: this.adaptiveLightingShift,
|
|
@@ -185,7 +173,7 @@ export class ColorBulb {
|
|
|
185
173
|
this.accessory.configureController(this.AdaptiveLightingController);
|
|
186
174
|
this.accessory.context.adaptiveLighting = true;
|
|
187
175
|
this.debugLog(
|
|
188
|
-
|
|
176
|
+
`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLighting: ${this.accessory.context.adaptiveLighting},` +
|
|
189
177
|
` adaptiveLightingShift: ${this.adaptiveLightingShift}`,
|
|
190
178
|
);
|
|
191
179
|
}
|
|
@@ -213,26 +201,37 @@ export class ColorBulb {
|
|
|
213
201
|
try {
|
|
214
202
|
await this.pushChanges();
|
|
215
203
|
} catch (e: any) {
|
|
216
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges`);
|
|
217
|
-
if (this.deviceLogging.includes('debug')) {
|
|
218
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges,` + ` Error Message: ${JSON.stringify(e.message)}`);
|
|
219
|
-
}
|
|
220
204
|
this.apiError(e);
|
|
205
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
|
|
206
|
+
+ ` Error Message: ${superStringify(e.message)}`);
|
|
221
207
|
}
|
|
222
208
|
this.colorBulbUpdateInProgress = false;
|
|
209
|
+
// Refresh the status from the API
|
|
210
|
+
interval(15000)
|
|
211
|
+
.pipe(skipWhile(() => this.colorBulbUpdateInProgress))
|
|
212
|
+
.pipe(take(1))
|
|
213
|
+
.subscribe(async () => {
|
|
214
|
+
await this.refreshStatus();
|
|
215
|
+
});
|
|
223
216
|
});
|
|
224
217
|
}
|
|
225
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Parse the device status from the SwitchBot api
|
|
221
|
+
*/
|
|
226
222
|
async parseStatus(): Promise<void> {
|
|
227
|
-
if (this.
|
|
223
|
+
/*if (this.BLE) {
|
|
224
|
+
await this.BLEparseStatus();
|
|
225
|
+
} else*/ if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
228
226
|
await this.openAPIparseStatus();
|
|
229
227
|
} else {
|
|
230
|
-
|
|
228
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
229
|
+
+ ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
231
230
|
}
|
|
232
231
|
}
|
|
233
232
|
|
|
234
233
|
async BLEparseStatus(): Promise<void> {
|
|
235
|
-
this.debugLog(
|
|
234
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
236
235
|
// State
|
|
237
236
|
switch (this.state) {
|
|
238
237
|
case 'on':
|
|
@@ -241,10 +240,11 @@ export class ColorBulb {
|
|
|
241
240
|
default:
|
|
242
241
|
this.On = false;
|
|
243
242
|
}
|
|
244
|
-
this.debugLog(
|
|
243
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
245
244
|
}
|
|
246
245
|
|
|
247
246
|
async openAPIparseStatus() {
|
|
247
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
248
248
|
switch (this.power) {
|
|
249
249
|
case 'on':
|
|
250
250
|
this.On = true;
|
|
@@ -252,61 +252,68 @@ export class ColorBulb {
|
|
|
252
252
|
default:
|
|
253
253
|
this.On = false;
|
|
254
254
|
}
|
|
255
|
-
this.debugLog(
|
|
255
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
256
256
|
|
|
257
257
|
// Brightness
|
|
258
258
|
this.Brightness = Number(this.brightness);
|
|
259
|
-
this.debugLog(
|
|
259
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
|
|
260
260
|
|
|
261
261
|
// Color, Hue & Brightness
|
|
262
262
|
if (this.color) {
|
|
263
|
-
this.debugLog(
|
|
263
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} color: ${superStringify(this.color)}`);
|
|
264
264
|
const [red, green, blue] = this.color!.split(':');
|
|
265
|
-
this.debugLog(
|
|
266
|
-
this.debugLog(
|
|
267
|
-
this.debugLog(
|
|
265
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} red: ${superStringify(red)}`);
|
|
266
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} green: ${superStringify(green)}`);
|
|
267
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} blue: ${superStringify(blue)}`);
|
|
268
268
|
|
|
269
269
|
const [hue, saturation] = rgb2hs(Number(red), Number(green), Number(blue));
|
|
270
|
-
this.debugLog(
|
|
270
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
271
|
+
+ ` hs: ${superStringify(rgb2hs(Number(red), Number(green), Number(blue)))}`);
|
|
271
272
|
|
|
272
273
|
// Hue
|
|
273
274
|
this.Hue = hue;
|
|
274
|
-
this.debugLog(
|
|
275
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.Hue}`);
|
|
275
276
|
|
|
276
277
|
// Saturation
|
|
277
278
|
this.Saturation = saturation;
|
|
278
|
-
this.debugLog(
|
|
279
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
|
|
279
280
|
}
|
|
280
281
|
|
|
281
282
|
// ColorTemperature
|
|
282
283
|
if (!Number.isNaN(this.colorTemperature)) {
|
|
283
|
-
this.debugLog(
|
|
284
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} OpenAPI ColorTemperature: ${this.colorTemperature}`);
|
|
284
285
|
const mired = Math.round(1000000 / this.colorTemperature!);
|
|
285
286
|
|
|
286
287
|
this.ColorTemperature = Number(mired);
|
|
287
288
|
|
|
288
289
|
this.ColorTemperature = Math.max(Math.min(this.ColorTemperature, 500), 140);
|
|
289
|
-
this.debugLog(
|
|
290
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
|
|
290
291
|
}
|
|
291
292
|
}
|
|
292
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Asks the SwitchBot API for the latest device information
|
|
296
|
+
*/
|
|
293
297
|
async refreshStatus(): Promise<void> {
|
|
294
|
-
if (this.
|
|
298
|
+
/*if (this.BLE) {
|
|
295
299
|
await this.BLERefreshStatus();
|
|
296
|
-
} else {
|
|
300
|
+
} else*/ if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
297
301
|
await this.openAPIRefreshStatus();
|
|
302
|
+
} else {
|
|
303
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
304
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
298
305
|
}
|
|
299
306
|
}
|
|
300
307
|
|
|
301
308
|
async BLERefreshStatus(): Promise<void> {
|
|
302
|
-
this.debugLog(
|
|
309
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
|
|
303
310
|
const switchbot = await this.platform.connectBLE();
|
|
304
311
|
// Convert to BLE Address
|
|
305
312
|
this.device.bleMac = this.device
|
|
306
313
|
.deviceId!.match(/.{1,2}/g)!
|
|
307
314
|
.join(':')
|
|
308
315
|
.toLowerCase();
|
|
309
|
-
this.debugLog(
|
|
316
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
310
317
|
this.getCustomBLEAddress(switchbot);
|
|
311
318
|
// Start to monitor advertisement packets
|
|
312
319
|
if (switchbot !== false) {
|
|
@@ -319,13 +326,9 @@ export class ColorBulb {
|
|
|
319
326
|
// Set an event hander
|
|
320
327
|
switchbot.onadvertisement = (ad: any) => {
|
|
321
328
|
this.address = ad.address;
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
this.infoLog(`Color Bulb: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
|
|
326
|
-
this.infoLog(`Color Bulb: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
|
|
327
|
-
}
|
|
328
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
329
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
|
|
330
|
+
+ ` BLE Address Found: ${this.address}`);
|
|
331
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
|
|
329
332
|
this.serviceData = ad.serviceData;
|
|
330
333
|
//this.state = ad.serviceData.state;
|
|
331
334
|
//this.delay = ad.serviceData.delay;
|
|
@@ -334,19 +337,19 @@ export class ColorBulb {
|
|
|
334
337
|
//this.wifiRssi = ad.serviceData.wifiRssi;
|
|
335
338
|
//this.overload = ad.serviceData.overload;
|
|
336
339
|
//this.currentPower = ad.serviceData.currentPower;
|
|
337
|
-
this.debugLog(
|
|
340
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
|
|
338
341
|
/*this.debugLog(
|
|
339
|
-
|
|
342
|
+
`${this.device.deviceType}: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
|
|
340
343
|
`delay: ${ad.serviceData.delay}, timer: ${ad.serviceData.timer}, syncUtcTime: ${ad.serviceData.syncUtcTime} ` +
|
|
341
344
|
`wifiRssi: ${ad.serviceData.wifiRssi}, overload: ${ad.serviceData.overload}, currentPower: ${ad.serviceData.currentPower}`,
|
|
342
345
|
);*/
|
|
343
346
|
|
|
344
347
|
if (this.serviceData) {
|
|
345
348
|
this.connected = true;
|
|
346
|
-
this.debugLog(
|
|
349
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
347
350
|
} else {
|
|
348
351
|
this.connected = false;
|
|
349
|
-
this.debugLog(
|
|
352
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
350
353
|
}
|
|
351
354
|
};
|
|
352
355
|
// Wait 2 seconds
|
|
@@ -356,72 +359,32 @@ export class ColorBulb {
|
|
|
356
359
|
// Stop to monitor
|
|
357
360
|
switchbot.stopScan();
|
|
358
361
|
if (this.connected) {
|
|
359
|
-
this.
|
|
362
|
+
this.BLEparseStatus();
|
|
360
363
|
this.updateHomeKitCharacteristics();
|
|
361
364
|
} else {
|
|
362
|
-
this.
|
|
363
|
-
if (this.platform.config.credentials?.token) {
|
|
364
|
-
this.warnLog(`Color Bulb: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
365
|
-
this.SwitchToOpenAPI = true;
|
|
366
|
-
await this.openAPIRefreshStatus();
|
|
367
|
-
}
|
|
365
|
+
await this.BLERefreshConnection(switchbot);
|
|
368
366
|
}
|
|
369
367
|
})
|
|
370
368
|
.catch(async (e: any) => {
|
|
371
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
|
|
372
|
-
if (this.deviceLogging.includes('debug')) {
|
|
373
|
-
this.errorLog(
|
|
374
|
-
`Color Bulb: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
375
|
-
);
|
|
376
|
-
}
|
|
377
|
-
if (this.platform.config.credentials?.token) {
|
|
378
|
-
this.warnLog(`Color Bulb: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
379
|
-
this.SwitchToOpenAPI = true;
|
|
380
|
-
await this.openAPIRefreshStatus();
|
|
381
|
-
}
|
|
382
369
|
this.apiError(e);
|
|
370
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
|
|
371
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
372
|
+
await this.BLERefreshConnection(switchbot);
|
|
383
373
|
});
|
|
384
374
|
} else {
|
|
385
|
-
await this.
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
async getCustomBLEAddress(switchbot: any) {
|
|
390
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
391
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} customBLEaddress: ${this.device.customBLEaddress}`);
|
|
392
|
-
(async () => {
|
|
393
|
-
// Start to monitor advertisement packets
|
|
394
|
-
await switchbot.startScan({
|
|
395
|
-
model: 'u',
|
|
396
|
-
});
|
|
397
|
-
// Set an event handler
|
|
398
|
-
switchbot.onadvertisement = (ad: any) => {
|
|
399
|
-
this.warnLog(`Color Bulb: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
400
|
-
};
|
|
401
|
-
await switchbot.wait(10000);
|
|
402
|
-
// Stop to monitor
|
|
403
|
-
switchbot.stopScan();
|
|
404
|
-
})();
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
async BLEconnection(switchbot: any): Promise<void> {
|
|
409
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
410
|
-
if (this.platform.config.credentials?.token) {
|
|
411
|
-
this.warnLog(`Color Bulb: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
412
|
-
this.SwitchToOpenAPI = true;
|
|
413
|
-
await this.openAPIRefreshStatus();
|
|
375
|
+
await this.BLERefreshConnection(switchbot);
|
|
414
376
|
}
|
|
415
377
|
}
|
|
416
378
|
|
|
417
379
|
async openAPIRefreshStatus() {
|
|
380
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
418
381
|
try {
|
|
419
382
|
const t = Date.now();
|
|
420
383
|
const nonce = 'requestID';
|
|
421
384
|
const data = this.platform.config.credentials?.token + t + nonce;
|
|
422
385
|
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
423
386
|
const sign = signTerm.toString('base64');
|
|
424
|
-
this.debugLog(
|
|
387
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
425
388
|
const options = {
|
|
426
389
|
hostname: HostDomain,
|
|
427
390
|
port: 443,
|
|
@@ -436,39 +399,36 @@ export class ColorBulb {
|
|
|
436
399
|
},
|
|
437
400
|
};
|
|
438
401
|
const req = https.request(options, (res) => {
|
|
439
|
-
this.debugLog(
|
|
402
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
|
|
403
|
+
this.statusCode({ res });
|
|
440
404
|
let rawData = '';
|
|
441
405
|
res.on('data', (d) => {
|
|
442
406
|
rawData += d;
|
|
443
|
-
this.debugLog(
|
|
407
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
444
408
|
});
|
|
445
409
|
res.on('end', () => {
|
|
446
410
|
try {
|
|
447
411
|
this.deviceStatus = JSON.parse(rawData);
|
|
448
|
-
this.debugLog(
|
|
412
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
449
413
|
this.power = this.deviceStatus.body.power;
|
|
450
414
|
this.color = this.deviceStatus.body.color;
|
|
451
415
|
this.brightness = this.deviceStatus.body.brightness;
|
|
452
416
|
this.colorTemperature = this.deviceStatus.body.colorTemperature;
|
|
453
|
-
this.
|
|
417
|
+
this.openAPIparseStatus();
|
|
454
418
|
this.updateHomeKitCharacteristics();
|
|
455
419
|
} catch (e: any) {
|
|
456
|
-
this.errorLog(
|
|
420
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
457
421
|
}
|
|
458
422
|
});
|
|
459
423
|
});
|
|
460
424
|
req.on('error', (e: any) => {
|
|
461
|
-
this.errorLog(
|
|
425
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
462
426
|
});
|
|
463
427
|
req.end();
|
|
464
428
|
} catch (e: any) {
|
|
465
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
466
|
-
if (this.deviceLogging.includes('debug')) {
|
|
467
|
-
this.errorLog(
|
|
468
|
-
`Color Bulb: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
469
|
-
);
|
|
470
|
-
}
|
|
471
429
|
this.apiError(e);
|
|
430
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
431
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
472
432
|
}
|
|
473
433
|
}
|
|
474
434
|
|
|
@@ -484,8 +444,63 @@ export class ColorBulb {
|
|
|
484
444
|
*
|
|
485
445
|
*/
|
|
486
446
|
async pushChanges(): Promise<void> {
|
|
447
|
+
/*if (this.BLE) {
|
|
448
|
+
await this.BLEpushChanges();
|
|
449
|
+
} else*/ if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
450
|
+
await this.openAPIpushChanges();
|
|
451
|
+
} else {
|
|
452
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
453
|
+
+ ` ${this.device.connectionType}, pushChanges will not happen.`);
|
|
454
|
+
}
|
|
455
|
+
interval(5000)
|
|
456
|
+
.pipe(take(1))
|
|
457
|
+
.subscribe(async () => {
|
|
458
|
+
await this.refreshStatus();
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
async BLEpushChanges(): Promise<void> {
|
|
463
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
|
|
464
|
+
if (this.On !== this.accessory.context.On) {
|
|
465
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges On: ${this.On} OnCached: ${this.accessory.context.On}`);
|
|
466
|
+
const switchbot = await this.platform.connectBLE();
|
|
467
|
+
// Convert to BLE Address
|
|
468
|
+
this.device.bleMac = this.device
|
|
469
|
+
.deviceId!.match(/.{1,2}/g)!
|
|
470
|
+
.join(':')
|
|
471
|
+
.toLowerCase();
|
|
472
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
473
|
+
switchbot
|
|
474
|
+
.discover({
|
|
475
|
+
model: 'u',
|
|
476
|
+
id: this.device.bleMac,
|
|
477
|
+
})
|
|
478
|
+
.then((device_list: any) => {
|
|
479
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
480
|
+
return this.turnOnOff(device_list);
|
|
481
|
+
})
|
|
482
|
+
.then(() => {
|
|
483
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
|
|
484
|
+
this.On = false;
|
|
485
|
+
})
|
|
486
|
+
.catch(async (e: any) => {
|
|
487
|
+
this.apiError(e);
|
|
488
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
|
|
489
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
490
|
+
await this.BLEPushConnection();
|
|
491
|
+
});
|
|
492
|
+
} else {
|
|
493
|
+
this.debugLog(
|
|
494
|
+
`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `On: ${this.On}, `
|
|
495
|
+
+`OnCached: ${this.accessory.context.On}`,
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
async openAPIpushChanges(): Promise<void> {
|
|
487
501
|
try {
|
|
488
|
-
|
|
502
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
|
|
503
|
+
if (this.On !== this.accessory.context.On) {
|
|
489
504
|
// Make Push On request to the API
|
|
490
505
|
const t = Date.now();
|
|
491
506
|
const nonce = 'requestID';
|
|
@@ -494,7 +509,7 @@ export class ColorBulb {
|
|
|
494
509
|
.update(Buffer.from(data, 'utf-8'))
|
|
495
510
|
.digest();
|
|
496
511
|
const sign = signTerm.toString('base64');
|
|
497
|
-
this.debugLog(
|
|
512
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
498
513
|
|
|
499
514
|
let command = '';
|
|
500
515
|
if (this.On) {
|
|
@@ -502,12 +517,12 @@ export class ColorBulb {
|
|
|
502
517
|
} else {
|
|
503
518
|
command = 'turnOff';
|
|
504
519
|
}
|
|
505
|
-
const body =
|
|
520
|
+
const body = superStringify({
|
|
506
521
|
'command': `${command}`,
|
|
507
522
|
'parameter': 'default',
|
|
508
523
|
'commandType': 'command',
|
|
509
524
|
});
|
|
510
|
-
this.infoLog(
|
|
525
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
|
|
511
526
|
const options = {
|
|
512
527
|
hostname: HostDomain,
|
|
513
528
|
port: 443,
|
|
@@ -523,55 +538,53 @@ export class ColorBulb {
|
|
|
523
538
|
},
|
|
524
539
|
};
|
|
525
540
|
const req = https.request(options, res => {
|
|
526
|
-
this.debugLog(
|
|
541
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges statusCode: ${res.statusCode}`);
|
|
527
542
|
this.statusCode({ res });
|
|
528
543
|
res.on('data', d => {
|
|
529
|
-
this.debugLog(
|
|
544
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
530
545
|
});
|
|
531
546
|
});
|
|
532
547
|
req.on('error', (e: any) => {
|
|
533
|
-
this.errorLog(
|
|
548
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
534
549
|
});
|
|
535
550
|
req.write(body);
|
|
536
551
|
req.end();
|
|
537
|
-
this.debugLog(
|
|
538
|
-
|
|
539
|
-
this.
|
|
552
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushChanges: ${superStringify(req)}`);
|
|
553
|
+
} else {
|
|
554
|
+
this.debugLog(
|
|
555
|
+
`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` + `On: ${this.On}, `
|
|
556
|
+
+`OnCached: ${this.accessory.context.On}`,
|
|
557
|
+
);
|
|
540
558
|
}
|
|
541
559
|
// Push Brightness Update
|
|
542
560
|
if (this.On) {
|
|
543
|
-
|
|
561
|
+
await this.pushBrightnessChanges();
|
|
544
562
|
}
|
|
545
|
-
|
|
546
563
|
// Push ColorTemperature Update
|
|
547
564
|
if (this.On) {
|
|
548
|
-
|
|
565
|
+
await this.pushColorTemperatureChanges();
|
|
549
566
|
}
|
|
550
|
-
|
|
551
567
|
// Push Hue & Saturation Update
|
|
552
568
|
if (this.On) {
|
|
553
569
|
await this.pushHueSaturationChanges();
|
|
554
570
|
}
|
|
555
571
|
} catch (e: any) {
|
|
556
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
557
|
-
if (this.deviceLogging.includes('debug')) {
|
|
558
|
-
this.errorLog(
|
|
559
|
-
`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
560
|
-
);
|
|
561
|
-
}
|
|
562
572
|
this.apiError(e);
|
|
573
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
|
|
574
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`,
|
|
575
|
+
);
|
|
563
576
|
}
|
|
564
577
|
}
|
|
565
578
|
|
|
566
579
|
async pushHueSaturationChanges(): Promise<void> {
|
|
567
580
|
try {
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
this.debugLog(
|
|
581
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges`);
|
|
582
|
+
if (this.Hue !== this.accessory.context.Hue || this.Saturation !== this.accessory.context.Saturation) {
|
|
583
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${superStringify(this.Hue)}`);
|
|
584
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${superStringify(this.Saturation)}`);
|
|
571
585
|
|
|
572
586
|
const [red, green, blue] = hs2rgb(Number(this.Hue), Number(this.Saturation));
|
|
573
|
-
this.debugLog(
|
|
574
|
-
|
|
587
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} rgb: ${superStringify([red, green, blue])}`);
|
|
575
588
|
// Make Push Hue/Saturation request to the API
|
|
576
589
|
const t = Date.now();
|
|
577
590
|
const nonce = 'requestID';
|
|
@@ -580,13 +593,13 @@ export class ColorBulb {
|
|
|
580
593
|
.update(Buffer.from(data, 'utf-8'))
|
|
581
594
|
.digest();
|
|
582
595
|
const sign = signTerm.toString('base64');
|
|
583
|
-
this.debugLog(
|
|
584
|
-
const body =
|
|
596
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
597
|
+
const body = superStringify({
|
|
585
598
|
'command': 'setColor',
|
|
586
599
|
'parameter': `${red}:${green}:${blue}`,
|
|
587
600
|
'commandType': 'command',
|
|
588
601
|
});
|
|
589
|
-
this.infoLog(
|
|
602
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
|
|
590
603
|
const options = {
|
|
591
604
|
hostname: HostDomain,
|
|
592
605
|
port: 443,
|
|
@@ -602,39 +615,32 @@ export class ColorBulb {
|
|
|
602
615
|
},
|
|
603
616
|
};
|
|
604
617
|
const req = https.request(options, res => {
|
|
605
|
-
this.debugLog(
|
|
618
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges statusCode: ${res.statusCode}`);
|
|
606
619
|
res.on('data', d => {
|
|
607
|
-
this.debugLog(
|
|
620
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
608
621
|
});
|
|
609
622
|
});
|
|
610
623
|
req.on('error', (e: any) => {
|
|
611
|
-
this.errorLog(
|
|
624
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
612
625
|
});
|
|
613
626
|
req.write(body);
|
|
614
627
|
req.end();
|
|
615
|
-
this.debugLog(
|
|
616
|
-
this.HueCached = this.Hue;
|
|
617
|
-
this.SaturationCached = this.Saturation;
|
|
628
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges: ${superStringify(req)}`);
|
|
618
629
|
} else {
|
|
619
|
-
this.debugLog(
|
|
620
|
-
|
|
621
|
-
`Hue: ${this.Hue}, HueCached: ${this.HueCached}, Saturation: ${this.Saturation}, SaturationCached: ${this.SaturationCached}`,
|
|
622
|
-
);
|
|
630
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushHueSaturationChanges. Hue: ${this.Hue}, `
|
|
631
|
+
+ `HueCached: ${this.accessory.context.Hue}, Saturation: ${this.Saturation}, SaturationCached: ${this.accessory.context.Saturation}`);
|
|
623
632
|
}
|
|
624
633
|
} catch (e: any) {
|
|
625
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
626
|
-
if (this.deviceLogging.includes('debug')) {
|
|
627
|
-
this.errorLog(
|
|
628
|
-
`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
629
|
-
);
|
|
630
|
-
}
|
|
631
634
|
this.apiError(e);
|
|
635
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushHueSaturationChanges with ${this.device.connectionType}`
|
|
636
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
632
637
|
}
|
|
633
638
|
}
|
|
634
639
|
|
|
635
640
|
async pushColorTemperatureChanges(): Promise<void> {
|
|
636
641
|
try {
|
|
637
|
-
|
|
642
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushColorTemperatureChanges`);
|
|
643
|
+
if (this.ColorTemperature !== this.accessory.context.ColorTemperature) {
|
|
638
644
|
const kelvin = Math.round(1000000 / Number(this.ColorTemperature));
|
|
639
645
|
this.cacheKelvin = kelvin;
|
|
640
646
|
|
|
@@ -646,13 +652,13 @@ export class ColorBulb {
|
|
|
646
652
|
.update(Buffer.from(data, 'utf-8'))
|
|
647
653
|
.digest();
|
|
648
654
|
const sign = signTerm.toString('base64');
|
|
649
|
-
this.debugLog(
|
|
650
|
-
const body =
|
|
655
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
656
|
+
const body = superStringify({
|
|
651
657
|
'command': 'setColorTemperature',
|
|
652
658
|
'parameter': `${kelvin}`,
|
|
653
659
|
'commandType': 'command',
|
|
654
660
|
});
|
|
655
|
-
this.infoLog(
|
|
661
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
|
|
656
662
|
const options = {
|
|
657
663
|
hostname: HostDomain,
|
|
658
664
|
port: 443,
|
|
@@ -668,39 +674,33 @@ export class ColorBulb {
|
|
|
668
674
|
},
|
|
669
675
|
};
|
|
670
676
|
const req = https.request(options, res => {
|
|
671
|
-
this.debugLog(
|
|
677
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
672
678
|
res.on('data', d => {
|
|
673
|
-
this.debugLog(
|
|
679
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
674
680
|
});
|
|
675
681
|
});
|
|
676
682
|
req.on('error', (e: any) => {
|
|
677
|
-
this.errorLog(
|
|
683
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
678
684
|
});
|
|
679
685
|
req.write(body);
|
|
680
686
|
req.end();
|
|
681
|
-
|
|
682
|
-
this.
|
|
683
|
-
this.ColorTemperatureCached = this.ColorTemperature;
|
|
687
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushColorTemperatureChanges: ${superStringify(req)}`);
|
|
688
|
+
this.accessory.context.ColorTemperature = this.ColorTemperature;
|
|
684
689
|
} else {
|
|
685
|
-
this.debugLog(
|
|
686
|
-
|
|
687
|
-
`ColorTemperature: ${this.ColorTemperature}, ColorTemperatureCached: ${this.ColorTemperatureCached}`,
|
|
688
|
-
);
|
|
690
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushColorTemperatureChanges.` +
|
|
691
|
+
`ColorTemperature: ${this.ColorTemperature}, ColorTemperatureCached: ${this.accessory.context.ColorTemperature}`);
|
|
689
692
|
}
|
|
690
693
|
} catch (e: any) {
|
|
691
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
692
|
-
if (this.deviceLogging.includes('debug')) {
|
|
693
|
-
this.errorLog(
|
|
694
|
-
`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
695
|
-
);
|
|
696
|
-
}
|
|
697
694
|
this.apiError(e);
|
|
695
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushColorTemperatureChanges with ${this.device.connectionType}`
|
|
696
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
698
697
|
}
|
|
699
698
|
}
|
|
700
699
|
|
|
701
700
|
async pushBrightnessChanges(): Promise<void> {
|
|
702
701
|
try {
|
|
703
|
-
|
|
702
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges`);
|
|
703
|
+
if (this.Brightness !== this.accessory.context.Brightness) {
|
|
704
704
|
// Make Push On request to the API
|
|
705
705
|
const t = Date.now();
|
|
706
706
|
const nonce = 'requestID';
|
|
@@ -709,13 +709,13 @@ export class ColorBulb {
|
|
|
709
709
|
.update(Buffer.from(data, 'utf-8'))
|
|
710
710
|
.digest();
|
|
711
711
|
const sign = signTerm.toString('base64');
|
|
712
|
-
this.debugLog(
|
|
713
|
-
const body =
|
|
712
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
713
|
+
const body = superStringify({
|
|
714
714
|
'command': 'setBrightness',
|
|
715
715
|
'parameter': `${this.Brightness}`,
|
|
716
716
|
'commandType': 'command',
|
|
717
717
|
});
|
|
718
|
-
this.infoLog(
|
|
718
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
|
|
719
719
|
const options = {
|
|
720
720
|
hostname: HostDomain,
|
|
721
721
|
port: 443,
|
|
@@ -731,117 +731,25 @@ export class ColorBulb {
|
|
|
731
731
|
},
|
|
732
732
|
};
|
|
733
733
|
const req = https.request(options, res => {
|
|
734
|
-
this.debugLog(
|
|
734
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges statusCode: ${res.statusCode}`);
|
|
735
735
|
res.on('data', d => {
|
|
736
|
-
this.debugLog(
|
|
736
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
737
737
|
});
|
|
738
738
|
});
|
|
739
739
|
req.on('error', (e: any) => {
|
|
740
|
-
this.errorLog(
|
|
740
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
741
741
|
});
|
|
742
742
|
req.write(body);
|
|
743
743
|
req.end();
|
|
744
|
-
this.debugLog(
|
|
745
|
-
this.BrightnessCached = this.Brightness;
|
|
744
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges: ${superStringify(req)}`);
|
|
746
745
|
} else {
|
|
747
|
-
this.debugLog(
|
|
748
|
-
|
|
749
|
-
);
|
|
746
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushBrightnessChanges.` + `Brightness: ${this.Brightness}, `
|
|
747
|
+
+`BrightnessCached: ${this.accessory.context.Brightness}`);
|
|
750
748
|
}
|
|
751
749
|
} catch (e: any) {
|
|
752
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
753
|
-
if (this.deviceLogging.includes('debug')) {
|
|
754
|
-
this.errorLog(
|
|
755
|
-
`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
756
|
-
);
|
|
757
|
-
}
|
|
758
750
|
this.apiError(e);
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
async updateHomeKitCharacteristics(): Promise<void> {
|
|
763
|
-
if (this.On === undefined) {
|
|
764
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} On: ${this.On}`);
|
|
765
|
-
} else {
|
|
766
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.On, this.On);
|
|
767
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
|
|
768
|
-
}
|
|
769
|
-
if (this.Brightness === undefined) {
|
|
770
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
|
|
771
|
-
} else {
|
|
772
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Brightness, this.Brightness);
|
|
773
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic Brightness: ${this.Brightness}`);
|
|
774
|
-
}
|
|
775
|
-
if (this.ColorTemperature === undefined) {
|
|
776
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
|
|
777
|
-
} else {
|
|
778
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, this.ColorTemperature);
|
|
779
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic ColorTemperature: ${this.ColorTemperature}`);
|
|
780
|
-
}
|
|
781
|
-
if (this.Hue === undefined) {
|
|
782
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} Hue: ${this.Hue}`);
|
|
783
|
-
} else {
|
|
784
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Hue, this.Hue);
|
|
785
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic Hue: ${this.Hue}`);
|
|
786
|
-
}
|
|
787
|
-
if (this.Saturation === undefined) {
|
|
788
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
|
|
789
|
-
} else {
|
|
790
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Saturation, this.Saturation);
|
|
791
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic Saturation: ${this.Saturation}`);
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
apiError(e: any): void {
|
|
796
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.On, e);
|
|
797
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Hue, e);
|
|
798
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Brightness, e);
|
|
799
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Saturation, e);
|
|
800
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, e);
|
|
801
|
-
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
805
|
-
switch (res.statusCode) {
|
|
806
|
-
case 151:
|
|
807
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
808
|
-
break;
|
|
809
|
-
case 152:
|
|
810
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} Device not found.`);
|
|
811
|
-
break;
|
|
812
|
-
case 160:
|
|
813
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} Command is not supported.`);
|
|
814
|
-
break;
|
|
815
|
-
case 161:
|
|
816
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} Device is offline.`);
|
|
817
|
-
this.offlineOff();
|
|
818
|
-
break;
|
|
819
|
-
case 171:
|
|
820
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
|
|
821
|
-
this.offlineOff();
|
|
822
|
-
break;
|
|
823
|
-
case 190:
|
|
824
|
-
this.errorLog(
|
|
825
|
-
`Color Bulb: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
826
|
-
` Or command: ${JSON.stringify(res)} format is invalid`,
|
|
827
|
-
);
|
|
828
|
-
break;
|
|
829
|
-
case 100:
|
|
830
|
-
if (this.platform.debugMode) {
|
|
831
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} Command successfully sent.`);
|
|
832
|
-
}
|
|
833
|
-
break;
|
|
834
|
-
default:
|
|
835
|
-
if (this.platform.debugMode) {
|
|
836
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} Unknown statusCode.`);
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
async offlineOff(): Promise<void> {
|
|
842
|
-
if (this.device.offline) {
|
|
843
|
-
this.On = false;
|
|
844
|
-
this.lightBulbService.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
|
|
751
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushBrightnessChanges with ${this.device.connectionType}`
|
|
752
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
845
753
|
}
|
|
846
754
|
}
|
|
847
755
|
|
|
@@ -849,7 +757,11 @@ export class ColorBulb {
|
|
|
849
757
|
* Handle requests to set the value of the "On" characteristic
|
|
850
758
|
*/
|
|
851
759
|
async OnSet(value: CharacteristicValue): Promise<void> {
|
|
852
|
-
this.
|
|
760
|
+
if (this.On === this.accessory.context.On) {
|
|
761
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set On: ${value}`);
|
|
762
|
+
} else {
|
|
763
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set On: ${value}`);
|
|
764
|
+
}
|
|
853
765
|
|
|
854
766
|
this.On = value;
|
|
855
767
|
this.doColorBulbUpdate.next();
|
|
@@ -859,7 +771,13 @@ export class ColorBulb {
|
|
|
859
771
|
* Handle requests to set the value of the "Brightness" characteristic
|
|
860
772
|
*/
|
|
861
773
|
async BrightnessSet(value: CharacteristicValue): Promise<void> {
|
|
862
|
-
this.
|
|
774
|
+
if (this.Brightness === this.accessory.context.Brightness) {
|
|
775
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set Brightness: ${value}`);
|
|
776
|
+
} else if (this.On) {
|
|
777
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Brightness: ${value}`);
|
|
778
|
+
} else {
|
|
779
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Brightness: ${value}`);
|
|
780
|
+
}
|
|
863
781
|
|
|
864
782
|
this.Brightness = value;
|
|
865
783
|
this.doColorBulbUpdate.next();
|
|
@@ -869,7 +787,13 @@ export class ColorBulb {
|
|
|
869
787
|
* Handle requests to set the value of the "ColorTemperature" characteristic
|
|
870
788
|
*/
|
|
871
789
|
async ColorTemperatureSet(value: CharacteristicValue): Promise<void> {
|
|
872
|
-
this.
|
|
790
|
+
if (this.ColorTemperature === this.accessory.context.ColorTemperature) {
|
|
791
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set ColorTemperature: ${value}`);
|
|
792
|
+
} else if (this.On) {
|
|
793
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set ColorTemperature: ${value}`);
|
|
794
|
+
} else {
|
|
795
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Set ColorTemperature: ${value}`);
|
|
796
|
+
}
|
|
873
797
|
|
|
874
798
|
// Convert mired to kelvin to nearest 100 (SwitchBot seems to need this)
|
|
875
799
|
const kelvin = Math.round(1000000 / Number(value) / 100) * 100;
|
|
@@ -877,7 +801,7 @@ export class ColorBulb {
|
|
|
877
801
|
// Check and increase/decrease kelvin to range of device
|
|
878
802
|
const k = Math.min(Math.max(kelvin, this.minKelvin), this.maxKelvin);
|
|
879
803
|
|
|
880
|
-
if (!this.
|
|
804
|
+
if (!this.accessory.context.On || this.cacheKelvin === k) {
|
|
881
805
|
return;
|
|
882
806
|
}
|
|
883
807
|
|
|
@@ -894,7 +818,13 @@ export class ColorBulb {
|
|
|
894
818
|
* Handle requests to set the value of the "Hue" characteristic
|
|
895
819
|
*/
|
|
896
820
|
async HueSet(value: CharacteristicValue): Promise<void> {
|
|
897
|
-
this.
|
|
821
|
+
if (this.Hue === this.accessory.context.Hue) {
|
|
822
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set Hue: ${value}`);
|
|
823
|
+
} else if (this.On) {
|
|
824
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Hue: ${value}`);
|
|
825
|
+
} else {
|
|
826
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Hue: ${value}`);
|
|
827
|
+
}
|
|
898
828
|
|
|
899
829
|
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, 140);
|
|
900
830
|
|
|
@@ -906,7 +836,13 @@ export class ColorBulb {
|
|
|
906
836
|
* Handle requests to set the value of the "Saturation" characteristic
|
|
907
837
|
*/
|
|
908
838
|
async SaturationSet(value: CharacteristicValue): Promise<void> {
|
|
909
|
-
this.
|
|
839
|
+
if (this.Saturation === this.accessory.context.Saturation) {
|
|
840
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set Saturation: ${value}`);
|
|
841
|
+
} else if (this.On) {
|
|
842
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Saturation: ${value}`);
|
|
843
|
+
} else {
|
|
844
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Saturation: ${value}`);
|
|
845
|
+
}
|
|
910
846
|
|
|
911
847
|
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, 140);
|
|
912
848
|
|
|
@@ -914,76 +850,205 @@ export class ColorBulb {
|
|
|
914
850
|
this.doColorBulbUpdate.next();
|
|
915
851
|
}
|
|
916
852
|
|
|
917
|
-
async
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
853
|
+
async updateHomeKitCharacteristics(): Promise<void> {
|
|
854
|
+
if (this.On === undefined) {
|
|
855
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
856
|
+
} else {
|
|
857
|
+
this.accessory.context.On = this.On;
|
|
858
|
+
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.On, this.On);
|
|
859
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
|
|
921
860
|
}
|
|
922
|
-
if (
|
|
923
|
-
|
|
861
|
+
if (this.Brightness === undefined) {
|
|
862
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
|
|
863
|
+
} else {
|
|
864
|
+
this.accessory.context.Brightness = this.Brightness;
|
|
865
|
+
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Brightness, this.Brightness);
|
|
866
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Brightness: ${this.Brightness}`);
|
|
924
867
|
}
|
|
925
|
-
if (
|
|
926
|
-
|
|
868
|
+
if (this.ColorTemperature === undefined) {
|
|
869
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
|
|
870
|
+
} else {
|
|
871
|
+
this.accessory.context.ColorTemperature = this.ColorTemperature;
|
|
872
|
+
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, this.ColorTemperature);
|
|
873
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic ColorTemperature: ${this.ColorTemperature}`);
|
|
927
874
|
}
|
|
928
|
-
if (
|
|
929
|
-
|
|
875
|
+
if (this.Hue === undefined) {
|
|
876
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.Hue}`);
|
|
877
|
+
} else {
|
|
878
|
+
this.accessory.context.Hue = this.Hue;
|
|
879
|
+
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Hue, this.Hue);
|
|
880
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Hue: ${this.Hue}`);
|
|
930
881
|
}
|
|
931
|
-
if (
|
|
932
|
-
|
|
882
|
+
if (this.Saturation === undefined) {
|
|
883
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
|
|
884
|
+
} else {
|
|
885
|
+
this.accessory.context.Saturation = this.Saturation;
|
|
886
|
+
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Saturation, this.Saturation);
|
|
887
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Saturation: ${this.Saturation}`);
|
|
933
888
|
}
|
|
934
|
-
|
|
935
|
-
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
async adaptiveLighting(device: device & devicesConfig): Promise<void> {
|
|
892
|
+
if (device.colorbulb?.adaptiveLightingShift) {
|
|
893
|
+
this.adaptiveLightingShift = device.colorbulb.adaptiveLightingShift;
|
|
894
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
895
|
+
} else {
|
|
896
|
+
this.adaptiveLightingShift = 0;
|
|
897
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
936
898
|
}
|
|
937
|
-
|
|
938
|
-
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
async getCustomBLEAddress(switchbot: any) {
|
|
902
|
+
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
903
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} customBLEaddress: ${this.device.customBLEaddress}`);
|
|
904
|
+
(async () => {
|
|
905
|
+
// Start to monitor advertisement packets
|
|
906
|
+
await switchbot.startScan({
|
|
907
|
+
model: 'u',
|
|
908
|
+
});
|
|
909
|
+
// Set an event handler
|
|
910
|
+
switchbot.onadvertisement = (ad: any) => {
|
|
911
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
|
|
912
|
+
};
|
|
913
|
+
await switchbot.wait(10000);
|
|
914
|
+
// Stop to monitor
|
|
915
|
+
switchbot.stopScan();
|
|
916
|
+
})();
|
|
939
917
|
}
|
|
940
918
|
}
|
|
941
919
|
|
|
942
|
-
async
|
|
943
|
-
if (device.
|
|
944
|
-
this.
|
|
945
|
-
this.
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
|
|
920
|
+
async BLEPushConnection() {
|
|
921
|
+
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
922
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
|
|
923
|
+
await this.openAPIpushChanges();
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
async BLERefreshConnection(switchbot: any): Promise<void> {
|
|
928
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
929
|
+
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
930
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
|
|
931
|
+
await this.openAPIRefreshStatus();
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
async turnOnOff(device_list: any): Promise<any> {
|
|
936
|
+
return await this.retry({
|
|
937
|
+
max: await this.maxRetry(),
|
|
938
|
+
fn: () => {
|
|
939
|
+
if (this.On) {
|
|
940
|
+
return device_list[0].turnOn({ id: this.device.bleMac });
|
|
941
|
+
} else {
|
|
942
|
+
return device_list[0].turnOff({ id: this.device.bleMac });
|
|
943
|
+
}
|
|
944
|
+
},
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
async retry({ max, fn }: { max: number; fn: { (): any; (): Promise<any> } }): Promise<null> {
|
|
949
|
+
return fn().catch(async (err: any) => {
|
|
950
|
+
if (max === 0) {
|
|
951
|
+
throw err;
|
|
952
|
+
}
|
|
953
|
+
this.infoLog(err);
|
|
954
|
+
this.infoLog('Retrying');
|
|
955
|
+
await this.switchbot.wait(1000);
|
|
956
|
+
return this.retry({ max: max - 1, fn });
|
|
957
|
+
});
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
async maxRetry(): Promise<number> {
|
|
961
|
+
let maxRetry: number;
|
|
962
|
+
if (this.device.bot?.maxRetry) {
|
|
963
|
+
maxRetry = this.device.bot?.maxRetry;
|
|
964
|
+
} else {
|
|
965
|
+
maxRetry = 5;
|
|
966
|
+
}
|
|
967
|
+
return maxRetry;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
minStep(device: device & devicesConfig): number {
|
|
971
|
+
if (device.colorbulb?.set_minStep) {
|
|
972
|
+
this.set_minStep = device.colorbulb?.set_minStep;
|
|
973
|
+
} else {
|
|
974
|
+
this.set_minStep = 1;
|
|
949
975
|
}
|
|
976
|
+
return this.set_minStep;
|
|
950
977
|
}
|
|
951
978
|
|
|
952
979
|
async scan(device: device & devicesConfig): Promise<void> {
|
|
953
980
|
if (device.scanDuration) {
|
|
954
981
|
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
955
|
-
if (
|
|
956
|
-
this.debugLog(
|
|
982
|
+
if (this.BLE) {
|
|
983
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
957
984
|
}
|
|
958
985
|
} else {
|
|
959
986
|
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
960
|
-
if (this.
|
|
961
|
-
this.debugLog(
|
|
987
|
+
if (this.BLE) {
|
|
988
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
962
989
|
}
|
|
963
990
|
}
|
|
964
991
|
}
|
|
965
992
|
|
|
966
|
-
async
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
993
|
+
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
994
|
+
switch (res.statusCode) {
|
|
995
|
+
case 151:
|
|
996
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
997
|
+
break;
|
|
998
|
+
case 152:
|
|
999
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
|
|
1000
|
+
break;
|
|
1001
|
+
case 160:
|
|
1002
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
|
|
1003
|
+
break;
|
|
1004
|
+
case 161:
|
|
1005
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
|
|
1006
|
+
this.offlineOff();
|
|
1007
|
+
break;
|
|
1008
|
+
case 171:
|
|
1009
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
|
|
1010
|
+
this.offlineOff();
|
|
1011
|
+
break;
|
|
1012
|
+
case 190:
|
|
1013
|
+
this.errorLog(
|
|
1014
|
+
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
1015
|
+
` Or command: ${superStringify(res)} format is invalid`,
|
|
1016
|
+
);
|
|
1017
|
+
break;
|
|
1018
|
+
case 100:
|
|
1019
|
+
if (this.platform.debugMode) {
|
|
1020
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
|
|
1021
|
+
}
|
|
1022
|
+
break;
|
|
1023
|
+
default:
|
|
1024
|
+
if (this.platform.debugMode) {
|
|
1025
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
async offlineOff(): Promise<void> {
|
|
1031
|
+
if (this.device.offline) {
|
|
1032
|
+
this.On = false;
|
|
1033
|
+
this.lightBulbService.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
|
|
1034
|
+
await this.updateHomeKitCharacteristics();
|
|
979
1035
|
}
|
|
980
1036
|
}
|
|
981
1037
|
|
|
1038
|
+
apiError(e: any): void {
|
|
1039
|
+
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.On, e);
|
|
1040
|
+
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Hue, e);
|
|
1041
|
+
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Brightness, e);
|
|
1042
|
+
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Saturation, e);
|
|
1043
|
+
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, e);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
982
1046
|
FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
|
|
983
1047
|
let FirmwareRevision: string;
|
|
984
|
-
this.debugLog(
|
|
985
|
-
|
|
986
|
-
this.debugLog(
|
|
1048
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
1049
|
+
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
1050
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
1051
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
987
1052
|
if (accessory.context.FirmwareRevision) {
|
|
988
1053
|
FirmwareRevision = accessory.context.FirmwareRevision;
|
|
989
1054
|
} else if (device.firmware) {
|
|
@@ -994,23 +1059,88 @@ export class ColorBulb {
|
|
|
994
1059
|
return FirmwareRevision;
|
|
995
1060
|
}
|
|
996
1061
|
|
|
997
|
-
|
|
998
|
-
if (
|
|
999
|
-
this.
|
|
1000
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
1062
|
+
private context() {
|
|
1063
|
+
if (this.On === undefined) {
|
|
1064
|
+
this.On = false;
|
|
1001
1065
|
} else {
|
|
1002
|
-
this.
|
|
1003
|
-
|
|
1066
|
+
this.On = this.accessory.context.On;
|
|
1067
|
+
}
|
|
1068
|
+
if (this.Hue === undefined) {
|
|
1069
|
+
this.Hue = 0;
|
|
1070
|
+
} else {
|
|
1071
|
+
this.Hue = this.accessory.context.Hue;
|
|
1072
|
+
}
|
|
1073
|
+
if (this.Brightness === undefined) {
|
|
1074
|
+
this.Brightness = 0;
|
|
1075
|
+
} else {
|
|
1076
|
+
this.Brightness = this.accessory.context.Brightness;
|
|
1077
|
+
}
|
|
1078
|
+
if (this.Brightness === undefined) {
|
|
1079
|
+
this.Saturation = 0;
|
|
1080
|
+
} else {
|
|
1081
|
+
this.Saturation = this.accessory.context.Saturation;
|
|
1004
1082
|
}
|
|
1083
|
+
if (this.ColorTemperature === undefined) {
|
|
1084
|
+
this.ColorTemperature = 140;
|
|
1085
|
+
} else {
|
|
1086
|
+
this.ColorTemperature = this.accessory.context.ColorTemperature;
|
|
1087
|
+
}
|
|
1088
|
+
this.minKelvin = 2000;
|
|
1089
|
+
this.maxKelvin = 9000;
|
|
1005
1090
|
}
|
|
1006
1091
|
|
|
1007
|
-
|
|
1008
|
-
if (device.
|
|
1009
|
-
this.
|
|
1092
|
+
async refreshRate(device: device & devicesConfig): Promise<void> {
|
|
1093
|
+
if (device.refreshRate) {
|
|
1094
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
1095
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
1096
|
+
} else if (this.platform.config.options!.refreshRate) {
|
|
1097
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
1098
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
async config(device: device & devicesConfig): Promise<void> {
|
|
1103
|
+
let config = {};
|
|
1104
|
+
if (device.colorbulb) {
|
|
1105
|
+
config = device.colorbulb;
|
|
1106
|
+
}
|
|
1107
|
+
if (device.connectionType !== undefined) {
|
|
1108
|
+
config['connectionType'] = device.connectionType;
|
|
1109
|
+
}
|
|
1110
|
+
if (device.external !== undefined) {
|
|
1111
|
+
config['external'] = device.external;
|
|
1112
|
+
}
|
|
1113
|
+
if (device.logging !== undefined) {
|
|
1114
|
+
config['logging'] = device.logging;
|
|
1115
|
+
}
|
|
1116
|
+
if (device.refreshRate !== undefined) {
|
|
1117
|
+
config['refreshRate'] = device.refreshRate;
|
|
1118
|
+
}
|
|
1119
|
+
if (device.scanDuration !== undefined) {
|
|
1120
|
+
config['scanDuration'] = device.scanDuration;
|
|
1121
|
+
}
|
|
1122
|
+
if (device.offline !== undefined) {
|
|
1123
|
+
config['offline'] = device.offline;
|
|
1124
|
+
}
|
|
1125
|
+
if (Object.entries(config).length !== 0) {
|
|
1126
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
async logs(device: device & devicesConfig): Promise<void> {
|
|
1131
|
+
if (this.platform.debugMode) {
|
|
1132
|
+
this.deviceLogging = this.accessory.context.logging = 'debugMode';
|
|
1133
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
|
1134
|
+
} else if (device.logging) {
|
|
1135
|
+
this.deviceLogging = this.accessory.context.logging = device.logging;
|
|
1136
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
1137
|
+
} else if (this.platform.config.options?.logging) {
|
|
1138
|
+
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
1139
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
1010
1140
|
} else {
|
|
1011
|
-
this.
|
|
1141
|
+
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
1142
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
1012
1143
|
}
|
|
1013
|
-
return this.set_minStep;
|
|
1014
1144
|
}
|
|
1015
1145
|
|
|
1016
1146
|
/**
|
|
@@ -1028,12 +1158,28 @@ export class ColorBulb {
|
|
|
1028
1158
|
}
|
|
1029
1159
|
}
|
|
1030
1160
|
|
|
1161
|
+
debugWarnLog(...log: any[]): void {
|
|
1162
|
+
if (this.enablingDeviceLogging()) {
|
|
1163
|
+
if (this.deviceLogging?.includes('debug')) {
|
|
1164
|
+
this.platform.log.warn('[DEBUG]', String(...log));
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1031
1169
|
errorLog(...log: any[]): void {
|
|
1032
1170
|
if (this.enablingDeviceLogging()) {
|
|
1033
1171
|
this.platform.log.error(String(...log));
|
|
1034
1172
|
}
|
|
1035
1173
|
}
|
|
1036
1174
|
|
|
1175
|
+
debugErrorLog(...log: any[]): void {
|
|
1176
|
+
if (this.enablingDeviceLogging()) {
|
|
1177
|
+
if (this.deviceLogging?.includes('debug')) {
|
|
1178
|
+
this.platform.log.error('[DEBUG]', String(...log));
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1037
1183
|
debugLog(...log: any[]): void {
|
|
1038
1184
|
if (this.enablingDeviceLogging()) {
|
|
1039
1185
|
if (this.deviceLogging === 'debug') {
|