@switchbot/homebridge-switchbot 2.0.0-beta.9 → 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 -14
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +472 -297
- 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 +482 -334
- 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
|
|
|
@@ -35,7 +36,6 @@ export class ColorBulb {
|
|
|
35
36
|
connected?: boolean;
|
|
36
37
|
switchbot!: switchbot;
|
|
37
38
|
address!: ad['address'];
|
|
38
|
-
SwitchToOpenAPI?: boolean;
|
|
39
39
|
serviceData!: serviceData;
|
|
40
40
|
state: serviceData['state'];
|
|
41
41
|
delay: serviceData['delay'];
|
|
@@ -60,6 +60,10 @@ export class ColorBulb {
|
|
|
60
60
|
colorBulbUpdateInProgress!: boolean;
|
|
61
61
|
doColorBulbUpdate!: Subject<void>;
|
|
62
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
|
+
|
|
63
67
|
constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
|
|
64
68
|
// default placeholders
|
|
65
69
|
this.logs(device);
|
|
@@ -67,17 +71,7 @@ export class ColorBulb {
|
|
|
67
71
|
this.refreshRate(device);
|
|
68
72
|
this.adaptiveLighting(device);
|
|
69
73
|
this.config(device);
|
|
70
|
-
|
|
71
|
-
this.On = false;
|
|
72
|
-
} else {
|
|
73
|
-
this.On = this.accessory.context.On;
|
|
74
|
-
}
|
|
75
|
-
this.Hue = 0;
|
|
76
|
-
this.Brightness = 0;
|
|
77
|
-
this.Saturation = 0;
|
|
78
|
-
this.ColorTemperature = 140;
|
|
79
|
-
this.minKelvin = 2000;
|
|
80
|
-
this.maxKelvin = 9000;
|
|
74
|
+
this.context();
|
|
81
75
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
82
76
|
this.doColorBulbUpdate = new Subject();
|
|
83
77
|
this.colorBulbUpdateInProgress = false;
|
|
@@ -104,7 +98,7 @@ export class ColorBulb {
|
|
|
104
98
|
this.accessory.removeService(this.lightBulbService);
|
|
105
99
|
this.lightBulbService = this.accessory.addService(this.platform.Service.Lightbulb);
|
|
106
100
|
this.accessory.context.adaptiveLighting = false;
|
|
107
|
-
this.debugLog(
|
|
101
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLighting: ${this.accessory.context.adaptiveLighting}`);
|
|
108
102
|
}
|
|
109
103
|
|
|
110
104
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
@@ -133,7 +127,6 @@ export class ColorBulb {
|
|
|
133
127
|
.onSet(this.BrightnessSet.bind(this));
|
|
134
128
|
|
|
135
129
|
// handle ColorTemperature events using the ColorTemperature characteristic
|
|
136
|
-
this.debugLog(`Color Bulb: ${accessory.displayName} Add ColorTemperature Characteristic`);
|
|
137
130
|
this.lightBulbService
|
|
138
131
|
.getCharacteristic(this.platform.Characteristic.ColorTemperature)
|
|
139
132
|
.setProps({
|
|
@@ -172,7 +165,7 @@ export class ColorBulb {
|
|
|
172
165
|
})
|
|
173
166
|
.onSet(this.SaturationSet.bind(this));
|
|
174
167
|
|
|
175
|
-
this.debugLog(
|
|
168
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
176
169
|
if (this.adaptiveLightingShift !== -1) {
|
|
177
170
|
this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.lightBulbService, {
|
|
178
171
|
customTemperatureAdjustment: this.adaptiveLightingShift,
|
|
@@ -180,7 +173,7 @@ export class ColorBulb {
|
|
|
180
173
|
this.accessory.configureController(this.AdaptiveLightingController);
|
|
181
174
|
this.accessory.context.adaptiveLighting = true;
|
|
182
175
|
this.debugLog(
|
|
183
|
-
|
|
176
|
+
`${this.device.deviceType}: ${this.accessory.displayName} adaptiveLighting: ${this.accessory.context.adaptiveLighting},` +
|
|
184
177
|
` adaptiveLightingShift: ${this.adaptiveLightingShift}`,
|
|
185
178
|
);
|
|
186
179
|
}
|
|
@@ -208,26 +201,37 @@ export class ColorBulb {
|
|
|
208
201
|
try {
|
|
209
202
|
await this.pushChanges();
|
|
210
203
|
} catch (e: any) {
|
|
211
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges`);
|
|
212
|
-
if (this.deviceLogging.includes('debug')) {
|
|
213
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges,` + ` Error Message: ${JSON.stringify(e.message)}`);
|
|
214
|
-
}
|
|
215
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)}`);
|
|
216
207
|
}
|
|
217
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
|
+
});
|
|
218
216
|
});
|
|
219
217
|
}
|
|
220
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Parse the device status from the SwitchBot api
|
|
221
|
+
*/
|
|
221
222
|
async parseStatus(): Promise<void> {
|
|
222
|
-
if (this.
|
|
223
|
+
/*if (this.BLE) {
|
|
224
|
+
await this.BLEparseStatus();
|
|
225
|
+
} else*/ if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
223
226
|
await this.openAPIparseStatus();
|
|
224
227
|
} else {
|
|
225
|
-
|
|
228
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
229
|
+
+ ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
226
230
|
}
|
|
227
231
|
}
|
|
228
232
|
|
|
229
233
|
async BLEparseStatus(): Promise<void> {
|
|
230
|
-
this.debugLog(
|
|
234
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
231
235
|
// State
|
|
232
236
|
switch (this.state) {
|
|
233
237
|
case 'on':
|
|
@@ -236,10 +240,11 @@ export class ColorBulb {
|
|
|
236
240
|
default:
|
|
237
241
|
this.On = false;
|
|
238
242
|
}
|
|
239
|
-
this.debugLog(
|
|
243
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
240
244
|
}
|
|
241
245
|
|
|
242
246
|
async openAPIparseStatus() {
|
|
247
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
243
248
|
switch (this.power) {
|
|
244
249
|
case 'on':
|
|
245
250
|
this.On = true;
|
|
@@ -247,61 +252,68 @@ export class ColorBulb {
|
|
|
247
252
|
default:
|
|
248
253
|
this.On = false;
|
|
249
254
|
}
|
|
250
|
-
this.debugLog(
|
|
255
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
251
256
|
|
|
252
257
|
// Brightness
|
|
253
258
|
this.Brightness = Number(this.brightness);
|
|
254
|
-
this.debugLog(
|
|
259
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
|
|
255
260
|
|
|
256
261
|
// Color, Hue & Brightness
|
|
257
262
|
if (this.color) {
|
|
258
|
-
this.debugLog(
|
|
263
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} color: ${superStringify(this.color)}`);
|
|
259
264
|
const [red, green, blue] = this.color!.split(':');
|
|
260
|
-
this.debugLog(
|
|
261
|
-
this.debugLog(
|
|
262
|
-
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)}`);
|
|
263
268
|
|
|
264
269
|
const [hue, saturation] = rgb2hs(Number(red), Number(green), Number(blue));
|
|
265
|
-
this.debugLog(
|
|
270
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
271
|
+
+ ` hs: ${superStringify(rgb2hs(Number(red), Number(green), Number(blue)))}`);
|
|
266
272
|
|
|
267
273
|
// Hue
|
|
268
274
|
this.Hue = hue;
|
|
269
|
-
this.debugLog(
|
|
275
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Hue: ${this.Hue}`);
|
|
270
276
|
|
|
271
277
|
// Saturation
|
|
272
278
|
this.Saturation = saturation;
|
|
273
|
-
this.debugLog(
|
|
279
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
|
|
274
280
|
}
|
|
275
281
|
|
|
276
282
|
// ColorTemperature
|
|
277
283
|
if (!Number.isNaN(this.colorTemperature)) {
|
|
278
|
-
this.debugLog(
|
|
284
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} OpenAPI ColorTemperature: ${this.colorTemperature}`);
|
|
279
285
|
const mired = Math.round(1000000 / this.colorTemperature!);
|
|
280
286
|
|
|
281
287
|
this.ColorTemperature = Number(mired);
|
|
282
288
|
|
|
283
289
|
this.ColorTemperature = Math.max(Math.min(this.ColorTemperature, 500), 140);
|
|
284
|
-
this.debugLog(
|
|
290
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
|
|
285
291
|
}
|
|
286
292
|
}
|
|
287
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Asks the SwitchBot API for the latest device information
|
|
296
|
+
*/
|
|
288
297
|
async refreshStatus(): Promise<void> {
|
|
289
|
-
if (this.
|
|
298
|
+
/*if (this.BLE) {
|
|
290
299
|
await this.BLERefreshStatus();
|
|
291
|
-
} else {
|
|
300
|
+
} else*/ if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
292
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.`);
|
|
293
305
|
}
|
|
294
306
|
}
|
|
295
307
|
|
|
296
308
|
async BLERefreshStatus(): Promise<void> {
|
|
297
|
-
this.debugLog(
|
|
309
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
|
|
298
310
|
const switchbot = await this.platform.connectBLE();
|
|
299
311
|
// Convert to BLE Address
|
|
300
312
|
this.device.bleMac = this.device
|
|
301
313
|
.deviceId!.match(/.{1,2}/g)!
|
|
302
314
|
.join(':')
|
|
303
315
|
.toLowerCase();
|
|
304
|
-
this.debugLog(
|
|
316
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
305
317
|
this.getCustomBLEAddress(switchbot);
|
|
306
318
|
// Start to monitor advertisement packets
|
|
307
319
|
if (switchbot !== false) {
|
|
@@ -314,13 +326,9 @@ export class ColorBulb {
|
|
|
314
326
|
// Set an event hander
|
|
315
327
|
switchbot.onadvertisement = (ad: any) => {
|
|
316
328
|
this.address = ad.address;
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
this.infoLog(`Color Bulb: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
|
|
321
|
-
this.infoLog(`Color Bulb: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
|
|
322
|
-
}
|
|
323
|
-
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)}`);
|
|
324
332
|
this.serviceData = ad.serviceData;
|
|
325
333
|
//this.state = ad.serviceData.state;
|
|
326
334
|
//this.delay = ad.serviceData.delay;
|
|
@@ -329,19 +337,19 @@ export class ColorBulb {
|
|
|
329
337
|
//this.wifiRssi = ad.serviceData.wifiRssi;
|
|
330
338
|
//this.overload = ad.serviceData.overload;
|
|
331
339
|
//this.currentPower = ad.serviceData.currentPower;
|
|
332
|
-
this.debugLog(
|
|
340
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
|
|
333
341
|
/*this.debugLog(
|
|
334
|
-
|
|
342
|
+
`${this.device.deviceType}: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
|
|
335
343
|
`delay: ${ad.serviceData.delay}, timer: ${ad.serviceData.timer}, syncUtcTime: ${ad.serviceData.syncUtcTime} ` +
|
|
336
344
|
`wifiRssi: ${ad.serviceData.wifiRssi}, overload: ${ad.serviceData.overload}, currentPower: ${ad.serviceData.currentPower}`,
|
|
337
345
|
);*/
|
|
338
346
|
|
|
339
347
|
if (this.serviceData) {
|
|
340
348
|
this.connected = true;
|
|
341
|
-
this.debugLog(
|
|
349
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
342
350
|
} else {
|
|
343
351
|
this.connected = false;
|
|
344
|
-
this.debugLog(
|
|
352
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
345
353
|
}
|
|
346
354
|
};
|
|
347
355
|
// Wait 2 seconds
|
|
@@ -351,72 +359,32 @@ export class ColorBulb {
|
|
|
351
359
|
// Stop to monitor
|
|
352
360
|
switchbot.stopScan();
|
|
353
361
|
if (this.connected) {
|
|
354
|
-
this.
|
|
362
|
+
this.BLEparseStatus();
|
|
355
363
|
this.updateHomeKitCharacteristics();
|
|
356
364
|
} else {
|
|
357
|
-
this.
|
|
358
|
-
if (this.platform.config.credentials?.token) {
|
|
359
|
-
this.warnLog(`Color Bulb: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
360
|
-
this.SwitchToOpenAPI = true;
|
|
361
|
-
await this.openAPIRefreshStatus();
|
|
362
|
-
}
|
|
365
|
+
await this.BLERefreshConnection(switchbot);
|
|
363
366
|
}
|
|
364
367
|
})
|
|
365
368
|
.catch(async (e: any) => {
|
|
366
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
|
|
367
|
-
if (this.deviceLogging.includes('debug')) {
|
|
368
|
-
this.errorLog(
|
|
369
|
-
`Color Bulb: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
370
|
-
);
|
|
371
|
-
}
|
|
372
|
-
if (this.platform.config.credentials?.token) {
|
|
373
|
-
this.warnLog(`Color Bulb: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
374
|
-
this.SwitchToOpenAPI = true;
|
|
375
|
-
await this.openAPIRefreshStatus();
|
|
376
|
-
}
|
|
377
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);
|
|
378
373
|
});
|
|
379
374
|
} else {
|
|
380
|
-
await this.
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
async getCustomBLEAddress(switchbot: any) {
|
|
385
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
386
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} customBLEaddress: ${this.device.customBLEaddress}`);
|
|
387
|
-
(async () => {
|
|
388
|
-
// Start to monitor advertisement packets
|
|
389
|
-
await switchbot.startScan({
|
|
390
|
-
model: 'u',
|
|
391
|
-
});
|
|
392
|
-
// Set an event handler
|
|
393
|
-
switchbot.onadvertisement = (ad: any) => {
|
|
394
|
-
this.warnLog(`Color Bulb: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
395
|
-
};
|
|
396
|
-
await switchbot.wait(10000);
|
|
397
|
-
// Stop to monitor
|
|
398
|
-
switchbot.stopScan();
|
|
399
|
-
})();
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
async BLEconnection(switchbot: any): Promise<void> {
|
|
404
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
405
|
-
if (this.platform.config.credentials?.token) {
|
|
406
|
-
this.warnLog(`Color Bulb: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
407
|
-
this.SwitchToOpenAPI = true;
|
|
408
|
-
await this.openAPIRefreshStatus();
|
|
375
|
+
await this.BLERefreshConnection(switchbot);
|
|
409
376
|
}
|
|
410
377
|
}
|
|
411
378
|
|
|
412
379
|
async openAPIRefreshStatus() {
|
|
380
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
413
381
|
try {
|
|
414
382
|
const t = Date.now();
|
|
415
383
|
const nonce = 'requestID';
|
|
416
384
|
const data = this.platform.config.credentials?.token + t + nonce;
|
|
417
385
|
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
418
386
|
const sign = signTerm.toString('base64');
|
|
419
|
-
this.debugLog(
|
|
387
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
420
388
|
const options = {
|
|
421
389
|
hostname: HostDomain,
|
|
422
390
|
port: 443,
|
|
@@ -431,39 +399,36 @@ export class ColorBulb {
|
|
|
431
399
|
},
|
|
432
400
|
};
|
|
433
401
|
const req = https.request(options, (res) => {
|
|
434
|
-
this.debugLog(
|
|
402
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
|
|
403
|
+
this.statusCode({ res });
|
|
435
404
|
let rawData = '';
|
|
436
405
|
res.on('data', (d) => {
|
|
437
406
|
rawData += d;
|
|
438
|
-
this.debugLog(
|
|
407
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
439
408
|
});
|
|
440
409
|
res.on('end', () => {
|
|
441
410
|
try {
|
|
442
411
|
this.deviceStatus = JSON.parse(rawData);
|
|
443
|
-
this.debugLog(
|
|
412
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
444
413
|
this.power = this.deviceStatus.body.power;
|
|
445
414
|
this.color = this.deviceStatus.body.color;
|
|
446
415
|
this.brightness = this.deviceStatus.body.brightness;
|
|
447
416
|
this.colorTemperature = this.deviceStatus.body.colorTemperature;
|
|
448
|
-
this.
|
|
417
|
+
this.openAPIparseStatus();
|
|
449
418
|
this.updateHomeKitCharacteristics();
|
|
450
419
|
} catch (e: any) {
|
|
451
|
-
this.errorLog(
|
|
420
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
452
421
|
}
|
|
453
422
|
});
|
|
454
423
|
});
|
|
455
424
|
req.on('error', (e: any) => {
|
|
456
|
-
this.errorLog(
|
|
425
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
457
426
|
});
|
|
458
427
|
req.end();
|
|
459
428
|
} catch (e: any) {
|
|
460
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
461
|
-
if (this.deviceLogging.includes('debug')) {
|
|
462
|
-
this.errorLog(
|
|
463
|
-
`Color Bulb: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
464
|
-
);
|
|
465
|
-
}
|
|
466
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)}`);
|
|
467
432
|
}
|
|
468
433
|
}
|
|
469
434
|
|
|
@@ -479,7 +444,62 @@ export class ColorBulb {
|
|
|
479
444
|
*
|
|
480
445
|
*/
|
|
481
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> {
|
|
482
501
|
try {
|
|
502
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
|
|
483
503
|
if (this.On !== this.accessory.context.On) {
|
|
484
504
|
// Make Push On request to the API
|
|
485
505
|
const t = Date.now();
|
|
@@ -489,7 +509,7 @@ export class ColorBulb {
|
|
|
489
509
|
.update(Buffer.from(data, 'utf-8'))
|
|
490
510
|
.digest();
|
|
491
511
|
const sign = signTerm.toString('base64');
|
|
492
|
-
this.debugLog(
|
|
512
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
493
513
|
|
|
494
514
|
let command = '';
|
|
495
515
|
if (this.On) {
|
|
@@ -497,12 +517,12 @@ export class ColorBulb {
|
|
|
497
517
|
} else {
|
|
498
518
|
command = 'turnOff';
|
|
499
519
|
}
|
|
500
|
-
const body =
|
|
520
|
+
const body = superStringify({
|
|
501
521
|
'command': `${command}`,
|
|
502
522
|
'parameter': 'default',
|
|
503
523
|
'commandType': 'command',
|
|
504
524
|
});
|
|
505
|
-
this.infoLog(
|
|
525
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
|
|
506
526
|
const options = {
|
|
507
527
|
hostname: HostDomain,
|
|
508
528
|
port: 443,
|
|
@@ -518,53 +538,53 @@ export class ColorBulb {
|
|
|
518
538
|
},
|
|
519
539
|
};
|
|
520
540
|
const req = https.request(options, res => {
|
|
521
|
-
this.debugLog(
|
|
541
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges statusCode: ${res.statusCode}`);
|
|
522
542
|
this.statusCode({ res });
|
|
523
543
|
res.on('data', d => {
|
|
524
|
-
this.debugLog(
|
|
544
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
525
545
|
});
|
|
526
546
|
});
|
|
527
547
|
req.on('error', (e: any) => {
|
|
528
|
-
this.errorLog(
|
|
548
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
529
549
|
});
|
|
530
550
|
req.write(body);
|
|
531
551
|
req.end();
|
|
532
|
-
this.debugLog(
|
|
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
|
+
);
|
|
533
558
|
}
|
|
534
559
|
// Push Brightness Update
|
|
535
560
|
if (this.On) {
|
|
536
561
|
await this.pushBrightnessChanges();
|
|
537
562
|
}
|
|
538
|
-
|
|
539
563
|
// Push ColorTemperature Update
|
|
540
564
|
if (this.On) {
|
|
541
565
|
await this.pushColorTemperatureChanges();
|
|
542
566
|
}
|
|
543
|
-
|
|
544
567
|
// Push Hue & Saturation Update
|
|
545
568
|
if (this.On) {
|
|
546
569
|
await this.pushHueSaturationChanges();
|
|
547
570
|
}
|
|
548
571
|
} catch (e: any) {
|
|
549
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
550
|
-
if (this.deviceLogging.includes('debug')) {
|
|
551
|
-
this.errorLog(
|
|
552
|
-
`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
553
|
-
);
|
|
554
|
-
}
|
|
555
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
|
+
);
|
|
556
576
|
}
|
|
557
577
|
}
|
|
558
578
|
|
|
559
579
|
async pushHueSaturationChanges(): Promise<void> {
|
|
560
580
|
try {
|
|
581
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges`);
|
|
561
582
|
if (this.Hue !== this.accessory.context.Hue || this.Saturation !== this.accessory.context.Saturation) {
|
|
562
|
-
this.debugLog(
|
|
563
|
-
this.debugLog(
|
|
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)}`);
|
|
564
585
|
|
|
565
586
|
const [red, green, blue] = hs2rgb(Number(this.Hue), Number(this.Saturation));
|
|
566
|
-
this.debugLog(
|
|
567
|
-
|
|
587
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} rgb: ${superStringify([red, green, blue])}`);
|
|
568
588
|
// Make Push Hue/Saturation request to the API
|
|
569
589
|
const t = Date.now();
|
|
570
590
|
const nonce = 'requestID';
|
|
@@ -573,13 +593,13 @@ export class ColorBulb {
|
|
|
573
593
|
.update(Buffer.from(data, 'utf-8'))
|
|
574
594
|
.digest();
|
|
575
595
|
const sign = signTerm.toString('base64');
|
|
576
|
-
this.debugLog(
|
|
577
|
-
const body =
|
|
596
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
597
|
+
const body = superStringify({
|
|
578
598
|
'command': 'setColor',
|
|
579
599
|
'parameter': `${red}:${green}:${blue}`,
|
|
580
600
|
'commandType': 'command',
|
|
581
601
|
});
|
|
582
|
-
this.infoLog(
|
|
602
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
|
|
583
603
|
const options = {
|
|
584
604
|
hostname: HostDomain,
|
|
585
605
|
port: 443,
|
|
@@ -595,37 +615,31 @@ export class ColorBulb {
|
|
|
595
615
|
},
|
|
596
616
|
};
|
|
597
617
|
const req = https.request(options, res => {
|
|
598
|
-
this.debugLog(
|
|
618
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges statusCode: ${res.statusCode}`);
|
|
599
619
|
res.on('data', d => {
|
|
600
|
-
this.debugLog(
|
|
620
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
601
621
|
});
|
|
602
622
|
});
|
|
603
623
|
req.on('error', (e: any) => {
|
|
604
|
-
this.errorLog(
|
|
624
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
605
625
|
});
|
|
606
626
|
req.write(body);
|
|
607
627
|
req.end();
|
|
608
|
-
this.debugLog(
|
|
628
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushHueSaturationChanges: ${superStringify(req)}`);
|
|
609
629
|
} else {
|
|
610
|
-
this.debugLog(
|
|
611
|
-
|
|
612
|
-
`Hue: ${this.Hue}, HueCached: ${this.accessory.context.Hue}, Saturation: ${this.Saturation},`
|
|
613
|
-
+` SaturationCached: ${this.accessory.context.Saturation}`,
|
|
614
|
-
);
|
|
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}`);
|
|
615
632
|
}
|
|
616
633
|
} catch (e: any) {
|
|
617
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
618
|
-
if (this.deviceLogging.includes('debug')) {
|
|
619
|
-
this.errorLog(
|
|
620
|
-
`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
621
|
-
);
|
|
622
|
-
}
|
|
623
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)}`);
|
|
624
637
|
}
|
|
625
638
|
}
|
|
626
639
|
|
|
627
640
|
async pushColorTemperatureChanges(): Promise<void> {
|
|
628
641
|
try {
|
|
642
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushColorTemperatureChanges`);
|
|
629
643
|
if (this.ColorTemperature !== this.accessory.context.ColorTemperature) {
|
|
630
644
|
const kelvin = Math.round(1000000 / Number(this.ColorTemperature));
|
|
631
645
|
this.cacheKelvin = kelvin;
|
|
@@ -638,13 +652,13 @@ export class ColorBulb {
|
|
|
638
652
|
.update(Buffer.from(data, 'utf-8'))
|
|
639
653
|
.digest();
|
|
640
654
|
const sign = signTerm.toString('base64');
|
|
641
|
-
this.debugLog(
|
|
642
|
-
const body =
|
|
655
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
656
|
+
const body = superStringify({
|
|
643
657
|
'command': 'setColorTemperature',
|
|
644
658
|
'parameter': `${kelvin}`,
|
|
645
659
|
'commandType': 'command',
|
|
646
660
|
});
|
|
647
|
-
this.infoLog(
|
|
661
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
|
|
648
662
|
const options = {
|
|
649
663
|
hostname: HostDomain,
|
|
650
664
|
port: 443,
|
|
@@ -660,38 +674,32 @@ export class ColorBulb {
|
|
|
660
674
|
},
|
|
661
675
|
};
|
|
662
676
|
const req = https.request(options, res => {
|
|
663
|
-
this.debugLog(
|
|
677
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
664
678
|
res.on('data', d => {
|
|
665
|
-
this.debugLog(
|
|
679
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
666
680
|
});
|
|
667
681
|
});
|
|
668
682
|
req.on('error', (e: any) => {
|
|
669
|
-
this.errorLog(
|
|
683
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
670
684
|
});
|
|
671
685
|
req.write(body);
|
|
672
686
|
req.end();
|
|
673
|
-
|
|
674
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} pushColorTemperatureChanges: ${JSON.stringify(req)}`);
|
|
687
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushColorTemperatureChanges: ${superStringify(req)}`);
|
|
675
688
|
this.accessory.context.ColorTemperature = this.ColorTemperature;
|
|
676
689
|
} else {
|
|
677
|
-
this.debugLog(
|
|
678
|
-
|
|
679
|
-
`ColorTemperature: ${this.ColorTemperature}, ColorTemperatureCached: ${this.accessory.context.ColorTemperature}`,
|
|
680
|
-
);
|
|
690
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushColorTemperatureChanges.` +
|
|
691
|
+
`ColorTemperature: ${this.ColorTemperature}, ColorTemperatureCached: ${this.accessory.context.ColorTemperature}`);
|
|
681
692
|
}
|
|
682
693
|
} catch (e: any) {
|
|
683
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
684
|
-
if (this.deviceLogging.includes('debug')) {
|
|
685
|
-
this.errorLog(
|
|
686
|
-
`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
687
|
-
);
|
|
688
|
-
}
|
|
689
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)}`);
|
|
690
697
|
}
|
|
691
698
|
}
|
|
692
699
|
|
|
693
700
|
async pushBrightnessChanges(): Promise<void> {
|
|
694
701
|
try {
|
|
702
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges`);
|
|
695
703
|
if (this.Brightness !== this.accessory.context.Brightness) {
|
|
696
704
|
// Make Push On request to the API
|
|
697
705
|
const t = Date.now();
|
|
@@ -701,13 +709,13 @@ export class ColorBulb {
|
|
|
701
709
|
.update(Buffer.from(data, 'utf-8'))
|
|
702
710
|
.digest();
|
|
703
711
|
const sign = signTerm.toString('base64');
|
|
704
|
-
this.debugLog(
|
|
705
|
-
const body =
|
|
712
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
713
|
+
const body = superStringify({
|
|
706
714
|
'command': 'setBrightness',
|
|
707
715
|
'parameter': `${this.Brightness}`,
|
|
708
716
|
'commandType': 'command',
|
|
709
717
|
});
|
|
710
|
-
this.infoLog(
|
|
718
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
|
|
711
719
|
const options = {
|
|
712
720
|
hostname: HostDomain,
|
|
713
721
|
port: 443,
|
|
@@ -723,123 +731,25 @@ export class ColorBulb {
|
|
|
723
731
|
},
|
|
724
732
|
};
|
|
725
733
|
const req = https.request(options, res => {
|
|
726
|
-
this.debugLog(
|
|
734
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges statusCode: ${res.statusCode}`);
|
|
727
735
|
res.on('data', d => {
|
|
728
|
-
this.debugLog(
|
|
736
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
729
737
|
});
|
|
730
738
|
});
|
|
731
739
|
req.on('error', (e: any) => {
|
|
732
|
-
this.errorLog(
|
|
740
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
733
741
|
});
|
|
734
742
|
req.write(body);
|
|
735
743
|
req.end();
|
|
736
|
-
this.debugLog(
|
|
744
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} pushBrightnessChanges: ${superStringify(req)}`);
|
|
737
745
|
} else {
|
|
738
|
-
this.debugLog(
|
|
739
|
-
|
|
740
|
-
+`BrightnessCached: ${this.accessory.context.Brightness}`,
|
|
741
|
-
);
|
|
746
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No pushBrightnessChanges.` + `Brightness: ${this.Brightness}, `
|
|
747
|
+
+`BrightnessCached: ${this.accessory.context.Brightness}`);
|
|
742
748
|
}
|
|
743
749
|
} catch (e: any) {
|
|
744
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
745
|
-
if (this.deviceLogging.includes('debug')) {
|
|
746
|
-
this.errorLog(
|
|
747
|
-
`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
748
|
-
);
|
|
749
|
-
}
|
|
750
750
|
this.apiError(e);
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
async updateHomeKitCharacteristics(): Promise<void> {
|
|
755
|
-
if (this.On === undefined) {
|
|
756
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} On: ${this.On}`);
|
|
757
|
-
} else {
|
|
758
|
-
this.accessory.context.On = this.On;
|
|
759
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.On, this.On);
|
|
760
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
|
|
761
|
-
}
|
|
762
|
-
if (this.Brightness === undefined) {
|
|
763
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
|
|
764
|
-
} else {
|
|
765
|
-
this.accessory.context.Brightness = this.Brightness;
|
|
766
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Brightness, this.Brightness);
|
|
767
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic Brightness: ${this.Brightness}`);
|
|
768
|
-
}
|
|
769
|
-
if (this.ColorTemperature === undefined) {
|
|
770
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
|
|
771
|
-
} else {
|
|
772
|
-
|
|
773
|
-
this.accessory.context.ColorTemperature = this.ColorTemperature;
|
|
774
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, this.ColorTemperature);
|
|
775
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic ColorTemperature: ${this.ColorTemperature}`);
|
|
776
|
-
}
|
|
777
|
-
if (this.Hue === undefined) {
|
|
778
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} Hue: ${this.Hue}`);
|
|
779
|
-
} else {
|
|
780
|
-
this.accessory.context.Hue = this.Hue;
|
|
781
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Hue, this.Hue);
|
|
782
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic Hue: ${this.Hue}`);
|
|
783
|
-
}
|
|
784
|
-
if (this.Saturation === undefined) {
|
|
785
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
|
|
786
|
-
} else {
|
|
787
|
-
this.accessory.context.Saturation = this.Saturation;
|
|
788
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Saturation, this.Saturation);
|
|
789
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} updateCharacteristic Saturation: ${this.Saturation}`);
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
apiError(e: any): void {
|
|
794
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.On, e);
|
|
795
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Hue, e);
|
|
796
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Brightness, e);
|
|
797
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.Saturation, e);
|
|
798
|
-
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, e);
|
|
799
|
-
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
803
|
-
switch (res.statusCode) {
|
|
804
|
-
case 151:
|
|
805
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
806
|
-
break;
|
|
807
|
-
case 152:
|
|
808
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} Device not found.`);
|
|
809
|
-
break;
|
|
810
|
-
case 160:
|
|
811
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} Command is not supported.`);
|
|
812
|
-
break;
|
|
813
|
-
case 161:
|
|
814
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} Device is offline.`);
|
|
815
|
-
this.offlineOff();
|
|
816
|
-
break;
|
|
817
|
-
case 171:
|
|
818
|
-
this.errorLog(`Color Bulb: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
|
|
819
|
-
this.offlineOff();
|
|
820
|
-
break;
|
|
821
|
-
case 190:
|
|
822
|
-
this.errorLog(
|
|
823
|
-
`Color Bulb: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
824
|
-
` Or command: ${JSON.stringify(res)} format is invalid`,
|
|
825
|
-
);
|
|
826
|
-
break;
|
|
827
|
-
case 100:
|
|
828
|
-
if (this.platform.debugMode) {
|
|
829
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} Command successfully sent.`);
|
|
830
|
-
}
|
|
831
|
-
break;
|
|
832
|
-
default:
|
|
833
|
-
if (this.platform.debugMode) {
|
|
834
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} Unknown statusCode.`);
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
async offlineOff(): Promise<void> {
|
|
840
|
-
if (this.device.offline) {
|
|
841
|
-
this.On = false;
|
|
842
|
-
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)}`);
|
|
843
753
|
}
|
|
844
754
|
}
|
|
845
755
|
|
|
@@ -847,7 +757,11 @@ export class ColorBulb {
|
|
|
847
757
|
* Handle requests to set the value of the "On" characteristic
|
|
848
758
|
*/
|
|
849
759
|
async OnSet(value: CharacteristicValue): Promise<void> {
|
|
850
|
-
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
|
+
}
|
|
851
765
|
|
|
852
766
|
this.On = value;
|
|
853
767
|
this.doColorBulbUpdate.next();
|
|
@@ -857,7 +771,13 @@ export class ColorBulb {
|
|
|
857
771
|
* Handle requests to set the value of the "Brightness" characteristic
|
|
858
772
|
*/
|
|
859
773
|
async BrightnessSet(value: CharacteristicValue): Promise<void> {
|
|
860
|
-
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
|
+
}
|
|
861
781
|
|
|
862
782
|
this.Brightness = value;
|
|
863
783
|
this.doColorBulbUpdate.next();
|
|
@@ -867,7 +787,13 @@ export class ColorBulb {
|
|
|
867
787
|
* Handle requests to set the value of the "ColorTemperature" characteristic
|
|
868
788
|
*/
|
|
869
789
|
async ColorTemperatureSet(value: CharacteristicValue): Promise<void> {
|
|
870
|
-
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
|
+
}
|
|
871
797
|
|
|
872
798
|
// Convert mired to kelvin to nearest 100 (SwitchBot seems to need this)
|
|
873
799
|
const kelvin = Math.round(1000000 / Number(value) / 100) * 100;
|
|
@@ -892,7 +818,13 @@ export class ColorBulb {
|
|
|
892
818
|
* Handle requests to set the value of the "Hue" characteristic
|
|
893
819
|
*/
|
|
894
820
|
async HueSet(value: CharacteristicValue): Promise<void> {
|
|
895
|
-
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
|
+
}
|
|
896
828
|
|
|
897
829
|
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, 140);
|
|
898
830
|
|
|
@@ -904,7 +836,13 @@ export class ColorBulb {
|
|
|
904
836
|
* Handle requests to set the value of the "Saturation" characteristic
|
|
905
837
|
*/
|
|
906
838
|
async SaturationSet(value: CharacteristicValue): Promise<void> {
|
|
907
|
-
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
|
+
}
|
|
908
846
|
|
|
909
847
|
this.lightBulbService.updateCharacteristic(this.platform.Characteristic.ColorTemperature, 140);
|
|
910
848
|
|
|
@@ -912,76 +850,205 @@ export class ColorBulb {
|
|
|
912
850
|
this.doColorBulbUpdate.next();
|
|
913
851
|
}
|
|
914
852
|
|
|
915
|
-
async
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
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}`);
|
|
919
860
|
}
|
|
920
|
-
if (
|
|
921
|
-
|
|
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}`);
|
|
922
867
|
}
|
|
923
|
-
if (
|
|
924
|
-
|
|
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}`);
|
|
925
874
|
}
|
|
926
|
-
if (
|
|
927
|
-
|
|
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}`);
|
|
928
881
|
}
|
|
929
|
-
if (
|
|
930
|
-
|
|
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}`);
|
|
931
888
|
}
|
|
932
|
-
|
|
933
|
-
|
|
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}`);
|
|
934
898
|
}
|
|
935
|
-
|
|
936
|
-
|
|
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
|
+
})();
|
|
937
917
|
}
|
|
938
918
|
}
|
|
939
919
|
|
|
940
|
-
async
|
|
941
|
-
if (device.
|
|
942
|
-
this.
|
|
943
|
-
this.
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
|
|
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();
|
|
947
932
|
}
|
|
948
933
|
}
|
|
949
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;
|
|
975
|
+
}
|
|
976
|
+
return this.set_minStep;
|
|
977
|
+
}
|
|
978
|
+
|
|
950
979
|
async scan(device: device & devicesConfig): Promise<void> {
|
|
951
980
|
if (device.scanDuration) {
|
|
952
981
|
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
953
|
-
if (
|
|
954
|
-
this.debugLog(
|
|
982
|
+
if (this.BLE) {
|
|
983
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
955
984
|
}
|
|
956
985
|
} else {
|
|
957
986
|
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
958
|
-
if (this.
|
|
959
|
-
this.debugLog(
|
|
987
|
+
if (this.BLE) {
|
|
988
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
960
989
|
}
|
|
961
990
|
}
|
|
962
991
|
}
|
|
963
992
|
|
|
964
|
-
async
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
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
|
+
}
|
|
977
1027
|
}
|
|
978
1028
|
}
|
|
979
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();
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
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
|
+
|
|
980
1046
|
FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
|
|
981
1047
|
let FirmwareRevision: string;
|
|
982
|
-
this.debugLog(
|
|
983
|
-
|
|
984
|
-
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}`);
|
|
985
1052
|
if (accessory.context.FirmwareRevision) {
|
|
986
1053
|
FirmwareRevision = accessory.context.FirmwareRevision;
|
|
987
1054
|
} else if (device.firmware) {
|
|
@@ -992,23 +1059,88 @@ export class ColorBulb {
|
|
|
992
1059
|
return FirmwareRevision;
|
|
993
1060
|
}
|
|
994
1061
|
|
|
995
|
-
|
|
996
|
-
if (
|
|
997
|
-
this.
|
|
998
|
-
this.debugLog(`Color Bulb: ${this.accessory.displayName} adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
1062
|
+
private context() {
|
|
1063
|
+
if (this.On === undefined) {
|
|
1064
|
+
this.On = false;
|
|
999
1065
|
} else {
|
|
1000
|
-
this.
|
|
1001
|
-
|
|
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;
|
|
1082
|
+
}
|
|
1083
|
+
if (this.ColorTemperature === undefined) {
|
|
1084
|
+
this.ColorTemperature = 140;
|
|
1085
|
+
} else {
|
|
1086
|
+
this.ColorTemperature = this.accessory.context.ColorTemperature;
|
|
1002
1087
|
}
|
|
1088
|
+
this.minKelvin = 2000;
|
|
1089
|
+
this.maxKelvin = 9000;
|
|
1003
1090
|
}
|
|
1004
1091
|
|
|
1005
|
-
|
|
1006
|
-
if (device.
|
|
1007
|
-
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}`);
|
|
1008
1140
|
} else {
|
|
1009
|
-
this.
|
|
1141
|
+
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
1142
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
1010
1143
|
}
|
|
1011
|
-
return this.set_minStep;
|
|
1012
1144
|
}
|
|
1013
1145
|
|
|
1014
1146
|
/**
|
|
@@ -1026,12 +1158,28 @@ export class ColorBulb {
|
|
|
1026
1158
|
}
|
|
1027
1159
|
}
|
|
1028
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
|
+
|
|
1029
1169
|
errorLog(...log: any[]): void {
|
|
1030
1170
|
if (this.enablingDeviceLogging()) {
|
|
1031
1171
|
this.platform.log.error(String(...log));
|
|
1032
1172
|
}
|
|
1033
1173
|
}
|
|
1034
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
|
+
|
|
1035
1183
|
debugLog(...log: any[]): void {
|
|
1036
1184
|
if (this.enablingDeviceLogging()) {
|
|
1037
1185
|
if (this.deviceLogging === 'debug') {
|