@switchbot/homebridge-switchbot 1.9.0 → 1.9.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/.eslintrc +3 -1
- package/.github/ISSUE_TEMPLATE/bug-report.yml +3 -3
- package/.github/ISSUE_TEMPLATE/feature-request.yml +2 -2
- package/.github/ISSUE_TEMPLATE/support-request.yml +3 -3
- package/.github/labeler.yml +1 -1
- package/.github/workflows/codeql-analysis.yml +29 -29
- package/.github/workflows/nodejs-beta.yml +1 -1
- package/.github/workflows/prerelease-beta.js +1 -1
- package/.github/workflows/stale.yml +1 -1
- package/.prettierrc +9 -0
- package/.vscode/settings.json +13 -1
- package/README.md +100 -99
- package/SECURITY.md +2 -2
- package/dist/devices/bots.d.ts +2 -2
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +91 -86
- package/dist/devices/bots.js.map +1 -1
- package/dist/devices/colorbulb.d.ts +15 -15
- package/dist/devices/colorbulb.d.ts.map +1 -1
- package/dist/devices/colorbulb.js +60 -71
- package/dist/devices/colorbulb.js.map +1 -1
- package/dist/devices/contact.d.ts +2 -2
- package/dist/devices/contact.d.ts.map +1 -1
- package/dist/devices/contact.js +33 -31
- package/dist/devices/contact.js.map +1 -1
- package/dist/devices/curtains.d.ts +2 -2
- package/dist/devices/curtains.d.ts.map +1 -1
- package/dist/devices/curtains.js +71 -71
- package/dist/devices/curtains.js.map +1 -1
- package/dist/devices/humidifiers.d.ts +2 -2
- package/dist/devices/humidifiers.d.ts.map +1 -1
- package/dist/devices/humidifiers.js +74 -76
- package/dist/devices/humidifiers.js.map +1 -1
- package/dist/devices/meters.d.ts +2 -2
- package/dist/devices/meters.d.ts.map +1 -1
- package/dist/devices/meters.js +29 -27
- package/dist/devices/meters.js.map +1 -1
- package/dist/devices/motion.d.ts +2 -2
- package/dist/devices/motion.d.ts.map +1 -1
- package/dist/devices/motion.js +34 -32
- package/dist/devices/motion.js.map +1 -1
- package/dist/devices/plugs.d.ts +7 -7
- package/dist/devices/plugs.d.ts.map +1 -1
- package/dist/devices/plugs.js +18 -23
- package/dist/devices/plugs.js.map +1 -1
- package/dist/irdevices/airconditioners.d.ts +2 -2
- package/dist/irdevices/airconditioners.d.ts.map +1 -1
- package/dist/irdevices/airconditioners.js +36 -45
- package/dist/irdevices/airconditioners.js.map +1 -1
- package/dist/irdevices/airpurifiers.d.ts +2 -2
- package/dist/irdevices/airpurifiers.d.ts.map +1 -1
- package/dist/irdevices/airpurifiers.js +12 -17
- package/dist/irdevices/airpurifiers.js.map +1 -1
- package/dist/irdevices/cameras.d.ts +2 -2
- package/dist/irdevices/cameras.d.ts.map +1 -1
- package/dist/irdevices/cameras.js +10 -13
- package/dist/irdevices/cameras.js.map +1 -1
- package/dist/irdevices/fans.d.ts +2 -2
- package/dist/irdevices/fans.d.ts.map +1 -1
- package/dist/irdevices/fans.js +15 -17
- package/dist/irdevices/fans.js.map +1 -1
- package/dist/irdevices/lights.d.ts +2 -2
- package/dist/irdevices/lights.d.ts.map +1 -1
- package/dist/irdevices/lights.js +10 -13
- package/dist/irdevices/lights.js.map +1 -1
- package/dist/irdevices/others.d.ts +2 -2
- package/dist/irdevices/others.d.ts.map +1 -1
- package/dist/irdevices/others.js +10 -13
- package/dist/irdevices/others.js.map +1 -1
- package/dist/irdevices/tvs.d.ts +2 -2
- package/dist/irdevices/tvs.d.ts.map +1 -1
- package/dist/irdevices/tvs.js +22 -30
- package/dist/irdevices/tvs.js.map +1 -1
- package/dist/irdevices/vacuumcleaners.d.ts +2 -2
- package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
- package/dist/irdevices/vacuumcleaners.js +11 -13
- package/dist/irdevices/vacuumcleaners.js.map +1 -1
- package/dist/irdevices/waterheaters.d.ts +2 -2
- package/dist/irdevices/waterheaters.d.ts.map +1 -1
- package/dist/irdevices/waterheaters.js +10 -13
- package/dist/irdevices/waterheaters.js.map +1 -1
- package/dist/platform.d.ts +3 -3
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +13 -14
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/homebridge-ui/public/index.html +231 -245
- package/homebridge-ui/server.js +2 -4
- package/nodemon.json +2 -4
- package/package.json +75 -71
- package/src/devices/bots.ts +217 -186
- package/src/devices/colorbulb.ts +90 -84
- package/src/devices/contact.ts +85 -78
- package/src/devices/curtains.ts +152 -135
- package/src/devices/humidifiers.ts +162 -137
- package/src/devices/meters.ts +76 -73
- package/src/devices/motion.ts +87 -78
- package/src/devices/plugs.ts +27 -31
- package/src/irdevices/airconditioners.ts +72 -55
- package/src/irdevices/airpurifiers.ts +22 -23
- package/src/irdevices/cameras.ts +18 -19
- package/src/irdevices/fans.ts +27 -25
- package/src/irdevices/lights.ts +18 -20
- package/src/irdevices/others.ts +18 -19
- package/src/irdevices/tvs.ts +33 -41
- package/src/irdevices/vacuumcleaners.ts +19 -19
- package/src/irdevices/waterheaters.ts +21 -31
- package/src/platform.ts +32 -33
- package/src/settings.ts +8 -19
- package/.github/PULL_REQUEST_TEMPLATE/pull_requests.md +0 -27
package/src/irdevices/others.ts
CHANGED
|
@@ -20,11 +20,7 @@ export class Others {
|
|
|
20
20
|
deviceLogging!: string;
|
|
21
21
|
otherDeviceType?: string;
|
|
22
22
|
|
|
23
|
-
constructor(
|
|
24
|
-
private readonly platform: SwitchBotPlatform,
|
|
25
|
-
private accessory: PlatformAccessory,
|
|
26
|
-
public device: irdevice & irDevicesConfig,
|
|
27
|
-
) {
|
|
23
|
+
constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: irdevice & irDevicesConfig) {
|
|
28
24
|
// default placeholders
|
|
29
25
|
this.logs(device);
|
|
30
26
|
this.deviceType(device);
|
|
@@ -54,9 +50,8 @@ export class Others {
|
|
|
54
50
|
accessory.removeService(this.service!);
|
|
55
51
|
} else if (!this.service && this.otherDeviceType === 'Fan') {
|
|
56
52
|
this.debugLog(`Other: ${accessory.displayName} Add Fanv2 Service`);
|
|
57
|
-
(this.service =
|
|
58
|
-
|
|
59
|
-
this.accessory.addService(this.platform.Service.Fanv2)), `${accessory.displayName} Fan`;
|
|
53
|
+
(this.service = this.accessory.getService(this.platform.Service.Fanv2) || this.accessory.addService(this.platform.Service.Fanv2)),
|
|
54
|
+
`${accessory.displayName} Fan`;
|
|
60
55
|
|
|
61
56
|
this.service.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Fan`);
|
|
62
57
|
|
|
@@ -145,8 +140,10 @@ export class Others {
|
|
|
145
140
|
|
|
146
141
|
public async pushChanges(payload: payload) {
|
|
147
142
|
try {
|
|
148
|
-
this.infoLog(
|
|
149
|
-
|
|
143
|
+
this.infoLog(
|
|
144
|
+
`Other: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
|
|
145
|
+
` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
|
|
146
|
+
);
|
|
150
147
|
|
|
151
148
|
// Make the API request
|
|
152
149
|
const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
|
|
@@ -156,18 +153,18 @@ export class Others {
|
|
|
156
153
|
} catch (e: any) {
|
|
157
154
|
this.errorLog(`Other: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
158
155
|
if (this.deviceLogging === 'debug') {
|
|
159
|
-
this.errorLog(
|
|
160
|
-
+ ` Error Message: ${JSON.stringify(e.message)}
|
|
156
|
+
this.errorLog(
|
|
157
|
+
`Other: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
158
|
+
);
|
|
161
159
|
}
|
|
162
160
|
if (this.platform.debugMode) {
|
|
163
|
-
this.errorLog(`Other: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
164
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
161
|
+
this.errorLog(`Other: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error: ${JSON.stringify(e)}`);
|
|
165
162
|
}
|
|
166
163
|
this.apiError(e);
|
|
167
164
|
}
|
|
168
165
|
}
|
|
169
166
|
|
|
170
|
-
private statusCode(push: AxiosResponse<{ statusCode: number
|
|
167
|
+
private statusCode(push: AxiosResponse<{ statusCode: number }>) {
|
|
171
168
|
switch (push.data.statusCode) {
|
|
172
169
|
case 151:
|
|
173
170
|
this.errorLog(`Other: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
@@ -185,8 +182,10 @@ export class Others {
|
|
|
185
182
|
this.errorLog(`Other: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
186
183
|
break;
|
|
187
184
|
case 190:
|
|
188
|
-
this.errorLog(
|
|
189
|
-
|
|
185
|
+
this.errorLog(
|
|
186
|
+
`Other: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
|
|
187
|
+
` with server, Or command: ${JSON.stringify(push.data)} format is invalid`,
|
|
188
|
+
);
|
|
190
189
|
break;
|
|
191
190
|
case 100:
|
|
192
191
|
this.debugLog(`Other: ${this.accessory.displayName} Command successfully sent.`);
|
|
@@ -242,8 +241,8 @@ export class Others {
|
|
|
242
241
|
}
|
|
243
242
|
|
|
244
243
|
/**
|
|
245
|
-
|
|
246
|
-
|
|
244
|
+
* Logging for Device
|
|
245
|
+
*/
|
|
247
246
|
infoLog(...log: any[]) {
|
|
248
247
|
if (this.enablingDeviceLogging()) {
|
|
249
248
|
this.platform.log.info(String(...log));
|
package/src/irdevices/tvs.ts
CHANGED
|
@@ -24,11 +24,7 @@ export class TV {
|
|
|
24
24
|
// Config
|
|
25
25
|
deviceLogging!: string;
|
|
26
26
|
|
|
27
|
-
constructor(
|
|
28
|
-
private readonly platform: SwitchBotPlatform,
|
|
29
|
-
private accessory: PlatformAccessory,
|
|
30
|
-
public device: irdevice & irDevicesConfig,
|
|
31
|
-
) {
|
|
27
|
+
constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: irdevice & irDevicesConfig) {
|
|
32
28
|
// default placeholders
|
|
33
29
|
this.logs(device);
|
|
34
30
|
this.config(device);
|
|
@@ -51,34 +47,30 @@ export class TV {
|
|
|
51
47
|
case 'Speaker':
|
|
52
48
|
case 'DIY Speaker':
|
|
53
49
|
accessory.category = this.platform.api.hap.Categories.SPEAKER;
|
|
54
|
-
(this.service =
|
|
55
|
-
|
|
56
|
-
accessory.addService(this.platform.Service.Television)), `${accessory.displayName} Speaker`;
|
|
50
|
+
(this.service = accessory.getService(this.platform.Service.Television) || accessory.addService(this.platform.Service.Television)),
|
|
51
|
+
`${accessory.displayName} Speaker`;
|
|
57
52
|
break;
|
|
58
53
|
case 'IPTV':
|
|
59
54
|
case 'DIY IPTV':
|
|
60
55
|
accessory.category = this.platform.api.hap.Categories.TV_STREAMING_STICK;
|
|
61
|
-
(this.service =
|
|
62
|
-
|
|
63
|
-
accessory.addService(this.platform.Service.Television)), `${accessory.displayName} Streaming Stick`;
|
|
56
|
+
(this.service = accessory.getService(this.platform.Service.Television) || accessory.addService(this.platform.Service.Television)),
|
|
57
|
+
`${accessory.displayName} Streaming Stick`;
|
|
64
58
|
break;
|
|
65
59
|
case 'DVD':
|
|
66
60
|
case 'DIY DVD':
|
|
67
61
|
case 'Set Top Box':
|
|
68
62
|
case 'DIY Set Top Box':
|
|
69
63
|
accessory.category = this.platform.api.hap.Categories.TV_SET_TOP_BOX;
|
|
70
|
-
(this.service =
|
|
71
|
-
|
|
72
|
-
accessory.addService(this.platform.Service.Television)), `${accessory.displayName} Set Top Box`;
|
|
64
|
+
(this.service = accessory.getService(this.platform.Service.Television) || accessory.addService(this.platform.Service.Television)),
|
|
65
|
+
`${accessory.displayName} Set Top Box`;
|
|
73
66
|
break;
|
|
74
67
|
default:
|
|
75
68
|
accessory.category = this.platform.api.hap.Categories.TELEVISION;
|
|
76
69
|
|
|
77
70
|
// get the Television service if it exists, otherwise create a new Television service
|
|
78
71
|
// you can create multiple services for each accessory
|
|
79
|
-
(this.service =
|
|
80
|
-
|
|
81
|
-
accessory.addService(this.platform.Service.Television)), `${accessory.displayName} TV`;
|
|
72
|
+
(this.service = accessory.getService(this.platform.Service.Television) || accessory.addService(this.platform.Service.Television)),
|
|
73
|
+
`${accessory.displayName} TV`;
|
|
82
74
|
}
|
|
83
75
|
|
|
84
76
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
@@ -111,22 +103,17 @@ export class TV {
|
|
|
111
103
|
*/
|
|
112
104
|
// create a new Television Speaker service
|
|
113
105
|
(this.speakerService =
|
|
114
|
-
accessory.getService(this.platform.Service.TelevisionSpeaker) ||
|
|
115
|
-
|
|
106
|
+
accessory.getService(this.platform.Service.TelevisionSpeaker) || accessory.addService(this.platform.Service.TelevisionSpeaker)),
|
|
107
|
+
`${accessory.displayName} Speaker`;
|
|
116
108
|
|
|
117
109
|
this.speakerService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Speaker`);
|
|
118
110
|
|
|
119
111
|
this.speakerService
|
|
120
112
|
.setCharacteristic(this.platform.Characteristic.Active, this.platform.Characteristic.Active.ACTIVE)
|
|
121
|
-
.setCharacteristic(
|
|
122
|
-
this.platform.Characteristic.VolumeControlType,
|
|
123
|
-
this.platform.Characteristic.VolumeControlType.ABSOLUTE,
|
|
124
|
-
);
|
|
113
|
+
.setCharacteristic(this.platform.Characteristic.VolumeControlType, this.platform.Characteristic.VolumeControlType.ABSOLUTE);
|
|
125
114
|
|
|
126
115
|
// handle volume control
|
|
127
|
-
this.speakerService
|
|
128
|
-
.getCharacteristic(this.platform.Characteristic.VolumeSelector)
|
|
129
|
-
.onSet(this.VolumeSelectorSet.bind(this));
|
|
116
|
+
this.speakerService.getCharacteristic(this.platform.Characteristic.VolumeSelector).onSet(this.VolumeSelectorSet.bind(this));
|
|
130
117
|
}
|
|
131
118
|
|
|
132
119
|
private VolumeSelectorSet(value: CharacteristicValue) {
|
|
@@ -232,8 +219,7 @@ export class TV {
|
|
|
232
219
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} ActiveIdentifier: ${this.ActiveIdentifier}`);
|
|
233
220
|
} else {
|
|
234
221
|
this.service?.updateCharacteristic(this.platform.Characteristic.ActiveIdentifier, this.ActiveIdentifier);
|
|
235
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName}`
|
|
236
|
-
+ ` updateCharacteristic ActiveIdentifier: ${this.ActiveIdentifier}`);
|
|
222
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName}` + ` updateCharacteristic ActiveIdentifier: ${this.ActiveIdentifier}`);
|
|
237
223
|
}
|
|
238
224
|
}
|
|
239
225
|
|
|
@@ -350,8 +336,10 @@ export class TV {
|
|
|
350
336
|
|
|
351
337
|
public async pushTVChanges(payload: payload) {
|
|
352
338
|
try {
|
|
353
|
-
this.infoLog(
|
|
354
|
-
|
|
339
|
+
this.infoLog(
|
|
340
|
+
`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
|
|
341
|
+
` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
|
|
342
|
+
);
|
|
355
343
|
|
|
356
344
|
// Make the API request
|
|
357
345
|
const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
|
|
@@ -361,19 +349,21 @@ export class TV {
|
|
|
361
349
|
} catch (e: any) {
|
|
362
350
|
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
363
351
|
if (this.deviceLogging === 'debug') {
|
|
364
|
-
this.errorLog(
|
|
365
|
-
|
|
352
|
+
this.errorLog(
|
|
353
|
+
`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` +
|
|
354
|
+
` Error Message: ${JSON.stringify(e.message)}`,
|
|
355
|
+
);
|
|
366
356
|
}
|
|
367
357
|
if (this.platform.debugMode) {
|
|
368
|
-
this.errorLog(
|
|
369
|
-
+ ` Error: ${JSON.stringify(e)}
|
|
358
|
+
this.errorLog(
|
|
359
|
+
`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error: ${JSON.stringify(e)}`,
|
|
360
|
+
);
|
|
370
361
|
}
|
|
371
362
|
this.apiError(e);
|
|
372
363
|
}
|
|
373
364
|
}
|
|
374
365
|
|
|
375
|
-
|
|
376
|
-
private statusCode(push: AxiosResponse<{ statusCode: number; }>) {
|
|
366
|
+
private statusCode(push: AxiosResponse<{ statusCode: number }>) {
|
|
377
367
|
switch (push.data.statusCode) {
|
|
378
368
|
case 151:
|
|
379
369
|
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
@@ -391,9 +381,11 @@ export class TV {
|
|
|
391
381
|
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
392
382
|
break;
|
|
393
383
|
case 190:
|
|
394
|
-
this.errorLog(
|
|
395
|
-
|
|
396
|
-
|
|
384
|
+
this.errorLog(
|
|
385
|
+
`${this.device.remoteType}: ` +
|
|
386
|
+
`${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
387
|
+
` Or command: ${JSON.stringify(push.data)} format is invalid`,
|
|
388
|
+
);
|
|
397
389
|
break;
|
|
398
390
|
case 100:
|
|
399
391
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent.`);
|
|
@@ -439,8 +431,8 @@ export class TV {
|
|
|
439
431
|
}
|
|
440
432
|
|
|
441
433
|
/**
|
|
442
|
-
|
|
443
|
-
|
|
434
|
+
* Logging for Device
|
|
435
|
+
*/
|
|
444
436
|
infoLog(...log: any[]) {
|
|
445
437
|
if (this.enablingDeviceLogging()) {
|
|
446
438
|
this.platform.log.info(String(...log));
|
|
@@ -19,11 +19,7 @@ export class VacuumCleaner {
|
|
|
19
19
|
// Config
|
|
20
20
|
deviceLogging!: string;
|
|
21
21
|
|
|
22
|
-
constructor(
|
|
23
|
-
private readonly platform: SwitchBotPlatform,
|
|
24
|
-
private accessory: PlatformAccessory,
|
|
25
|
-
public device: irdevice & irDevicesConfig,
|
|
26
|
-
) {
|
|
22
|
+
constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: irdevice & irDevicesConfig) {
|
|
27
23
|
// default placeholders
|
|
28
24
|
this.logs(device);
|
|
29
25
|
this.config(device);
|
|
@@ -42,9 +38,8 @@ export class VacuumCleaner {
|
|
|
42
38
|
|
|
43
39
|
// get the Television service if it exists, otherwise create a new Television service
|
|
44
40
|
// you can create multiple services for each accessory
|
|
45
|
-
(this.service =
|
|
46
|
-
|
|
47
|
-
accessory.addService(this.platform.Service.Switch)), `${accessory.displayName} Vacuum`;
|
|
41
|
+
(this.service = accessory.getService(this.platform.Service.Switch) || accessory.addService(this.platform.Service.Switch)),
|
|
42
|
+
`${accessory.displayName} Vacuum`;
|
|
48
43
|
|
|
49
44
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
50
45
|
// when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
|
|
@@ -111,8 +106,10 @@ export class VacuumCleaner {
|
|
|
111
106
|
|
|
112
107
|
public async pushChanges(payload: payload) {
|
|
113
108
|
try {
|
|
114
|
-
this.infoLog(
|
|
115
|
-
|
|
109
|
+
this.infoLog(
|
|
110
|
+
`Vacuum Cleaner: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
|
|
111
|
+
` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
|
|
112
|
+
);
|
|
116
113
|
|
|
117
114
|
// Make the API request
|
|
118
115
|
const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
|
|
@@ -124,18 +121,19 @@ export class VacuumCleaner {
|
|
|
124
121
|
} catch (e: any) {
|
|
125
122
|
this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
126
123
|
if (this.deviceLogging === 'debug') {
|
|
127
|
-
this.errorLog(
|
|
128
|
-
|
|
124
|
+
this.errorLog(
|
|
125
|
+
`Vacuum Cleaner: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` +
|
|
126
|
+
` Error Message: ${JSON.stringify(e.message)}`,
|
|
127
|
+
);
|
|
129
128
|
}
|
|
130
129
|
if (this.platform.debugMode) {
|
|
131
|
-
this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
132
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
130
|
+
this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error: ${JSON.stringify(e)}`);
|
|
133
131
|
}
|
|
134
132
|
this.apiError(e);
|
|
135
133
|
}
|
|
136
134
|
}
|
|
137
135
|
|
|
138
|
-
private statusCode(push: AxiosResponse<{ statusCode: number
|
|
136
|
+
private statusCode(push: AxiosResponse<{ statusCode: number }>) {
|
|
139
137
|
switch (push.data.statusCode) {
|
|
140
138
|
case 151:
|
|
141
139
|
this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
@@ -153,8 +151,10 @@ export class VacuumCleaner {
|
|
|
153
151
|
this.errorLog(`Vacuum Cleaner: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
154
152
|
break;
|
|
155
153
|
case 190:
|
|
156
|
-
this.errorLog(
|
|
157
|
-
|
|
154
|
+
this.errorLog(
|
|
155
|
+
`Vacuum Cleaner: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
|
|
156
|
+
` with server, Or command: ${JSON.stringify(push.data)} format is invalid`,
|
|
157
|
+
);
|
|
158
158
|
break;
|
|
159
159
|
case 100:
|
|
160
160
|
this.debugLog(`Vacuum Cleaner: ${this.accessory.displayName} Command successfully sent.`);
|
|
@@ -199,8 +199,8 @@ export class VacuumCleaner {
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
/**
|
|
202
|
-
|
|
203
|
-
|
|
202
|
+
* Logging for Device
|
|
203
|
+
*/
|
|
204
204
|
infoLog(...log: any[]) {
|
|
205
205
|
if (this.enablingDeviceLogging()) {
|
|
206
206
|
this.platform.log.info(String(...log));
|
|
@@ -19,11 +19,7 @@ export class WaterHeater {
|
|
|
19
19
|
// Config
|
|
20
20
|
deviceLogging!: string;
|
|
21
21
|
|
|
22
|
-
constructor(
|
|
23
|
-
private readonly platform: SwitchBotPlatform,
|
|
24
|
-
private accessory: PlatformAccessory,
|
|
25
|
-
public device: irdevice & irDevicesConfig,
|
|
26
|
-
) {
|
|
22
|
+
constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: irdevice & irDevicesConfig) {
|
|
27
23
|
// default placeholders
|
|
28
24
|
this.logs(device);
|
|
29
25
|
this.config(device);
|
|
@@ -42,9 +38,8 @@ export class WaterHeater {
|
|
|
42
38
|
|
|
43
39
|
// get the Television service if it exists, otherwise create a new Television service
|
|
44
40
|
// you can create multiple services for each accessory
|
|
45
|
-
(this.service =
|
|
46
|
-
|
|
47
|
-
accessory.addService(this.platform.Service.Valve)), `${accessory.displayName} Water Heater`;
|
|
41
|
+
(this.service = accessory.getService(this.platform.Service.Valve) || accessory.addService(this.platform.Service.Valve)),
|
|
42
|
+
`${accessory.displayName} Water Heater`;
|
|
48
43
|
|
|
49
44
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
50
45
|
// when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
|
|
@@ -52,16 +47,10 @@ export class WaterHeater {
|
|
|
52
47
|
|
|
53
48
|
// set the service name, this is what is displayed as the default name on the Home app
|
|
54
49
|
// in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
|
|
55
|
-
this.service.setCharacteristic(
|
|
56
|
-
this.platform.Characteristic.Name,
|
|
57
|
-
`${device.deviceName} ${device.remoteType}`,
|
|
58
|
-
);
|
|
50
|
+
this.service.setCharacteristic(this.platform.Characteristic.Name, `${device.deviceName} ${device.remoteType}`);
|
|
59
51
|
|
|
60
52
|
// set sleep discovery characteristic
|
|
61
|
-
this.service.setCharacteristic(
|
|
62
|
-
this.platform.Characteristic.ValveType,
|
|
63
|
-
this.platform.Characteristic.ValveType.GENERIC_VALVE,
|
|
64
|
-
);
|
|
53
|
+
this.service.setCharacteristic(this.platform.Characteristic.ValveType, this.platform.Characteristic.ValveType.GENERIC_VALVE);
|
|
65
54
|
|
|
66
55
|
// handle on / off events using the Active characteristic
|
|
67
56
|
this.service.getCharacteristic(this.platform.Characteristic.Active).onSet(this.ActiveSet.bind(this));
|
|
@@ -71,10 +60,7 @@ export class WaterHeater {
|
|
|
71
60
|
this.debugLog(`Water Heater: ${this.accessory.displayName} Active: ${value}`);
|
|
72
61
|
if (value === this.platform.Characteristic.Active.INACTIVE) {
|
|
73
62
|
this.pushWaterHeaterOffChanges();
|
|
74
|
-
this.service.setCharacteristic(
|
|
75
|
-
this.platform.Characteristic.InUse,
|
|
76
|
-
this.platform.Characteristic.InUse.NOT_IN_USE,
|
|
77
|
-
);
|
|
63
|
+
this.service.setCharacteristic(this.platform.Characteristic.InUse, this.platform.Characteristic.InUse.NOT_IN_USE);
|
|
78
64
|
} else {
|
|
79
65
|
this.pushWaterHeaterOnChanges();
|
|
80
66
|
this.service.setCharacteristic(this.platform.Characteristic.InUse, this.platform.Characteristic.InUse.IN_USE);
|
|
@@ -127,8 +113,10 @@ export class WaterHeater {
|
|
|
127
113
|
|
|
128
114
|
public async pushChanges(payload: payload) {
|
|
129
115
|
try {
|
|
130
|
-
this.infoLog(
|
|
131
|
-
|
|
116
|
+
this.infoLog(
|
|
117
|
+
`Water Heater: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
|
|
118
|
+
` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
|
|
119
|
+
);
|
|
132
120
|
|
|
133
121
|
// Make the API request
|
|
134
122
|
const push = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
|
|
@@ -138,18 +126,18 @@ export class WaterHeater {
|
|
|
138
126
|
} catch (e: any) {
|
|
139
127
|
this.errorLog(`Water Heater: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
140
128
|
if (this.deviceLogging === 'debug') {
|
|
141
|
-
this.errorLog(
|
|
142
|
-
+ ` Error Message: ${JSON.stringify(e.message)}
|
|
129
|
+
this.errorLog(
|
|
130
|
+
`Water Heater: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
131
|
+
);
|
|
143
132
|
}
|
|
144
133
|
if (this.platform.debugMode) {
|
|
145
|
-
this.errorLog(`Water Heater: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
146
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
134
|
+
this.errorLog(`Water Heater: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error: ${JSON.stringify(e)}`);
|
|
147
135
|
}
|
|
148
136
|
this.apiError(e);
|
|
149
137
|
}
|
|
150
138
|
}
|
|
151
139
|
|
|
152
|
-
private statusCode(push: AxiosResponse<{ statusCode: number
|
|
140
|
+
private statusCode(push: AxiosResponse<{ statusCode: number }>) {
|
|
153
141
|
switch (push.data.statusCode) {
|
|
154
142
|
case 151:
|
|
155
143
|
this.errorLog(`Water Heater: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
@@ -167,8 +155,10 @@ export class WaterHeater {
|
|
|
167
155
|
this.errorLog(`Water Heater: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
168
156
|
break;
|
|
169
157
|
case 190:
|
|
170
|
-
this.errorLog(
|
|
171
|
-
|
|
158
|
+
this.errorLog(
|
|
159
|
+
`Water Heater: ${this.accessory.displayName} Device internal error due to device states not synchronized` +
|
|
160
|
+
` with server, Or command: ${JSON.stringify(push.data)} format is invalid`,
|
|
161
|
+
);
|
|
172
162
|
break;
|
|
173
163
|
case 100:
|
|
174
164
|
this.debugLog(`Water Heater: ${this.accessory.displayName} Command successfully sent.`);
|
|
@@ -213,8 +203,8 @@ export class WaterHeater {
|
|
|
213
203
|
}
|
|
214
204
|
|
|
215
205
|
/**
|
|
216
|
-
|
|
217
|
-
|
|
206
|
+
* Logging for Device
|
|
207
|
+
*/
|
|
218
208
|
infoLog(...log: any[]) {
|
|
219
209
|
if (this.enablingDeviceLogging()) {
|
|
220
210
|
this.platform.log.info(String(...log));
|
package/src/platform.ts
CHANGED
|
@@ -51,8 +51,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
51
51
|
|
|
52
52
|
// HOOBS notice
|
|
53
53
|
if (__dirname.includes('hoobs')) {
|
|
54
|
-
this.log.warn('This plugin has not been tested under HOOBS, it is highly recommended that '
|
|
55
|
-
'you switch to Homebridge: https://git.io/Jtxb0');
|
|
54
|
+
this.log.warn('This plugin has not been tested under HOOBS, it is highly recommended that you switch to Homebridge: https://git.io/Jtxb0');
|
|
56
55
|
}
|
|
57
56
|
|
|
58
57
|
// verify the config
|
|
@@ -207,8 +206,8 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
207
206
|
}
|
|
208
207
|
|
|
209
208
|
/**
|
|
210
|
-
|
|
211
|
-
|
|
209
|
+
* this method discovers devices
|
|
210
|
+
*/
|
|
212
211
|
async discoverDevices() {
|
|
213
212
|
try {
|
|
214
213
|
if (this.config.credentials?.openToken) {
|
|
@@ -234,10 +233,12 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
234
233
|
this.debugLog(`SwitchBot Device Config Set: ${JSON.stringify(this.config.options?.devices)}`);
|
|
235
234
|
const deviceConfigs = this.config.options?.devices;
|
|
236
235
|
|
|
237
|
-
const mergeBydeviceId = (a1: { deviceId: string
|
|
238
|
-
a1.map((itm: { deviceId: string
|
|
239
|
-
...a2.find(
|
|
240
|
-
item
|
|
236
|
+
const mergeBydeviceId = (a1: { deviceId: string }[], a2: any[]) =>
|
|
237
|
+
a1.map((itm: { deviceId: string }) => ({
|
|
238
|
+
...a2.find(
|
|
239
|
+
(item: { deviceId: string }) =>
|
|
240
|
+
item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item,
|
|
241
|
+
),
|
|
241
242
|
...itm,
|
|
242
243
|
}));
|
|
243
244
|
|
|
@@ -269,10 +270,12 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
269
270
|
this.debugLog(`IR Device Config Set: ${JSON.stringify(this.config.options?.irdevices)}`);
|
|
270
271
|
const irDeviceConfig = this.config.options?.irdevices;
|
|
271
272
|
|
|
272
|
-
const mergeIRBydeviceId = (a1: { deviceId: string
|
|
273
|
-
a1.map((itm: { deviceId: string
|
|
274
|
-
...a2.find(
|
|
275
|
-
item
|
|
273
|
+
const mergeIRBydeviceId = (a1: { deviceId: string }[], a2: any[]) =>
|
|
274
|
+
a1.map((itm: { deviceId: string }) => ({
|
|
275
|
+
...a2.find(
|
|
276
|
+
(item: { deviceId: string }) =>
|
|
277
|
+
item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item,
|
|
278
|
+
),
|
|
276
279
|
...itm,
|
|
277
280
|
}));
|
|
278
281
|
|
|
@@ -324,8 +327,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
324
327
|
this.debugLog('The client has defined a contentType header that is not supported by the server.');
|
|
325
328
|
} else if (e.message.includes('422')) {
|
|
326
329
|
this.errorLog('Failed to Discover Devices: Unprocessable Entity');
|
|
327
|
-
this.debugLog(
|
|
328
|
-
|
|
330
|
+
this.debugLog(
|
|
331
|
+
'The client has made a valid request, but the server cannot process it.' +
|
|
332
|
+
' This is often used for APIs for which certain limits have been exceeded.',
|
|
333
|
+
);
|
|
329
334
|
} else if (e.message.includes('429')) {
|
|
330
335
|
this.errorLog('Failed to Discover Devices: Too Many Requests');
|
|
331
336
|
this.debugLog('The client has exceeded the number of requests allowed for a given time window.');
|
|
@@ -826,8 +831,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
826
831
|
}
|
|
827
832
|
|
|
828
833
|
private isCurtainGrouped(device: device & devicesConfig) {
|
|
829
|
-
this.debugLog(
|
|
830
|
-
|
|
834
|
+
this.debugLog(
|
|
835
|
+
`deviceId: ${device.deviceId}, curtainDevicesIds: ${device.curtainDevicesIds},` +
|
|
836
|
+
` master: ${device.master}, group: ${device.group}, disable_group: ${device.curtain?.disable_group}`,
|
|
837
|
+
);
|
|
831
838
|
|
|
832
839
|
if (device.group && !device.curtain?.disable_group) {
|
|
833
840
|
this.debugLog(`[Curtain Config] disable_group: ${device.curtain?.disable_group}`);
|
|
@@ -991,10 +998,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
991
998
|
this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
|
|
992
999
|
|
|
993
1000
|
/**
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1001
|
+
* Publish as external accessory
|
|
1002
|
+
* Only one TV can exist per bridge, to bypass this limitation, you should
|
|
1003
|
+
* publish your TV as an external accessory.
|
|
1004
|
+
*/
|
|
998
1005
|
this.api.publishExternalAccessories(PLUGIN_NAME, [accessory]);
|
|
999
1006
|
this.accessories.push(accessory);
|
|
1000
1007
|
} else {
|
|
@@ -1443,9 +1450,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
1443
1450
|
}
|
|
1444
1451
|
}
|
|
1445
1452
|
|
|
1446
|
-
public async connectionTypeNewAccessory(
|
|
1447
|
-
device: device & devicesConfig,
|
|
1448
|
-
accessory: PlatformAccessory) {
|
|
1453
|
+
public async connectionTypeNewAccessory(device: device & devicesConfig, accessory: PlatformAccessory) {
|
|
1449
1454
|
if (device.ble) {
|
|
1450
1455
|
accessory.context.connectionType = 'BLE';
|
|
1451
1456
|
} else {
|
|
@@ -1453,10 +1458,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
1453
1458
|
}
|
|
1454
1459
|
}
|
|
1455
1460
|
|
|
1456
|
-
public async connectionTypeExistingAccessory(
|
|
1457
|
-
device: device & devicesConfig,
|
|
1458
|
-
existingAccessory: PlatformAccessory,
|
|
1459
|
-
) {
|
|
1461
|
+
public async connectionTypeExistingAccessory(device: device & devicesConfig, existingAccessory: PlatformAccessory) {
|
|
1460
1462
|
if (device.ble) {
|
|
1461
1463
|
existingAccessory.context.connectionType = 'BLE';
|
|
1462
1464
|
} else {
|
|
@@ -1464,14 +1466,11 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
1464
1466
|
}
|
|
1465
1467
|
}
|
|
1466
1468
|
|
|
1467
|
-
public async connectionTypeNewIRAccessory(
|
|
1468
|
-
accessory: PlatformAccessory) {
|
|
1469
|
+
public async connectionTypeNewIRAccessory(accessory: PlatformAccessory) {
|
|
1469
1470
|
accessory.context.connectionType = 'IR wirth OpenAPI';
|
|
1470
1471
|
}
|
|
1471
1472
|
|
|
1472
|
-
public async connectionTypeExistingIRAccessory(
|
|
1473
|
-
existingAccessory: PlatformAccessory,
|
|
1474
|
-
) {
|
|
1473
|
+
public async connectionTypeExistingIRAccessory(existingAccessory: PlatformAccessory) {
|
|
1475
1474
|
existingAccessory.context.connectionType = 'IR with OpenAPI';
|
|
1476
1475
|
}
|
|
1477
1476
|
|
|
@@ -1487,7 +1486,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
1487
1486
|
}
|
|
1488
1487
|
}
|
|
1489
1488
|
|
|
1490
|
-
public async deviceInfo(device: irdevice & devicesConfig | device & devicesConfig) {
|
|
1489
|
+
public async deviceInfo(device: (irdevice & devicesConfig) | (device & devicesConfig)) {
|
|
1491
1490
|
if (this.platformLogging === 'debug') {
|
|
1492
1491
|
this.warnLog(JSON.stringify(device));
|
|
1493
1492
|
this.deviceStatus = (await this.axios.get(`${DeviceURL}/${device.deviceId}/status`)).data;
|
package/src/settings.ts
CHANGED
|
@@ -66,7 +66,7 @@ export type bot = {
|
|
|
66
66
|
mode?: string;
|
|
67
67
|
deviceType?: string;
|
|
68
68
|
doublePress?: number;
|
|
69
|
-
allowPush?: boolean
|
|
69
|
+
allowPush?: boolean;
|
|
70
70
|
};
|
|
71
71
|
|
|
72
72
|
export type humidifier = {
|
|
@@ -285,9 +285,9 @@ export type ad = {
|
|
|
285
285
|
|
|
286
286
|
export type serviceData = {
|
|
287
287
|
//Model of BLE SwitchBot Device
|
|
288
|
-
model: string
|
|
288
|
+
model: string;
|
|
289
289
|
//Model Name of BLE SwitchBot Device
|
|
290
|
-
modelName: string
|
|
290
|
+
modelName: string;
|
|
291
291
|
//Mode for Bot either Press or Switch
|
|
292
292
|
mode?: boolean;
|
|
293
293
|
//Bot State
|
|
@@ -305,9 +305,9 @@ export type serviceData = {
|
|
|
305
305
|
// Fahrenheit enabled for Meter
|
|
306
306
|
fahrenheit: boolean;
|
|
307
307
|
// Humidity level for Meter
|
|
308
|
-
humidity?: number
|
|
308
|
+
humidity?: number;
|
|
309
309
|
//Motion Detected for Contact or Motion Sensors
|
|
310
|
-
movement?: boolean
|
|
310
|
+
movement?: boolean;
|
|
311
311
|
//Motion ((lightLevel == 1) ? 'dark' : ((lightLevel == 2) ? 'bright' : 'unknown'))
|
|
312
312
|
//Contact ((lightLevel == 0) ? 'dark' : 'bright')
|
|
313
313
|
//Curtain (light sensor level (1-10))
|
|
@@ -327,18 +327,8 @@ export type temperature = {
|
|
|
327
327
|
};
|
|
328
328
|
|
|
329
329
|
export type switchbot = {
|
|
330
|
-
discover: (
|
|
331
|
-
|
|
332
|
-
{
|
|
333
|
-
duration?: any;
|
|
334
|
-
model: string;
|
|
335
|
-
quick: boolean;
|
|
336
|
-
id?: MacAddress;
|
|
337
|
-
}
|
|
338
|
-
) => Promise<any>;
|
|
339
|
-
wait: (
|
|
340
|
-
arg0: number
|
|
341
|
-
) => any;
|
|
330
|
+
discover: (arg0: { duration?: any; model: string; quick: boolean; id?: MacAddress }) => Promise<any>;
|
|
331
|
+
wait: (arg0: number) => any;
|
|
342
332
|
};
|
|
343
333
|
|
|
344
334
|
export function rgb2hs(r, g, b) {
|
|
@@ -894,5 +884,4 @@ export function m2hs(m) {
|
|
|
894
884
|
const input = Math.min(Math.max(Math.round(m), 140), 500);
|
|
895
885
|
const toReturn = table[input];
|
|
896
886
|
return [Math.round(toReturn[1]), Math.round(toReturn[0])];
|
|
897
|
-
|
|
898
|
-
}
|
|
887
|
+
}
|