@switchbot/homebridge-switchbot 1.8.2-beta.2 → 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/extensions.json +5 -0
- package/.vscode/settings.json +27 -0
- package/CHANGELOG.md +15 -0
- package/README.md +100 -99
- package/SECURITY.md +2 -2
- package/config.schema.json +9 -0
- package/dist/devices/bots.d.ts +4 -2
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +101 -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 +19 -20
- 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/homebridge-ui/public/index.html +231 -245
- package/homebridge-ui/server.js +2 -4
- package/nodemon.json +2 -4
- package/package.json +12 -8
- package/src/devices/bots.ts +228 -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 +38 -40
- package/src/settings.ts +8 -18
- 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
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import { Bot } from './devices/bots';
|
|
3
2
|
import { Plug } from './devices/plugs';
|
|
4
3
|
import { Meter } from './devices/meters';
|
|
@@ -52,8 +51,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
52
51
|
|
|
53
52
|
// HOOBS notice
|
|
54
53
|
if (__dirname.includes('hoobs')) {
|
|
55
|
-
this.log.warn('This plugin has not been tested under HOOBS, it is highly recommended that '
|
|
56
|
-
'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');
|
|
57
55
|
}
|
|
58
56
|
|
|
59
57
|
// verify the config
|
|
@@ -131,14 +129,14 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
131
129
|
this.config.options = this.config.options || {};
|
|
132
130
|
|
|
133
131
|
const platformConfig = {};
|
|
134
|
-
if (this.config.options
|
|
135
|
-
platformConfig['logging'] = this.config.options
|
|
132
|
+
if (this.config.options.logging) {
|
|
133
|
+
platformConfig['logging'] = this.config.options.logging;
|
|
136
134
|
}
|
|
137
|
-
if (this.config.options
|
|
138
|
-
platformConfig['refreshRate'] = this.config.options
|
|
135
|
+
if (this.config.options.logging) {
|
|
136
|
+
platformConfig['refreshRate'] = this.config.options.refreshRate;
|
|
139
137
|
}
|
|
140
|
-
if (this.config.options
|
|
141
|
-
platformConfig['pushRate'] = this.config.options
|
|
138
|
+
if (this.config.options.logging) {
|
|
139
|
+
platformConfig['pushRate'] = this.config.options.pushRate;
|
|
142
140
|
}
|
|
143
141
|
if (Object.entries(platformConfig).length !== 0) {
|
|
144
142
|
this.warnLog(`Platform Config: ${JSON.stringify(platformConfig)}`);
|
|
@@ -208,8 +206,8 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
208
206
|
}
|
|
209
207
|
|
|
210
208
|
/**
|
|
211
|
-
|
|
212
|
-
|
|
209
|
+
* this method discovers devices
|
|
210
|
+
*/
|
|
213
211
|
async discoverDevices() {
|
|
214
212
|
try {
|
|
215
213
|
if (this.config.credentials?.openToken) {
|
|
@@ -235,10 +233,12 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
235
233
|
this.debugLog(`SwitchBot Device Config Set: ${JSON.stringify(this.config.options?.devices)}`);
|
|
236
234
|
const deviceConfigs = this.config.options?.devices;
|
|
237
235
|
|
|
238
|
-
const mergeBydeviceId = (a1: { deviceId: string
|
|
239
|
-
a1.map((itm: { deviceId: string
|
|
240
|
-
...a2.find(
|
|
241
|
-
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
|
+
),
|
|
242
242
|
...itm,
|
|
243
243
|
}));
|
|
244
244
|
|
|
@@ -270,10 +270,12 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
270
270
|
this.debugLog(`IR Device Config Set: ${JSON.stringify(this.config.options?.irdevices)}`);
|
|
271
271
|
const irDeviceConfig = this.config.options?.irdevices;
|
|
272
272
|
|
|
273
|
-
const mergeIRBydeviceId = (a1: { deviceId: string
|
|
274
|
-
a1.map((itm: { deviceId: string
|
|
275
|
-
...a2.find(
|
|
276
|
-
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
|
+
),
|
|
277
279
|
...itm,
|
|
278
280
|
}));
|
|
279
281
|
|
|
@@ -325,8 +327,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
325
327
|
this.debugLog('The client has defined a contentType header that is not supported by the server.');
|
|
326
328
|
} else if (e.message.includes('422')) {
|
|
327
329
|
this.errorLog('Failed to Discover Devices: Unprocessable Entity');
|
|
328
|
-
this.debugLog(
|
|
329
|
-
|
|
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
|
+
);
|
|
330
334
|
} else if (e.message.includes('429')) {
|
|
331
335
|
this.errorLog('Failed to Discover Devices: Too Many Requests');
|
|
332
336
|
this.debugLog('The client has exceeded the number of requests allowed for a given time window.');
|
|
@@ -827,8 +831,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
827
831
|
}
|
|
828
832
|
|
|
829
833
|
private isCurtainGrouped(device: device & devicesConfig) {
|
|
830
|
-
this.debugLog(
|
|
831
|
-
|
|
834
|
+
this.debugLog(
|
|
835
|
+
`deviceId: ${device.deviceId}, curtainDevicesIds: ${device.curtainDevicesIds},` +
|
|
836
|
+
` master: ${device.master}, group: ${device.group}, disable_group: ${device.curtain?.disable_group}`,
|
|
837
|
+
);
|
|
832
838
|
|
|
833
839
|
if (device.group && !device.curtain?.disable_group) {
|
|
834
840
|
this.debugLog(`[Curtain Config] disable_group: ${device.curtain?.disable_group}`);
|
|
@@ -992,10 +998,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
992
998
|
this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
|
|
993
999
|
|
|
994
1000
|
/**
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
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
|
+
*/
|
|
999
1005
|
this.api.publishExternalAccessories(PLUGIN_NAME, [accessory]);
|
|
1000
1006
|
this.accessories.push(accessory);
|
|
1001
1007
|
} else {
|
|
@@ -1444,9 +1450,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
1444
1450
|
}
|
|
1445
1451
|
}
|
|
1446
1452
|
|
|
1447
|
-
public async connectionTypeNewAccessory(
|
|
1448
|
-
device: device & devicesConfig,
|
|
1449
|
-
accessory: PlatformAccessory) {
|
|
1453
|
+
public async connectionTypeNewAccessory(device: device & devicesConfig, accessory: PlatformAccessory) {
|
|
1450
1454
|
if (device.ble) {
|
|
1451
1455
|
accessory.context.connectionType = 'BLE';
|
|
1452
1456
|
} else {
|
|
@@ -1454,10 +1458,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
1454
1458
|
}
|
|
1455
1459
|
}
|
|
1456
1460
|
|
|
1457
|
-
public async connectionTypeExistingAccessory(
|
|
1458
|
-
device: device & devicesConfig,
|
|
1459
|
-
existingAccessory: PlatformAccessory,
|
|
1460
|
-
) {
|
|
1461
|
+
public async connectionTypeExistingAccessory(device: device & devicesConfig, existingAccessory: PlatformAccessory) {
|
|
1461
1462
|
if (device.ble) {
|
|
1462
1463
|
existingAccessory.context.connectionType = 'BLE';
|
|
1463
1464
|
} else {
|
|
@@ -1465,14 +1466,11 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
1465
1466
|
}
|
|
1466
1467
|
}
|
|
1467
1468
|
|
|
1468
|
-
public async connectionTypeNewIRAccessory(
|
|
1469
|
-
accessory: PlatformAccessory) {
|
|
1469
|
+
public async connectionTypeNewIRAccessory(accessory: PlatformAccessory) {
|
|
1470
1470
|
accessory.context.connectionType = 'IR wirth OpenAPI';
|
|
1471
1471
|
}
|
|
1472
1472
|
|
|
1473
|
-
public async connectionTypeExistingIRAccessory(
|
|
1474
|
-
existingAccessory: PlatformAccessory,
|
|
1475
|
-
) {
|
|
1473
|
+
public async connectionTypeExistingIRAccessory(existingAccessory: PlatformAccessory) {
|
|
1476
1474
|
existingAccessory.context.connectionType = 'IR with OpenAPI';
|
|
1477
1475
|
}
|
|
1478
1476
|
|
|
@@ -1488,7 +1486,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
1488
1486
|
}
|
|
1489
1487
|
}
|
|
1490
1488
|
|
|
1491
|
-
public async deviceInfo(device: irdevice & devicesConfig | device & devicesConfig) {
|
|
1489
|
+
public async deviceInfo(device: (irdevice & devicesConfig) | (device & devicesConfig)) {
|
|
1492
1490
|
if (this.platformLogging === 'debug') {
|
|
1493
1491
|
this.warnLog(JSON.stringify(device));
|
|
1494
1492
|
this.deviceStatus = (await this.axios.get(`${DeviceURL}/${device.deviceId}/status`)).data;
|