@switchbot/homebridge-switchbot 1.2.6-beta.3 → 1.3.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 +9 -0
- package/config.schema.json +11 -1
- package/dist/devices/bots.js +1 -1
- package/dist/devices/bots.js.map +1 -1
- package/dist/devices/colorbulb.d.ts +14 -2
- package/dist/devices/colorbulb.d.ts.map +1 -1
- package/dist/devices/colorbulb.js +127 -30
- package/dist/devices/colorbulb.js.map +1 -1
- package/dist/devices/curtains.js +1 -1
- package/dist/devices/curtains.js.map +1 -1
- package/dist/devices/humidifiers.js +1 -1
- package/dist/devices/humidifiers.js.map +1 -1
- package/dist/devices/indoorcam.d.ts +32 -3
- package/dist/devices/indoorcam.d.ts.map +1 -1
- package/dist/devices/indoorcam.js +92 -45
- package/dist/devices/indoorcam.js.map +1 -1
- package/dist/devices/plugs.js +1 -1
- package/dist/devices/plugs.js.map +1 -1
- package/dist/irdevices/airconditioners.js +1 -1
- package/dist/irdevices/airconditioners.js.map +1 -1
- package/dist/irdevices/airpurifiers.js +1 -1
- package/dist/irdevices/airpurifiers.js.map +1 -1
- package/dist/irdevices/cameras.js +1 -1
- package/dist/irdevices/cameras.js.map +1 -1
- package/dist/irdevices/fans.js +1 -1
- package/dist/irdevices/fans.js.map +1 -1
- package/dist/irdevices/lights.js +1 -1
- package/dist/irdevices/lights.js.map +1 -1
- package/dist/irdevices/others.js +1 -1
- package/dist/irdevices/others.js.map +1 -1
- package/dist/irdevices/tvs.js +1 -1
- package/dist/irdevices/tvs.js.map +1 -1
- package/dist/irdevices/vacuumcleaners.js +1 -1
- package/dist/irdevices/vacuumcleaners.js.map +1 -1
- package/dist/irdevices/waterheaters.js +1 -1
- package/dist/irdevices/waterheaters.js.map +1 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +3 -3
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +1 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/package.json +1 -1
- package/src/devices/bots.ts +1 -1
- package/src/devices/colorbulb.ts +149 -37
- package/src/devices/curtains.ts +1 -1
- package/src/devices/humidifiers.ts +1 -1
- package/src/devices/indoorcam.ts +117 -49
- package/src/devices/plugs.ts +1 -1
- package/src/irdevices/airconditioners.ts +1 -1
- package/src/irdevices/airpurifiers.ts +1 -1
- package/src/irdevices/cameras.ts +1 -1
- package/src/irdevices/fans.ts +1 -1
- package/src/irdevices/lights.ts +1 -1
- package/src/irdevices/others.ts +1 -1
- package/src/irdevices/tvs.ts +1 -1
- package/src/irdevices/vacuumcleaners.ts +1 -1
- package/src/irdevices/waterheaters.ts +1 -1
- package/src/platform.ts +5 -3
- package/src/settings.ts +1 -0
package/src/devices/colorbulb.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { AxiosResponse } from 'axios';
|
|
|
2
2
|
import { interval, Subject } from 'rxjs';
|
|
3
3
|
import { SwitchBotPlatform } from '../platform';
|
|
4
4
|
import { debounceTime, skipWhile, tap } from 'rxjs/operators';
|
|
5
|
-
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
6
|
-
import { DeviceURL, device, devicesConfig, switchbot, deviceStatusResponse, payload, hs2rgb, rgb2hs } from '../settings';
|
|
5
|
+
import { Service, PlatformAccessory, CharacteristicValue, ControllerConstructor, Controller, ControllerServiceMap } from 'homebridge';
|
|
6
|
+
import { DeviceURL, device, devicesConfig, switchbot, deviceStatusResponse, payload, hs2rgb, rgb2hs, m2hs } from '../settings';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Platform Accessory
|
|
@@ -16,10 +16,15 @@ export class ColorBulb {
|
|
|
16
16
|
|
|
17
17
|
// Characteristic Values
|
|
18
18
|
On!: CharacteristicValue;
|
|
19
|
+
OnCached!: CharacteristicValue;
|
|
19
20
|
Hue!: CharacteristicValue;
|
|
20
|
-
|
|
21
|
+
HueCached!: CharacteristicValue;
|
|
21
22
|
Saturation!: CharacteristicValue;
|
|
23
|
+
SaturationCached!: CharacteristicValue;
|
|
24
|
+
Brightness!: CharacteristicValue;
|
|
25
|
+
BrightnessCached!: CharacteristicValue;
|
|
22
26
|
ColorTemperature!: CharacteristicValue;
|
|
27
|
+
ColorTemperatureCached!: CharacteristicValue;
|
|
23
28
|
|
|
24
29
|
// OpenAPI Others
|
|
25
30
|
deviceStatus!: deviceStatusResponse;
|
|
@@ -32,9 +37,15 @@ export class ColorBulb {
|
|
|
32
37
|
private readonly deviceDebug = this.platform.config.options?.debug === 'device' || this.platform.debugMode;
|
|
33
38
|
private readonly debugDebug = this.platform.config.options?.debug === 'debug' || this.platform.debugMode;
|
|
34
39
|
|
|
40
|
+
// Adaptive Lighting
|
|
41
|
+
AdaptiveLightingController: ControllerConstructor | Controller<ControllerServiceMap>;
|
|
42
|
+
minKelvin: number;
|
|
43
|
+
maxKelvin: number;
|
|
44
|
+
|
|
35
45
|
// Updates
|
|
36
46
|
colorBulbUpdateInProgress!: boolean;
|
|
37
47
|
doColorBulbUpdate!: Subject<void>;
|
|
48
|
+
cacheKelvin!: number;
|
|
38
49
|
|
|
39
50
|
constructor(
|
|
40
51
|
private readonly platform: SwitchBotPlatform,
|
|
@@ -45,11 +56,13 @@ export class ColorBulb {
|
|
|
45
56
|
this.platform.device(`Color Bulb: ${this.accessory.displayName} Config: (ble: ${device.ble}, set_minStep: ${device.colorbulb?.set_minStep}`);
|
|
46
57
|
|
|
47
58
|
// default placeholders
|
|
59
|
+
this.minKelvin = 2000;
|
|
60
|
+
this.maxKelvin = 9000;
|
|
61
|
+
this.Hue = 0;
|
|
48
62
|
this.On = false;
|
|
49
|
-
this.ColorTemperature = 140;
|
|
50
63
|
this.Brightness = 0;
|
|
51
64
|
this.Saturation = 0;
|
|
52
|
-
this.
|
|
65
|
+
this.ColorTemperature = 140;
|
|
53
66
|
|
|
54
67
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
55
68
|
this.doColorBulbUpdate = new Subject();
|
|
@@ -109,6 +122,7 @@ export class ColorBulb {
|
|
|
109
122
|
})
|
|
110
123
|
.onSet(this.ColorTemperatureSet.bind(this));
|
|
111
124
|
|
|
125
|
+
|
|
112
126
|
// handle Hue events using the Hue characteristic
|
|
113
127
|
this.service.getCharacteristic(this.platform.Characteristic.Hue)
|
|
114
128
|
.setProps({
|
|
@@ -133,6 +147,12 @@ export class ColorBulb {
|
|
|
133
147
|
})
|
|
134
148
|
.onSet(this.SaturationSet.bind(this));
|
|
135
149
|
|
|
150
|
+
const adaptiveLightingShift = device.colorbulb?.adaptiveLightingShift || 0;
|
|
151
|
+
this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.service, {
|
|
152
|
+
customTemperatureAdjustment: adaptiveLightingShift,
|
|
153
|
+
});
|
|
154
|
+
this.accessory.configureController(this.AdaptiveLightingController);
|
|
155
|
+
|
|
136
156
|
// Update Homekit
|
|
137
157
|
this.updateHomeKitCharacteristics();
|
|
138
158
|
|
|
@@ -258,32 +278,70 @@ export class ColorBulb {
|
|
|
258
278
|
*/
|
|
259
279
|
async pushChanges() {
|
|
260
280
|
try {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
281
|
+
if (this.On !== this.OnCached) {
|
|
282
|
+
// Push On Update
|
|
283
|
+
const payload = {
|
|
284
|
+
commandType: 'command',
|
|
285
|
+
parameter: 'default',
|
|
286
|
+
} as payload;
|
|
287
|
+
|
|
288
|
+
if (this.On) {
|
|
289
|
+
payload.command = 'turnOn';
|
|
290
|
+
} else {
|
|
291
|
+
payload.command = 'turnOff';
|
|
292
|
+
}
|
|
266
293
|
|
|
294
|
+
this.platform.log.info(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
|
|
295
|
+
+ ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
|
|
296
|
+
|
|
297
|
+
// Make the API request
|
|
298
|
+
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
299
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
|
|
300
|
+
this.statusCode(push);
|
|
301
|
+
this.OnCached = this.On;
|
|
302
|
+
}
|
|
303
|
+
// Push Brightness Update
|
|
267
304
|
if (this.On) {
|
|
268
|
-
|
|
269
|
-
} else {
|
|
270
|
-
payload.command = 'turnOff';
|
|
305
|
+
await this.pushBrightnessChanges();
|
|
271
306
|
}
|
|
272
307
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
278
|
-
this.platform.debug(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
|
|
279
|
-
this.statusCode(push);
|
|
308
|
+
// Push ColorTemperature Update
|
|
309
|
+
if (this.On) {
|
|
310
|
+
await this.pushColorTemperatureChanges();
|
|
311
|
+
}
|
|
280
312
|
|
|
281
|
-
// Push
|
|
313
|
+
// Push Hue & Saturation Update
|
|
282
314
|
if (this.On) {
|
|
315
|
+
await this.pushHueSaturationChanges();
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
} catch (e: any) {
|
|
319
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
320
|
+
if (this.deviceDebug) {
|
|
321
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
322
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
323
|
+
}
|
|
324
|
+
if (this.debugDebug) {
|
|
325
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
326
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
327
|
+
}
|
|
328
|
+
this.apiError(e);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
private async pushHueSaturationChanges() {
|
|
333
|
+
try {
|
|
334
|
+
if ((this.Hue !== this.HueCached) || (this.Saturation !== this.SaturationCached)) {
|
|
335
|
+
this.platform.device(`Color Bulb: ${this.accessory.displayName} Hue: ${JSON.stringify(this.Hue)}`);
|
|
336
|
+
this.platform.device(`Color Bulb: ${this.accessory.displayName} Saturation: ${JSON.stringify(this.Saturation)}`);
|
|
337
|
+
|
|
338
|
+
const [red, green, blue] = hs2rgb(Number(this.Hue), Number(this.Saturation));
|
|
339
|
+
this.platform.device(`Color Bulb: ${this.accessory.displayName} rgb: ${JSON.stringify([red, green, blue])}`);
|
|
340
|
+
|
|
283
341
|
const payload = {
|
|
284
342
|
commandType: 'command',
|
|
285
|
-
command: '
|
|
286
|
-
parameter: `${
|
|
343
|
+
command: 'setColor',
|
|
344
|
+
parameter: `${red}:${green}:${blue}`,
|
|
287
345
|
} as payload;
|
|
288
346
|
|
|
289
347
|
this.platform.log.info(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
|
|
@@ -293,11 +351,31 @@ export class ColorBulb {
|
|
|
293
351
|
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
294
352
|
this.platform.debug(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
|
|
295
353
|
this.statusCode(push);
|
|
354
|
+
this.HueCached = this.Hue;
|
|
355
|
+
this.SaturationCached = this.Saturation;
|
|
356
|
+
} else {
|
|
357
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} No Changes.`
|
|
358
|
+
+ `Hue: ${this.Hue}, HueCached: ${this.HueCached}, Saturation: ${this.Saturation}, SaturationCached: ${this.SaturationCached}`);
|
|
359
|
+
}
|
|
360
|
+
} catch (e: any) {
|
|
361
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
362
|
+
if (this.deviceDebug) {
|
|
363
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
364
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
296
365
|
}
|
|
366
|
+
if (this.debugDebug) {
|
|
367
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
368
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
369
|
+
}
|
|
370
|
+
this.apiError(e);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
297
373
|
|
|
298
|
-
|
|
299
|
-
|
|
374
|
+
private async pushColorTemperatureChanges() {
|
|
375
|
+
try {
|
|
376
|
+
if (this.ColorTemperature !== this.ColorTemperatureCached) {
|
|
300
377
|
const kelvin = Math.round(1000000 / Number(this.ColorTemperature));
|
|
378
|
+
this.cacheKelvin = kelvin;
|
|
301
379
|
|
|
302
380
|
const payload = {
|
|
303
381
|
commandType: 'command',
|
|
@@ -312,20 +390,32 @@ export class ColorBulb {
|
|
|
312
390
|
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
313
391
|
this.platform.debug(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
|
|
314
392
|
this.statusCode(push);
|
|
393
|
+
this.ColorTemperatureCached = this.ColorTemperature;
|
|
394
|
+
} else {
|
|
395
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} No Changes.`
|
|
396
|
+
+ `ColorTemperature: ${this.ColorTemperature}, ColorTemperatureCached: ${this.ColorTemperatureCached}`);
|
|
315
397
|
}
|
|
398
|
+
} catch (e: any) {
|
|
399
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
400
|
+
if (this.deviceDebug) {
|
|
401
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
402
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
403
|
+
}
|
|
404
|
+
if (this.debugDebug) {
|
|
405
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
406
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
407
|
+
}
|
|
408
|
+
this.apiError(e);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
316
411
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
this.platform.device(`Color Bulb: ${this.accessory.displayName} Saturation: ${JSON.stringify(this.Saturation)}`);
|
|
321
|
-
|
|
322
|
-
const [red, green, blue] = hs2rgb(Number(this.Hue), Number(this.Saturation));
|
|
323
|
-
this.platform.device(`Color Bulb: ${this.accessory.displayName} rgb: ${JSON.stringify([red, green, blue])}`);
|
|
324
|
-
|
|
412
|
+
private async pushBrightnessChanges() {
|
|
413
|
+
try {
|
|
414
|
+
if (this.Brightness !== this.BrightnessCached) {
|
|
325
415
|
const payload = {
|
|
326
416
|
commandType: 'command',
|
|
327
|
-
command: '
|
|
328
|
-
parameter: `${
|
|
417
|
+
command: 'setBrightness',
|
|
418
|
+
parameter: `${this.Brightness}`,
|
|
329
419
|
} as payload;
|
|
330
420
|
|
|
331
421
|
this.platform.log.info(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
|
|
@@ -335,8 +425,11 @@ export class ColorBulb {
|
|
|
335
425
|
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
336
426
|
this.platform.debug(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
|
|
337
427
|
this.statusCode(push);
|
|
428
|
+
this.BrightnessCached = this.Brightness;
|
|
429
|
+
} else {
|
|
430
|
+
this.platform.debug(`Color Bulb: ${this.accessory.displayName} No Changes.`
|
|
431
|
+
+ `Brightness: ${this.Brightness}, BrightnessCached: ${this.BrightnessCached}`);
|
|
338
432
|
}
|
|
339
|
-
|
|
340
433
|
} catch (e: any) {
|
|
341
434
|
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
342
435
|
if (this.deviceDebug) {
|
|
@@ -407,7 +500,7 @@ export class ColorBulb {
|
|
|
407
500
|
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} Device is offline.`);
|
|
408
501
|
break;
|
|
409
502
|
case 171:
|
|
410
|
-
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} Hub Device is offline
|
|
503
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
411
504
|
break;
|
|
412
505
|
case 190:
|
|
413
506
|
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
|
@@ -447,6 +540,21 @@ export class ColorBulb {
|
|
|
447
540
|
ColorTemperatureSet(value: CharacteristicValue) {
|
|
448
541
|
this.platform.debug(`Color Bulb: ${this.accessory.displayName} ColorTemperature: ${value}`);
|
|
449
542
|
|
|
543
|
+
// Convert mired to kelvin to nearest 100 (SwitchBot seems to need this)
|
|
544
|
+
const kelvin = Math.round(1000000 / Number(value) / 100) * 100;
|
|
545
|
+
|
|
546
|
+
// Check and increase/decrease kelvin to range of device
|
|
547
|
+
const k = Math.min(Math.max(kelvin, this.minKelvin), this.maxKelvin);
|
|
548
|
+
|
|
549
|
+
if (!this.OnCached || this.cacheKelvin === k) {
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// Updating the hue/sat to the corresponding values mimics native adaptive lighting
|
|
554
|
+
const hs = m2hs(value);
|
|
555
|
+
this.service.updateCharacteristic(this.platform.Characteristic.Hue, hs[0]);
|
|
556
|
+
this.service.updateCharacteristic(this.platform.Characteristic.Saturation, hs[1]);
|
|
557
|
+
|
|
450
558
|
this.ColorTemperature = value;
|
|
451
559
|
this.doColorBulbUpdate.next();
|
|
452
560
|
}
|
|
@@ -457,6 +565,8 @@ export class ColorBulb {
|
|
|
457
565
|
HueSet(value: CharacteristicValue) {
|
|
458
566
|
this.platform.debug(`Color Bulb: ${this.accessory.displayName} Hue: ${value}`);
|
|
459
567
|
|
|
568
|
+
this.service.updateCharacteristic(this.platform.Characteristic.ColorTemperature, 140);
|
|
569
|
+
|
|
460
570
|
this.Hue = value;
|
|
461
571
|
this.doColorBulbUpdate.next();
|
|
462
572
|
}
|
|
@@ -467,6 +577,8 @@ export class ColorBulb {
|
|
|
467
577
|
SaturationSet(value: CharacteristicValue) {
|
|
468
578
|
this.platform.debug(`Color Bulb: ${this.accessory.displayName} Saturation: ${value}`);
|
|
469
579
|
|
|
580
|
+
this.service.updateCharacteristic(this.platform.Characteristic.ColorTemperature, 140);
|
|
581
|
+
|
|
470
582
|
this.Saturation = value;
|
|
471
583
|
this.doColorBulbUpdate.next();
|
|
472
584
|
}
|
package/src/devices/curtains.ts
CHANGED
|
@@ -632,7 +632,7 @@ export class Curtain {
|
|
|
632
632
|
this.platform.log.error(`Curtain: ${this.accessory.displayName} Device is offline.`);
|
|
633
633
|
break;
|
|
634
634
|
case 171:
|
|
635
|
-
this.platform.log.error(`Curtain: ${this.accessory.displayName} Hub Device is offline
|
|
635
|
+
this.platform.log.error(`Curtain: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
636
636
|
break;
|
|
637
637
|
case 190:
|
|
638
638
|
this.platform.log.error(`Curtain: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
|
@@ -630,7 +630,7 @@ export class Humidifier {
|
|
|
630
630
|
this.platform.log.error(`Humidifier: ${this.accessory.displayName} Device is offline.`);
|
|
631
631
|
break;
|
|
632
632
|
case 171:
|
|
633
|
-
this.platform.log.error(`Humidifier: ${this.accessory.displayName} Hub Device is offline
|
|
633
|
+
this.platform.log.error(`Humidifier: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
634
634
|
break;
|
|
635
635
|
case 190:
|
|
636
636
|
this.platform.log.error(`Humidifier: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
package/src/devices/indoorcam.ts
CHANGED
|
@@ -10,8 +10,13 @@ export class IndoorCam {
|
|
|
10
10
|
private service: Service;
|
|
11
11
|
|
|
12
12
|
// Characteristic Values
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
Active!: CharacteristicValue;
|
|
14
|
+
SetupEndpoints!: CharacteristicValue;
|
|
15
|
+
StreamingStatus!: CharacteristicValue;
|
|
16
|
+
SupportedRTPConfiguration!: CharacteristicValue;
|
|
17
|
+
SelectedRTPStreamConfiguration!: CharacteristicValue;
|
|
18
|
+
SupportedVideoStreamConfiguration!: CharacteristicValue;
|
|
19
|
+
SupportedAudioStreamConfiguration!: CharacteristicValue;
|
|
15
20
|
|
|
16
21
|
// OpenAPI Others
|
|
17
22
|
deviceStatus!: deviceStatusResponse;
|
|
@@ -29,9 +34,12 @@ export class IndoorCam {
|
|
|
29
34
|
private accessory: PlatformAccessory,
|
|
30
35
|
public device: device & devicesConfig,
|
|
31
36
|
) {
|
|
37
|
+
// Indoor Cam Config
|
|
38
|
+
this.platform.device(`Indoor Cam: ${this.accessory.displayName} Config: (hide_device: ${device.hide_device})`);
|
|
39
|
+
|
|
40
|
+
this.platform.log.error(`Indoor Cam: ${this.accessory.displayName} was added but will not work as OpenAPI doesn't support it yet.`);
|
|
32
41
|
// default placeholders
|
|
33
|
-
this.
|
|
34
|
-
this.OutletInUse = true;
|
|
42
|
+
this.SelectedRTPStreamConfiguration;
|
|
35
43
|
|
|
36
44
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
37
45
|
this.doCameraUpdate = new Subject();
|
|
@@ -50,8 +58,8 @@ export class IndoorCam {
|
|
|
50
58
|
// get the WindowCovering service if it exists, otherwise create a new WindowCovering service
|
|
51
59
|
// you can create multiple services for each accessory
|
|
52
60
|
(this.service =
|
|
53
|
-
accessory.getService(this.platform.Service.
|
|
54
|
-
accessory.addService(this.platform.Service.
|
|
61
|
+
accessory.getService(this.platform.Service.CameraRTPStreamManagement) ||
|
|
62
|
+
accessory.addService(this.platform.Service.CameraRTPStreamManagement)), `${accessory.displayName} Indoor Camera`;
|
|
55
63
|
|
|
56
64
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
57
65
|
// when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
|
|
@@ -65,9 +73,26 @@ export class IndoorCam {
|
|
|
65
73
|
// see https://developers.homebridge.io/#/service/WindowCovering
|
|
66
74
|
|
|
67
75
|
// create handlers for required characteristics
|
|
68
|
-
this.service.getCharacteristic(this.platform.Characteristic.
|
|
76
|
+
this.service.getCharacteristic(this.platform.Characteristic.Active)
|
|
77
|
+
.onSet(this.ActiveSet.bind(this));
|
|
78
|
+
|
|
79
|
+
this.service.getCharacteristic(this.platform.Characteristic.SelectedRTPStreamConfiguration)
|
|
80
|
+
.onSet(this.SelectedRTPStreamConfigurationSet.bind(this));
|
|
81
|
+
|
|
82
|
+
this.service.getCharacteristic(this.platform.Characteristic.SetupEndpoints)
|
|
83
|
+
.onSet(this.SetupEndpointsSet.bind(this));
|
|
84
|
+
|
|
85
|
+
this.service.getCharacteristic(this.platform.Characteristic.StreamingStatus)
|
|
86
|
+
.onSet(this.StreamingStatusSet.bind(this));
|
|
69
87
|
|
|
70
|
-
this.service.
|
|
88
|
+
this.service.getCharacteristic(this.platform.Characteristic.SupportedAudioStreamConfiguration)
|
|
89
|
+
.onSet(this.SupportedAudioStreamConfigurationSet.bind(this));
|
|
90
|
+
|
|
91
|
+
this.service.getCharacteristic(this.platform.Characteristic.SupportedRTPConfiguration)
|
|
92
|
+
.onSet(this.SupportedRTPConfigurationSet.bind(this));
|
|
93
|
+
|
|
94
|
+
this.service.getCharacteristic(this.platform.Characteristic.SupportedVideoStreamConfiguration)
|
|
95
|
+
.onSet(this.SupportedVideoStreamConfigurationSet.bind(this));
|
|
71
96
|
|
|
72
97
|
// Update Homekit
|
|
73
98
|
this.updateHomeKitCharacteristics();
|
|
@@ -108,14 +133,7 @@ export class IndoorCam {
|
|
|
108
133
|
}
|
|
109
134
|
|
|
110
135
|
parseStatus() {
|
|
111
|
-
|
|
112
|
-
case 'on':
|
|
113
|
-
this.On = true;
|
|
114
|
-
break;
|
|
115
|
-
default:
|
|
116
|
-
this.On = false;
|
|
117
|
-
}
|
|
118
|
-
this.platform.debug(`Indoor Cam ${this.accessory.displayName} On: ${this.On}`);
|
|
136
|
+
this.platform.debug(`Indoor Cam ${this.accessory.displayName} SelectedRTPStreamConfiguration: ${this.SelectedRTPStreamConfiguration}`);
|
|
119
137
|
}
|
|
120
138
|
|
|
121
139
|
|
|
@@ -146,45 +164,37 @@ export class IndoorCam {
|
|
|
146
164
|
* Camera - "command" "turnOn" "default" = set to ON state
|
|
147
165
|
*/
|
|
148
166
|
async pushChanges() {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
167
|
+
if (!this.Active) {
|
|
168
|
+
const payload = {
|
|
169
|
+
commandType: 'command',
|
|
170
|
+
parameter: 'default',
|
|
171
|
+
command: 'turnOn',
|
|
172
|
+
} as payload;
|
|
173
|
+
|
|
174
|
+
this.platform.log.info(`Indoor Cam: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
|
|
175
|
+
+ ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
|
|
176
|
+
|
|
177
|
+
// Make the API request
|
|
178
|
+
const push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
|
|
179
|
+
this.platform.debug(`Indoor Cam: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
|
|
180
|
+
this.statusCode(push);
|
|
181
|
+
this.refreshStatus();
|
|
156
182
|
} else {
|
|
157
|
-
|
|
183
|
+
this.platform.device(`Indoor Cam: ${this.accessory.displayName} No pushChanges. Active: ${this.Active}`);
|
|
158
184
|
}
|
|
159
|
-
|
|
160
|
-
this.platform.log.info(`Indoor Cam: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
|
|
161
|
-
+ ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
|
|
162
|
-
|
|
163
|
-
// Make the API request
|
|
164
|
-
const push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
|
|
165
|
-
this.platform.debug(`Indoor Cam: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
|
|
166
|
-
this.statusCode(push);
|
|
167
|
-
this.refreshStatus();
|
|
168
185
|
}
|
|
169
186
|
|
|
170
187
|
updateHomeKitCharacteristics() {
|
|
171
|
-
if (this.
|
|
172
|
-
this.platform.debug(`Indoor Cam: ${this.accessory.displayName} On: ${this.
|
|
188
|
+
if (this.SelectedRTPStreamConfiguration === undefined) {
|
|
189
|
+
this.platform.debug(`Indoor Cam: ${this.accessory.displayName} On: ${this.SelectedRTPStreamConfiguration}`);
|
|
173
190
|
} else {
|
|
174
|
-
this.service.updateCharacteristic(this.platform.Characteristic.
|
|
175
|
-
this.platform.device(`Indoor Cam: ${this.accessory.displayName} updateCharacteristic On: ${this.
|
|
176
|
-
}
|
|
177
|
-
if (this.OutletInUse === undefined) {
|
|
178
|
-
this.platform.debug(`Indoor Cam: ${this.accessory.displayName} OutletInUse: ${this.OutletInUse}`);
|
|
179
|
-
} else {
|
|
180
|
-
this.service.updateCharacteristic(this.platform.Characteristic.OutletInUse, this.OutletInUse);
|
|
181
|
-
this.platform.device(`Indoor Cam: ${this.accessory.displayName} updateCharacteristic OutletInUse: ${this.OutletInUse}`);
|
|
191
|
+
this.service.updateCharacteristic(this.platform.Characteristic.SelectedRTPStreamConfiguration, this.SelectedRTPStreamConfiguration);
|
|
192
|
+
this.platform.device(`Indoor Cam: ${this.accessory.displayName} updateCharacteristic On: ${this.SelectedRTPStreamConfiguration}`);
|
|
182
193
|
}
|
|
183
194
|
}
|
|
184
195
|
|
|
185
196
|
public apiError(e: any) {
|
|
186
|
-
this.service.updateCharacteristic(this.platform.Characteristic.
|
|
187
|
-
this.service.updateCharacteristic(this.platform.Characteristic.OutletInUse, e);
|
|
197
|
+
this.service.updateCharacteristic(this.platform.Characteristic.SelectedRTPStreamConfiguration, e);
|
|
188
198
|
}
|
|
189
199
|
|
|
190
200
|
private statusCode(push: AxiosResponse<{ statusCode: number; }>) {
|
|
@@ -202,7 +212,7 @@ export class IndoorCam {
|
|
|
202
212
|
this.platform.log.error(`Indoor Cam: ${this.accessory.displayName} Device is offline.`);
|
|
203
213
|
break;
|
|
204
214
|
case 171:
|
|
205
|
-
this.platform.log.error(`Indoor Cam: ${this.accessory.displayName} Hub Device is offline
|
|
215
|
+
this.platform.log.error(`Indoor Cam: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
206
216
|
break;
|
|
207
217
|
case 190:
|
|
208
218
|
this.platform.log.error(`Indoor Cam: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
|
@@ -216,15 +226,73 @@ export class IndoorCam {
|
|
|
216
226
|
}
|
|
217
227
|
}
|
|
218
228
|
|
|
229
|
+
/**
|
|
230
|
+
* Handle requests to set the value of the "Active" characteristic
|
|
231
|
+
*/
|
|
232
|
+
ActiveSet(value: CharacteristicValue) {
|
|
233
|
+
this.platform.debug(`Indoor Cam: ${this.accessory.displayName} Active: ${value}`);
|
|
234
|
+
|
|
235
|
+
this.Active = value;
|
|
236
|
+
this.doCameraUpdate.next();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Handle requests to set the value of the "SelectedRTPStreamConfiguration" characteristic
|
|
241
|
+
*/
|
|
242
|
+
SelectedRTPStreamConfigurationSet(value: CharacteristicValue) {
|
|
243
|
+
this.platform.debug(`Indoor Cam: ${this.accessory.displayName} SelectedRTPStreamConfiguration: ${value}`);
|
|
244
|
+
|
|
245
|
+
this.SelectedRTPStreamConfiguration = value;
|
|
246
|
+
this.doCameraUpdate.next();
|
|
247
|
+
}
|
|
248
|
+
|
|
219
249
|
/**
|
|
220
250
|
* Handle requests to set the value of the "On" characteristic
|
|
221
251
|
*/
|
|
222
|
-
|
|
223
|
-
this.platform.debug(`Indoor Cam: ${this.accessory.displayName}
|
|
252
|
+
SetupEndpointsSet(value: CharacteristicValue) {
|
|
253
|
+
this.platform.debug(`Indoor Cam: ${this.accessory.displayName} SetupEndpoints: ${value}`);
|
|
224
254
|
|
|
225
|
-
this.
|
|
255
|
+
this.SetupEndpoints = value;
|
|
226
256
|
this.doCameraUpdate.next();
|
|
227
257
|
}
|
|
228
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Handle requests to set the value of the "On" characteristic
|
|
261
|
+
*/
|
|
262
|
+
SupportedAudioStreamConfigurationSet(value: CharacteristicValue) {
|
|
263
|
+
this.platform.debug(`Indoor Cam: ${this.accessory.displayName} SupportedAudioStreamConfiguration: ${value}`);
|
|
264
|
+
|
|
265
|
+
this.SupportedAudioStreamConfiguration = value;
|
|
266
|
+
this.doCameraUpdate.next();
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Handle requests to set the value of the "On" characteristic
|
|
271
|
+
*/
|
|
272
|
+
SupportedRTPConfigurationSet(value: CharacteristicValue) {
|
|
273
|
+
this.platform.debug(`Indoor Cam: ${this.accessory.displayName} SupportedRTPConfiguration: ${value}`);
|
|
274
|
+
|
|
275
|
+
this.SupportedRTPConfiguration = value;
|
|
276
|
+
this.doCameraUpdate.next();
|
|
277
|
+
}
|
|
229
278
|
|
|
279
|
+
/**
|
|
280
|
+
* Handle requests to set the value of the "On" characteristic
|
|
281
|
+
*/
|
|
282
|
+
StreamingStatusSet(value: CharacteristicValue) {
|
|
283
|
+
this.platform.debug(`Indoor Cam: ${this.accessory.displayName} StreamingStatus: ${value}`);
|
|
284
|
+
|
|
285
|
+
this.StreamingStatus = value;
|
|
286
|
+
this.doCameraUpdate.next();
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Handle requests to set the value of the "On" characteristic
|
|
291
|
+
*/
|
|
292
|
+
SupportedVideoStreamConfigurationSet(value: CharacteristicValue) {
|
|
293
|
+
this.platform.debug(`Indoor Cam: ${this.accessory.displayName} SupportedVideoStreamConfiguration: ${value}`);
|
|
294
|
+
|
|
295
|
+
this.SupportedVideoStreamConfiguration = value;
|
|
296
|
+
this.doCameraUpdate.next();
|
|
297
|
+
}
|
|
230
298
|
}
|
package/src/devices/plugs.ts
CHANGED
|
@@ -190,7 +190,7 @@ export class Plug {
|
|
|
190
190
|
this.platform.log.error(`Plug: ${this.accessory.displayName} Device is offline.`);
|
|
191
191
|
break;
|
|
192
192
|
case 171:
|
|
193
|
-
this.platform.log.error(`Plug: ${this.accessory.displayName} Hub Device is offline
|
|
193
|
+
this.platform.log.error(`Plug: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
194
194
|
break;
|
|
195
195
|
case 190:
|
|
196
196
|
this.platform.log.error(`Plug: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
|
@@ -379,7 +379,7 @@ export class AirConditioner {
|
|
|
379
379
|
this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} Device is offline.`);
|
|
380
380
|
break;
|
|
381
381
|
case 171:
|
|
382
|
-
this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} Hub Device is offline
|
|
382
|
+
this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
383
383
|
break;
|
|
384
384
|
case 190:
|
|
385
385
|
this.platform.log.error(`Air Conditioner: ${this.accessory.displayName} Device internal error due to device states not synchronized`
|
|
@@ -239,7 +239,7 @@ export class AirPurifier {
|
|
|
239
239
|
this.platform.log.error(`Air Purifier: ${this.accessory.displayName} Device is offline.`);
|
|
240
240
|
break;
|
|
241
241
|
case 171:
|
|
242
|
-
this.platform.log.error(`Air Purifier: ${this.accessory.displayName} Hub Device is offline
|
|
242
|
+
this.platform.log.error(`Air Purifier: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
243
243
|
break;
|
|
244
244
|
case 190:
|
|
245
245
|
this.platform.log.error(`Air Purifier: ${this.accessory.displayName} Device internal error due to device states not synchronized`
|
package/src/irdevices/cameras.ts
CHANGED
|
@@ -139,7 +139,7 @@ export class Camera {
|
|
|
139
139
|
this.platform.log.error(`Camera: ${this.accessory.displayName} Device is offline.`);
|
|
140
140
|
break;
|
|
141
141
|
case 171:
|
|
142
|
-
this.platform.log.error(`Camera: ${this.accessory.displayName} Hub Device is offline
|
|
142
|
+
this.platform.log.error(`Camera: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
143
143
|
break;
|
|
144
144
|
case 190:
|
|
145
145
|
this.platform.log.error(`Camera: ${this.accessory.displayName} Device internal error due to device states not synchronized`
|
package/src/irdevices/fans.ts
CHANGED
|
@@ -261,7 +261,7 @@ export class Fan {
|
|
|
261
261
|
this.platform.log.error(`Fan: ${this.accessory.displayName} Device is offline.`);
|
|
262
262
|
break;
|
|
263
263
|
case 171:
|
|
264
|
-
this.platform.log.error(`Fan: ${this.accessory.displayName} Hub Device is offline
|
|
264
|
+
this.platform.log.error(`Fan: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
265
265
|
break;
|
|
266
266
|
case 190:
|
|
267
267
|
this.platform.log.error(`Fan: ${this.accessory.displayName} Device internal error due to device states not synchronized`
|
package/src/irdevices/lights.ts
CHANGED
|
@@ -173,7 +173,7 @@ export class Light {
|
|
|
173
173
|
this.platform.log.error(`Light: ${this.accessory.displayName} Device is offline.`);
|
|
174
174
|
break;
|
|
175
175
|
case 171:
|
|
176
|
-
this.platform.log.error(`Light: ${this.accessory.displayName} Hub Device is offline
|
|
176
|
+
this.platform.log.error(`Light: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
177
177
|
break;
|
|
178
178
|
case 190:
|
|
179
179
|
this.platform.log.error(`Light: ${this.accessory.displayName} Device internal error due to device states not synchronized`
|
package/src/irdevices/others.ts
CHANGED
|
@@ -160,7 +160,7 @@ export class Others {
|
|
|
160
160
|
this.platform.log.error(`Other: ${this.accessory.displayName} Device is offline.`);
|
|
161
161
|
break;
|
|
162
162
|
case 171:
|
|
163
|
-
this.platform.log.error(`Other: ${this.accessory.displayName} Hub Device is offline
|
|
163
|
+
this.platform.log.error(`Other: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
164
164
|
break;
|
|
165
165
|
case 190:
|
|
166
166
|
this.platform.log.error(`Other: ${this.accessory.displayName} Device internal error due to device states not synchronized`
|
package/src/irdevices/tvs.ts
CHANGED
|
@@ -377,7 +377,7 @@ export class TV {
|
|
|
377
377
|
this.platform.log.error(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline.`);
|
|
378
378
|
break;
|
|
379
379
|
case 171:
|
|
380
|
-
this.platform.log.error(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline
|
|
380
|
+
this.platform.log.error(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
381
381
|
break;
|
|
382
382
|
case 190:
|
|
383
383
|
this.platform.log.error(`${this.device.remoteType}: `
|
|
@@ -139,7 +139,7 @@ export class VacuumCleaner {
|
|
|
139
139
|
this.platform.log.error(`Vacuum Cleaner: ${this.accessory.displayName} Device is offline.`);
|
|
140
140
|
break;
|
|
141
141
|
case 171:
|
|
142
|
-
this.platform.log.error(`Vacuum Cleaner: ${this.accessory.displayName} Hub Device is offline
|
|
142
|
+
this.platform.log.error(`Vacuum Cleaner: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
143
143
|
break;
|
|
144
144
|
case 190:
|
|
145
145
|
this.platform.log.error(`Vacuum Cleaner: ${this.accessory.displayName} Device internal error due to device states not synchronized`
|
|
@@ -153,7 +153,7 @@ export class WaterHeater {
|
|
|
153
153
|
this.platform.log.error(`Water Heater: ${this.accessory.displayName} Device is offline.`);
|
|
154
154
|
break;
|
|
155
155
|
case 171:
|
|
156
|
-
this.platform.log.error(`Water Heater: ${this.accessory.displayName} Hub Device is offline
|
|
156
|
+
this.platform.log.error(`Water Heater: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
157
157
|
break;
|
|
158
158
|
case 190:
|
|
159
159
|
this.platform.log.error(`Water Heater: ${this.accessory.displayName} Device internal error due to device states not synchronized`
|