@switchbot/homebridge-switchbot 1.1.1-beta.7 → 1.2.1-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -1
- package/README.md +67 -28
- package/config.schema.json +46 -43
- package/dist/devices/bots.d.ts +2 -0
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +118 -68
- package/dist/devices/bots.js.map +1 -1
- package/dist/devices/colorbulb.d.ts +19 -3
- package/dist/devices/colorbulb.d.ts.map +1 -1
- package/dist/devices/colorbulb.js +190 -31
- package/dist/devices/colorbulb.js.map +1 -1
- package/dist/devices/contact.d.ts +2 -0
- package/dist/devices/contact.d.ts.map +1 -1
- package/dist/devices/contact.js +22 -5
- package/dist/devices/contact.js.map +1 -1
- package/dist/devices/curtains.d.ts +5 -3
- package/dist/devices/curtains.d.ts.map +1 -1
- package/dist/devices/curtains.js +76 -26
- package/dist/devices/curtains.js.map +1 -1
- package/dist/devices/humidifiers.d.ts +2 -0
- package/dist/devices/humidifiers.d.ts.map +1 -1
- package/dist/devices/humidifiers.js +84 -27
- package/dist/devices/humidifiers.js.map +1 -1
- package/dist/devices/indoorcam.d.ts +2 -0
- package/dist/devices/indoorcam.d.ts.map +1 -1
- package/dist/devices/indoorcam.js +23 -7
- package/dist/devices/indoorcam.js.map +1 -1
- package/dist/devices/meters.d.ts +2 -0
- package/dist/devices/meters.d.ts.map +1 -1
- package/dist/devices/meters.js +21 -3
- package/dist/devices/meters.js.map +1 -1
- package/dist/devices/motion.d.ts +2 -0
- package/dist/devices/motion.d.ts.map +1 -1
- package/dist/devices/motion.js +21 -3
- package/dist/devices/motion.js.map +1 -1
- package/dist/devices/plugs.d.ts +2 -0
- package/dist/devices/plugs.d.ts.map +1 -1
- package/dist/devices/plugs.js +23 -7
- package/dist/devices/plugs.js.map +1 -1
- package/dist/irdevices/airconditioners.d.ts +2 -0
- package/dist/irdevices/airconditioners.d.ts.map +1 -1
- package/dist/irdevices/airconditioners.js +14 -5
- package/dist/irdevices/airconditioners.js.map +1 -1
- package/dist/irdevices/airpurifiers.d.ts +2 -0
- package/dist/irdevices/airpurifiers.d.ts.map +1 -1
- package/dist/irdevices/airpurifiers.js +14 -5
- package/dist/irdevices/airpurifiers.js.map +1 -1
- package/dist/irdevices/cameras.d.ts +2 -0
- package/dist/irdevices/cameras.d.ts.map +1 -1
- package/dist/irdevices/cameras.js +14 -5
- package/dist/irdevices/cameras.js.map +1 -1
- package/dist/irdevices/fans.d.ts +2 -0
- package/dist/irdevices/fans.d.ts.map +1 -1
- package/dist/irdevices/fans.js +13 -5
- package/dist/irdevices/fans.js.map +1 -1
- package/dist/irdevices/lights.d.ts +2 -0
- package/dist/irdevices/lights.d.ts.map +1 -1
- package/dist/irdevices/lights.js +14 -5
- package/dist/irdevices/lights.js.map +1 -1
- package/dist/irdevices/others.d.ts +2 -0
- package/dist/irdevices/others.d.ts.map +1 -1
- package/dist/irdevices/others.js +20 -11
- package/dist/irdevices/others.js.map +1 -1
- package/dist/irdevices/tvs.d.ts +2 -0
- package/dist/irdevices/tvs.d.ts.map +1 -1
- package/dist/irdevices/tvs.js +14 -4
- package/dist/irdevices/tvs.js.map +1 -1
- package/dist/irdevices/vacuumcleaners.d.ts +2 -0
- package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
- package/dist/irdevices/vacuumcleaners.js +14 -5
- package/dist/irdevices/vacuumcleaners.js.map +1 -1
- package/dist/irdevices/waterheaters.d.ts +2 -0
- package/dist/irdevices/waterheaters.d.ts.map +1 -1
- package/dist/irdevices/waterheaters.js +14 -5
- package/dist/irdevices/waterheaters.js.map +1 -1
- package/dist/platform.d.ts +1 -0
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +35 -26
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +4 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +557 -1
- package/dist/settings.js.map +1 -1
- package/package.json +6 -6
- package/src/devices/bots.ts +118 -69
- package/src/devices/colorbulb.ts +218 -33
- package/src/devices/contact.ts +23 -5
- package/src/devices/curtains.ts +80 -31
- package/src/devices/humidifiers.ts +85 -29
- package/src/devices/indoorcam.ts +24 -7
- package/src/devices/meters.ts +22 -3
- package/src/devices/motion.ts +22 -3
- package/src/devices/plugs.ts +24 -7
- package/src/irdevices/airconditioners.ts +15 -5
- package/src/irdevices/airpurifiers.ts +15 -5
- package/src/irdevices/cameras.ts +15 -5
- package/src/irdevices/fans.ts +13 -5
- package/src/irdevices/lights.ts +15 -5
- package/src/irdevices/others.ts +21 -11
- package/src/irdevices/tvs.ts +15 -4
- package/src/irdevices/vacuumcleaners.ts +15 -5
- package/src/irdevices/waterheaters.ts +15 -5
- package/src/platform.ts +36 -26
- package/src/settings.ts +557 -1
package/src/devices/bots.ts
CHANGED
|
@@ -31,6 +31,10 @@ export class Bot {
|
|
|
31
31
|
state!: serviceData['state'];
|
|
32
32
|
battery!: serviceData['battery'];
|
|
33
33
|
|
|
34
|
+
// Config
|
|
35
|
+
private readonly deviceDebug = this.platform.config.options?.debug === 'device' || this.platform.debugMode;
|
|
36
|
+
private readonly debugDebug = this.platform.config.options?.debug === 'debug' || this.platform.debugMode;
|
|
37
|
+
|
|
34
38
|
// Updates
|
|
35
39
|
botUpdateInProgress!: boolean;
|
|
36
40
|
doBotUpdate!: Subject<void>;
|
|
@@ -65,39 +69,36 @@ export class Bot {
|
|
|
65
69
|
|
|
66
70
|
// get the LightBulb service if it exists, otherwise create a new LightBulb service
|
|
67
71
|
// you can create multiple services for each accessory
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
accessory.removeService(this.outletService!);
|
|
72
|
+
if (device.bot?.deviceType === 'switch') {
|
|
73
|
+
// If outletService still pressent, then remove first
|
|
74
|
+
if (this.outletService) {
|
|
75
|
+
this.platform.device(`Bot: ${this.accessory.displayName} Removing Leftover outletService first`);
|
|
76
|
+
}
|
|
77
|
+
this.outletService = this.accessory.getService(this.platform.Service.Outlet);
|
|
78
|
+
accessory.removeService(this.outletService!);
|
|
76
79
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
// Add switchService
|
|
81
|
+
(this.switchService =
|
|
82
|
+
accessory.getService(this.platform.Service.Switch) ||
|
|
83
|
+
accessory.addService(this.platform.Service.Switch)), `${accessory.displayName} Switch`;
|
|
84
|
+
this.platform.log.info(`Bot: ${this.accessory.displayName} Displaying as Switch`);
|
|
82
85
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
this.switchService = this.accessory.getService(this.platform.Service.Switch);
|
|
92
|
-
accessory.removeService(this.switchService!);
|
|
86
|
+
this.switchService?.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
|
|
87
|
+
} else {
|
|
88
|
+
// If switchService still pressent, then remove first
|
|
89
|
+
if (this.switchService) {
|
|
90
|
+
this.platform.device(`Bot: ${this.accessory.displayName} Removing Leftover switchService first`);
|
|
91
|
+
}
|
|
92
|
+
this.switchService = this.accessory.getService(this.platform.Service.Switch);
|
|
93
|
+
accessory.removeService(this.switchService!);
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
// Add outletService
|
|
96
|
+
(this.outletService =
|
|
97
|
+
accessory.getService(this.platform.Service.Outlet) ||
|
|
98
|
+
accessory.addService(this.platform.Service.Outlet)), `${accessory.displayName} Outlet`;
|
|
99
|
+
this.platform.log.info(`Bot: ${this.accessory.displayName} Displaying as Outlet`);
|
|
99
100
|
|
|
100
|
-
|
|
101
|
+
this.outletService?.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
if (device.ble) {
|
|
@@ -141,10 +142,15 @@ export class Bot {
|
|
|
141
142
|
try {
|
|
142
143
|
await this.pushChanges();
|
|
143
144
|
} catch (e: any) {
|
|
144
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName} failed
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges`);
|
|
146
|
+
if (this.deviceDebug) {
|
|
147
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges,`
|
|
148
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
149
|
+
}
|
|
150
|
+
if (this.debugDebug) {
|
|
151
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges,`
|
|
152
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
153
|
+
}
|
|
148
154
|
}
|
|
149
155
|
this.botUpdateInProgress = false;
|
|
150
156
|
});
|
|
@@ -239,7 +245,15 @@ export class Bot {
|
|
|
239
245
|
this.parseStatus();
|
|
240
246
|
this.updateHomeKitCharacteristics();
|
|
241
247
|
}).catch(async (e: any) => {
|
|
242
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName}
|
|
248
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
|
|
249
|
+
if (this.deviceDebug) {
|
|
250
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
|
|
251
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
252
|
+
}
|
|
253
|
+
if (this.debugDebug) {
|
|
254
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
|
|
255
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
256
|
+
}
|
|
243
257
|
if (this.platform.config.credentials?.openToken) {
|
|
244
258
|
this.platform.log.warn(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
245
259
|
await this.openAPIRefreshStatus();
|
|
@@ -264,8 +278,15 @@ export class Bot {
|
|
|
264
278
|
this.parseStatus();
|
|
265
279
|
this.updateHomeKitCharacteristics();
|
|
266
280
|
} catch (e: any) {
|
|
267
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName} failed
|
|
268
|
-
|
|
281
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
282
|
+
if (this.deviceDebug) {
|
|
283
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
|
|
284
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
285
|
+
}
|
|
286
|
+
if (this.debugDebug) {
|
|
287
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
|
|
288
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
289
|
+
}
|
|
269
290
|
this.apiError(e);
|
|
270
291
|
}
|
|
271
292
|
}
|
|
@@ -298,7 +319,15 @@ export class Bot {
|
|
|
298
319
|
}).then(() => {
|
|
299
320
|
this.platform.device(`Bot: ${this.accessory.displayName} Done.`);
|
|
300
321
|
}).catch(async (e: any) => {
|
|
301
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName}
|
|
322
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
|
|
323
|
+
if (this.deviceDebug) {
|
|
324
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
325
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
326
|
+
}
|
|
327
|
+
if (this.debugDebug) {
|
|
328
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
329
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
330
|
+
}
|
|
302
331
|
if (this.platform.config.credentials?.openToken) {
|
|
303
332
|
this.platform.log.warn(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
304
333
|
await this.openAPIpushChanges();
|
|
@@ -306,20 +335,28 @@ export class Bot {
|
|
|
306
335
|
});
|
|
307
336
|
} else if (this.device.bot?.mode === 'switch') {
|
|
308
337
|
this.platform.device(`Bot: ${this.accessory.displayName} Press Mode: ${this.device.bot?.mode}`);
|
|
309
|
-
switchbot.discover({ model: 'H', quick: true, id: this.device.bleMac }).then((device_list) => {
|
|
338
|
+
switchbot.discover({ model: 'H', quick: true, id: this.device.bleMac }).then((device_list: any) => {
|
|
310
339
|
this.platform.log.info(`Bot: ${this.accessory.displayName} On: ${this.SwitchOn}`);
|
|
311
340
|
return this.turnOnOff(device_list);
|
|
312
341
|
}).then(() => {
|
|
313
342
|
this.platform.device(`Bot: ${this.accessory.displayName} Done.`);
|
|
314
343
|
}).catch(async (e: any) => {
|
|
315
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName}
|
|
344
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
|
|
345
|
+
if (this.deviceDebug) {
|
|
346
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
347
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
348
|
+
}
|
|
349
|
+
if (this.debugDebug) {
|
|
350
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
351
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
352
|
+
}
|
|
316
353
|
if (this.platform.config.credentials?.openToken) {
|
|
317
354
|
this.platform.log.warn(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
318
355
|
await this.openAPIpushChanges();
|
|
319
356
|
}
|
|
320
357
|
});
|
|
321
358
|
} else {
|
|
322
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName} Mode Not Set
|
|
359
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} Mode Not Set, mode: ${this.device.bot?.mode}`);
|
|
323
360
|
}
|
|
324
361
|
}
|
|
325
362
|
|
|
@@ -333,35 +370,47 @@ export class Bot {
|
|
|
333
370
|
|
|
334
371
|
private async openAPIpushChanges() {
|
|
335
372
|
if (this.platform.config.credentials?.openToken) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
373
|
+
try {
|
|
374
|
+
this.platform.debug(`Bot: ${this.accessory.displayName} OpenAPI pushChanges`);
|
|
375
|
+
const payload = {
|
|
376
|
+
commandType: 'command',
|
|
377
|
+
parameter: 'default',
|
|
378
|
+
} as payload;
|
|
379
|
+
|
|
380
|
+
if (this.device.bot?.mode === 'switch' && this.SwitchOn) {
|
|
381
|
+
payload.command = 'turnOn';
|
|
382
|
+
this.SwitchOn = true;
|
|
383
|
+
this.platform.debug(`Bot: ${this.accessory.displayName} Switch Mode, Turning ${this.SwitchOn}`);
|
|
384
|
+
} else if (this.device.bot?.mode === 'switch' && !this.SwitchOn) {
|
|
385
|
+
payload.command = 'turnOff';
|
|
386
|
+
this.SwitchOn = false;
|
|
387
|
+
this.platform.debug(`Bot: ${this.accessory.displayName} Switch Mode, Turning ${this.SwitchOn}`);
|
|
388
|
+
} else if (this.device.bot?.mode === 'press') {
|
|
389
|
+
payload.command = 'press';
|
|
390
|
+
this.platform.debug(`Bot: ${this.accessory.displayName} Press Mode`);
|
|
391
|
+
this.SwitchOn = false;
|
|
392
|
+
} else {
|
|
393
|
+
throw new Error(`Bot: ${this.accessory.displayName} Device Paramters not set for this Bot.`);
|
|
394
|
+
}
|
|
357
395
|
|
|
358
|
-
|
|
359
|
-
|
|
396
|
+
this.platform.log.info(`Bot: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
|
|
397
|
+
+ ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
|
|
360
398
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
399
|
+
// Make the API request
|
|
400
|
+
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
401
|
+
this.platform.debug(`Bot ${this.accessory.displayName} pushchanges: ${JSON.stringify(push.data)}`);
|
|
402
|
+
this.statusCode(push);
|
|
403
|
+
} catch (e: any) {
|
|
404
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
405
|
+
if (this.deviceDebug) {
|
|
406
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
407
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
408
|
+
}
|
|
409
|
+
if (this.debugDebug) {
|
|
410
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
411
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
365
414
|
}
|
|
366
415
|
}
|
|
367
416
|
|
|
@@ -425,8 +474,8 @@ export class Bot {
|
|
|
425
474
|
this.platform.log.error(`Bot: ${this.accessory.displayName} Hub Device is offline.`);
|
|
426
475
|
break;
|
|
427
476
|
case 190:
|
|
428
|
-
|
|
429
|
-
|
|
477
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
|
478
|
+
+ ` Or command: ${JSON.stringify(push.data)} format is invalid`);
|
|
430
479
|
break;
|
|
431
480
|
case 100:
|
|
432
481
|
this.platform.debug(`Bot: ${this.accessory.displayName} Command successfully sent.`);
|
package/src/devices/colorbulb.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
|
2
2
|
import { SwitchBotPlatform } from '../platform';
|
|
3
3
|
import { interval, Subject } from 'rxjs';
|
|
4
4
|
import { debounceTime, skipWhile, tap } from 'rxjs/operators';
|
|
5
|
-
import { DeviceURL, device, devicesConfig, switchbot, deviceStatusResponse, payload } from '../settings';
|
|
5
|
+
import { DeviceURL, device, devicesConfig, switchbot, deviceStatusResponse, payload, hs2rgb, rgb2hs } from '../settings';
|
|
6
6
|
import { AxiosResponse } from 'axios';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -16,7 +16,9 @@ export class ColorBulb {
|
|
|
16
16
|
|
|
17
17
|
// Characteristic Values
|
|
18
18
|
On!: CharacteristicValue;
|
|
19
|
+
Hue!: CharacteristicValue;
|
|
19
20
|
Brightness!: CharacteristicValue;
|
|
21
|
+
Saturation!: CharacteristicValue;
|
|
20
22
|
ColorTemperature!: CharacteristicValue;
|
|
21
23
|
|
|
22
24
|
// OpenAPI Others
|
|
@@ -27,6 +29,8 @@ export class ColorBulb {
|
|
|
27
29
|
|
|
28
30
|
// Config
|
|
29
31
|
set_minStep?: number;
|
|
32
|
+
private readonly deviceDebug = this.platform.config.options?.debug === 'device' || this.platform.debugMode;
|
|
33
|
+
private readonly debugDebug = this.platform.config.options?.debug === 'debug' || this.platform.debugMode;
|
|
30
34
|
|
|
31
35
|
// Updates
|
|
32
36
|
colorBulbUpdateInProgress!: boolean;
|
|
@@ -93,15 +97,38 @@ export class ColorBulb {
|
|
|
93
97
|
// handle ColorTemperature events using the ColorTemperature characteristic
|
|
94
98
|
this.service.getCharacteristic(this.platform.Characteristic.ColorTemperature)
|
|
95
99
|
.setProps({
|
|
96
|
-
|
|
100
|
+
minValue: 140,
|
|
101
|
+
maxValue: 500,
|
|
102
|
+
validValueRanges: [140, 500],
|
|
103
|
+
})
|
|
104
|
+
.onGet(() => {
|
|
105
|
+
return this.ColorTemperature;
|
|
106
|
+
})
|
|
107
|
+
.onSet(this.ColorTemperatureSet.bind(this));
|
|
108
|
+
|
|
109
|
+
// handle Hue events using the Hue characteristic
|
|
110
|
+
this.service.getCharacteristic(this.platform.Characteristic.Hue)
|
|
111
|
+
.setProps({
|
|
112
|
+
minValue: 0,
|
|
113
|
+
maxValue: 360,
|
|
114
|
+
validValueRanges: [0, 360],
|
|
115
|
+
})
|
|
116
|
+
.onGet(() => {
|
|
117
|
+
return this.Hue;
|
|
118
|
+
})
|
|
119
|
+
.onSet(this.HueSet.bind(this));
|
|
120
|
+
|
|
121
|
+
// handle Hue events using the Hue characteristic
|
|
122
|
+
this.service.getCharacteristic(this.platform.Characteristic.Saturation)
|
|
123
|
+
.setProps({
|
|
97
124
|
minValue: 0,
|
|
98
125
|
maxValue: 100,
|
|
99
126
|
validValueRanges: [0, 100],
|
|
100
127
|
})
|
|
101
128
|
.onGet(() => {
|
|
102
|
-
return this.
|
|
129
|
+
return this.Saturation;
|
|
103
130
|
})
|
|
104
|
-
.onSet(this.
|
|
131
|
+
.onSet(this.SaturationSet.bind(this));
|
|
105
132
|
|
|
106
133
|
// Update Homekit
|
|
107
134
|
this.updateHomeKitCharacteristics();
|
|
@@ -126,9 +153,15 @@ export class ColorBulb {
|
|
|
126
153
|
try {
|
|
127
154
|
await this.pushChanges();
|
|
128
155
|
} catch (e: any) {
|
|
129
|
-
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed
|
|
130
|
-
|
|
131
|
-
|
|
156
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges`);
|
|
157
|
+
if (this.deviceDebug) {
|
|
158
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges,`
|
|
159
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
160
|
+
}
|
|
161
|
+
if (this.debugDebug) {
|
|
162
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges,`
|
|
163
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
164
|
+
}
|
|
132
165
|
this.apiError(e);
|
|
133
166
|
}
|
|
134
167
|
this.colorBulbUpdateInProgress = false;
|
|
@@ -152,9 +185,40 @@ export class ColorBulb {
|
|
|
152
185
|
default:
|
|
153
186
|
this.On = false;
|
|
154
187
|
}
|
|
155
|
-
this.platform.
|
|
156
|
-
|
|
157
|
-
|
|
188
|
+
this.platform.log.warn(`Color Bulb: ${this.accessory.displayName} On: ${this.On}`);
|
|
189
|
+
|
|
190
|
+
// Brightness
|
|
191
|
+
this.Brightness = Number(this.deviceStatus.body.brightness);
|
|
192
|
+
this.platform.log.warn(`Color Bulb: ${this.accessory.displayName} Brightness: ${this.Brightness}`);
|
|
193
|
+
|
|
194
|
+
// Color, Hue & Brightness
|
|
195
|
+
if (this.deviceStatus.body.color) {
|
|
196
|
+
this.platform.log.warn(`Color Bulb: ${this.accessory.displayName} color: ${JSON.stringify(this.deviceStatus.body.color)}`);
|
|
197
|
+
const [red, green, blue] = this.deviceStatus.body.color!.split(':');
|
|
198
|
+
this.platform.log.warn(`Color Bulb: ${this.accessory.displayName} red: ${JSON.stringify(red)}`);
|
|
199
|
+
this.platform.log.warn(`Color Bulb: ${this.accessory.displayName} green: ${JSON.stringify(green)}`);
|
|
200
|
+
this.platform.log.warn(`Color Bulb: ${this.accessory.displayName} blue: ${JSON.stringify(blue)}`);
|
|
201
|
+
|
|
202
|
+
const [hue, saturation] = rgb2hs(Number(red), Number(green), Number(blue));
|
|
203
|
+
this.platform.log.warn(`Color Bulb: ${this.accessory.displayName} hs: ${JSON.stringify(rgb2hs(Number(red), Number(green), Number(blue)))}`);
|
|
204
|
+
|
|
205
|
+
// Hue
|
|
206
|
+
this.Hue = hue;
|
|
207
|
+
this.platform.log.warn(`Color Bulb: ${this.accessory.displayName} Hue: ${this.Hue}`);
|
|
208
|
+
|
|
209
|
+
// Saturation
|
|
210
|
+
this.Saturation = saturation;
|
|
211
|
+
this.platform.log.warn(`Color Bulb: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// ColorTemperature
|
|
215
|
+
if (this.deviceStatus.body.colorTemperature) {
|
|
216
|
+
// Convert mired to kelvin to nearest 100 (Govee seems to need this)
|
|
217
|
+
const mired = Math.round(1000000 / this.deviceStatus.body.colorTemperature);
|
|
218
|
+
|
|
219
|
+
this.ColorTemperature = Number(mired);
|
|
220
|
+
this.platform.log.warn(`Color Bulb: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
|
|
221
|
+
}
|
|
158
222
|
}
|
|
159
223
|
|
|
160
224
|
async refreshStatus() {
|
|
@@ -164,37 +228,123 @@ export class ColorBulb {
|
|
|
164
228
|
this.parseStatus();
|
|
165
229
|
this.updateHomeKitCharacteristics();
|
|
166
230
|
} catch (e: any) {
|
|
167
|
-
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed
|
|
168
|
-
|
|
231
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
232
|
+
if (this.deviceDebug) {
|
|
233
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
|
|
234
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
235
|
+
}
|
|
236
|
+
if (this.debugDebug) {
|
|
237
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
|
|
238
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
239
|
+
}
|
|
169
240
|
this.apiError(e);
|
|
170
241
|
}
|
|
171
242
|
}
|
|
172
243
|
|
|
173
244
|
/**
|
|
174
245
|
* Pushes the requested changes to the SwitchBot API
|
|
175
|
-
* deviceType
|
|
176
|
-
* Color Bulb - "command"
|
|
177
|
-
* Color Bulb - "command"
|
|
246
|
+
* deviceType commandType Command command parameter Description
|
|
247
|
+
* Color Bulb - "command" "turnOff" "default" = set to OFF state
|
|
248
|
+
* Color Bulb - "command" "turnOn" "default" = set to ON state
|
|
249
|
+
* Color Bulb - "command" "toggle" "default" = toggle state
|
|
250
|
+
* Color Bulb - "command" "setBrightness" "{1-100}" = set brightness
|
|
251
|
+
* Color Bulb - "command" "setColor" "{0-255}:{0-255}:{0-255}" = set RGB color value
|
|
252
|
+
* Color Bulb - "command" "setColorTemperature" "{2700-6500}" = set color temperature
|
|
178
253
|
*/
|
|
179
254
|
async pushChanges() {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
255
|
+
try {
|
|
256
|
+
// Push On Update
|
|
257
|
+
if (this.On) {
|
|
258
|
+
const payload = {
|
|
259
|
+
commandType: 'command',
|
|
260
|
+
parameter: 'default',
|
|
261
|
+
} as payload;
|
|
262
|
+
|
|
263
|
+
if (this.On) {
|
|
264
|
+
payload.command = 'turnOn';
|
|
265
|
+
} else {
|
|
266
|
+
payload.command = 'turnOff';
|
|
267
|
+
}
|
|
190
268
|
|
|
191
|
-
|
|
192
|
-
|
|
269
|
+
this.platform.log.info(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
|
|
270
|
+
+ ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
|
|
271
|
+
|
|
272
|
+
// Make the API request
|
|
273
|
+
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
274
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
|
|
275
|
+
this.statusCode(push);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Push Brightness Update
|
|
279
|
+
if (this.On) {
|
|
280
|
+
const payload = {
|
|
281
|
+
commandType: 'command',
|
|
282
|
+
command: 'setBrightness',
|
|
283
|
+
parameter: `{${this.Brightness}}`,
|
|
284
|
+
} as payload;
|
|
285
|
+
|
|
286
|
+
this.platform.log.info(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
|
|
287
|
+
+ ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
|
|
288
|
+
|
|
289
|
+
// Make the API request
|
|
290
|
+
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
291
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
|
|
292
|
+
this.statusCode(push);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Push ColorTemperature Update
|
|
296
|
+
if (this.On) {
|
|
297
|
+
const kelvin = Math.round(1000000 / Number(this.ColorTemperature));
|
|
298
|
+
|
|
299
|
+
const payload = {
|
|
300
|
+
commandType: 'command',
|
|
301
|
+
command: 'setColorTemperature',
|
|
302
|
+
parameter: `{${kelvin}}`,
|
|
303
|
+
} as payload;
|
|
304
|
+
|
|
305
|
+
this.platform.log.info(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
|
|
306
|
+
+ ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
|
|
307
|
+
|
|
308
|
+
// Make the API request
|
|
309
|
+
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
310
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
|
|
311
|
+
this.statusCode(push);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Push Hue & Saturation Update
|
|
315
|
+
if (this.On) {
|
|
316
|
+
this.platform.log.warn(JSON.stringify(this.Hue));
|
|
317
|
+
this.platform.log.warn(JSON.stringify(this.Saturation));
|
|
318
|
+
|
|
319
|
+
const [red, green, blue] = hs2rgb(Number(this.Hue), Number(this.Saturation));
|
|
320
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} rgb: ${JSON.stringify([red, green, blue])}`);
|
|
321
|
+
|
|
322
|
+
const payload = {
|
|
323
|
+
commandType: 'command',
|
|
324
|
+
command: 'setColor',
|
|
325
|
+
parameter: `{${red}}:{${green}}:{${blue}}`,
|
|
326
|
+
} as payload;
|
|
327
|
+
|
|
328
|
+
this.platform.log.info(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
|
|
329
|
+
+ ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
|
|
330
|
+
|
|
331
|
+
// Make the API request
|
|
332
|
+
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
333
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
|
|
334
|
+
this.statusCode(push);
|
|
335
|
+
}
|
|
193
336
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
337
|
+
} catch (e: any) {
|
|
338
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
339
|
+
if (this.deviceDebug) {
|
|
340
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
341
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
342
|
+
}
|
|
343
|
+
if (this.debugDebug) {
|
|
344
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
345
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
198
348
|
}
|
|
199
349
|
|
|
200
350
|
updateHomeKitCharacteristics() {
|
|
@@ -216,11 +366,25 @@ export class ColorBulb {
|
|
|
216
366
|
this.service.updateCharacteristic(this.platform.Characteristic.Brightness, this.ColorTemperature);
|
|
217
367
|
this.platform.debug(`Color Bulb: ${this.accessory.displayName} updateCharacteristic ColorTemperature: ${this.ColorTemperature}`);
|
|
218
368
|
}
|
|
369
|
+
if (this.Hue === undefined) {
|
|
370
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} Hue: ${this.Hue}`);
|
|
371
|
+
} else {
|
|
372
|
+
this.service.updateCharacteristic(this.platform.Characteristic.Hue, this.Hue);
|
|
373
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} updateCharacteristic Hue: ${this.Hue}`);
|
|
374
|
+
}
|
|
375
|
+
if (this.Saturation === undefined) {
|
|
376
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} Saturation: ${this.Saturation}`);
|
|
377
|
+
} else {
|
|
378
|
+
this.service.updateCharacteristic(this.platform.Characteristic.Saturation, this.Saturation);
|
|
379
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} updateCharacteristic Saturation: ${this.Saturation}`);
|
|
380
|
+
}
|
|
219
381
|
}
|
|
220
382
|
|
|
221
383
|
public apiError(e: any) {
|
|
222
384
|
this.service.updateCharacteristic(this.platform.Characteristic.On, e);
|
|
385
|
+
this.service.updateCharacteristic(this.platform.Characteristic.Hue, e);
|
|
223
386
|
this.service.updateCharacteristic(this.platform.Characteristic.Brightness, e);
|
|
387
|
+
this.service.updateCharacteristic(this.platform.Characteristic.Saturation, e);
|
|
224
388
|
this.service.updateCharacteristic(this.platform.Characteristic.ColorTemperature, e);
|
|
225
389
|
}
|
|
226
390
|
|
|
@@ -242,8 +406,8 @@ export class ColorBulb {
|
|
|
242
406
|
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} Hub Device is offline.`);
|
|
243
407
|
break;
|
|
244
408
|
case 190:
|
|
245
|
-
|
|
246
|
-
|
|
409
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
|
410
|
+
+ ` Or command: ${JSON.stringify(push.data)} format is invalid`);
|
|
247
411
|
break;
|
|
248
412
|
case 100:
|
|
249
413
|
this.platform.debug(`Color Bulb: ${this.accessory.displayName} Command successfully sent.`);
|
|
@@ -282,4 +446,25 @@ export class ColorBulb {
|
|
|
282
446
|
this.ColorTemperature = value;
|
|
283
447
|
this.doColorBulbUpdate.next();
|
|
284
448
|
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Handle requests to set the value of the "Hue" characteristic
|
|
452
|
+
*/
|
|
453
|
+
HueSet(value: CharacteristicValue) {
|
|
454
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} Hue: ${value}`);
|
|
455
|
+
|
|
456
|
+
this.Hue = value;
|
|
457
|
+
this.doColorBulbUpdate.next();
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Handle requests to set the value of the "Saturation" characteristic
|
|
462
|
+
*/
|
|
463
|
+
SaturationSet(value: CharacteristicValue) {
|
|
464
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} Saturation: ${value}`);
|
|
465
|
+
|
|
466
|
+
this.Saturation = value;
|
|
467
|
+
this.doColorBulbUpdate.next();
|
|
468
|
+
}
|
|
285
469
|
}
|
|
470
|
+
|