@switchbot/homebridge-switchbot 2.8.0-beta.0 → 2.8.0-beta.10
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/.prettierrc +1 -1
- package/.vscode/settings.json +1 -1
- package/CHANGELOG.md +10 -0
- package/config.schema.json +8 -0
- package/dist/device/blindtilt.d.ts +1 -0
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +58 -65
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +1 -0
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +52 -55
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +1 -0
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +68 -68
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +1 -0
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +76 -75
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +2 -0
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +67 -59
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +2 -0
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +81 -94
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/hub.d.ts +9 -1
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +197 -30
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +58 -62
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +1 -0
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +28 -26
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +1 -0
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +68 -67
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts +2 -0
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +51 -47
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +5 -3
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +75 -74
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +4 -3
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +74 -74
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +2 -0
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +66 -54
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +1 -0
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +39 -39
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +1 -0
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +74 -53
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +64 -66
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +1 -1
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +32 -34
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +1 -1
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +20 -23
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +2 -2
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +30 -32
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/light.d.ts +1 -1
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +26 -29
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +1 -1
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +22 -23
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +2 -2
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +47 -50
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +20 -23
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +1 -1
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +22 -23
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +46 -44
- 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/dist/utils.js +1 -1
- package/dist/utils.js.map +1 -1
- package/package.json +3 -3
- package/src/device/blindtilt.ts +114 -78
- package/src/device/bot.ts +102 -63
- package/src/device/ceilinglight.ts +113 -73
- package/src/device/colorbulb.ts +144 -87
- package/src/device/contact.ts +98 -63
- package/src/device/curtain.ts +160 -134
- package/src/device/hub.ts +228 -39
- package/src/device/humidifier.ts +136 -85
- package/src/device/iosensor.ts +52 -32
- package/src/device/lightstrip.ts +118 -72
- package/src/device/lock.ts +85 -50
- package/src/device/meter.ts +104 -80
- package/src/device/meterplus.ts +103 -80
- package/src/device/motion.ts +95 -59
- package/src/device/plug.ts +70 -44
- package/src/device/robotvacuumcleaner.ts +107 -56
- package/src/irdevice/airconditioner.ts +116 -86
- package/src/irdevice/airpurifier.ts +60 -39
- package/src/irdevice/camera.ts +40 -28
- package/src/irdevice/fan.ts +52 -38
- package/src/irdevice/light.ts +48 -34
- package/src/irdevice/other.ts +44 -28
- package/src/irdevice/tv.ts +70 -56
- package/src/irdevice/vacuumcleaner.ts +40 -28
- package/src/irdevice/waterheater.ts +48 -32
- package/src/platform.ts +87 -56
- package/src/settings.ts +41 -40
- package/src/utils.ts +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
|
|
1
2
|
import { request } from 'undici';
|
|
2
3
|
import { SwitchBotPlatform } from '../platform';
|
|
3
|
-
import { irDevicesConfig, irdevice
|
|
4
|
-
import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
|
|
4
|
+
import { Devices, irDevicesConfig, irdevice } from '../settings';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Platform Accessory
|
|
@@ -20,13 +20,17 @@ export class WaterHeater {
|
|
|
20
20
|
disablePushOff?: boolean;
|
|
21
21
|
deviceLogging!: string;
|
|
22
22
|
|
|
23
|
-
constructor(
|
|
23
|
+
constructor(
|
|
24
|
+
private readonly platform: SwitchBotPlatform,
|
|
25
|
+
private accessory: PlatformAccessory,
|
|
26
|
+
public device: irdevice & irDevicesConfig,
|
|
27
|
+
) {
|
|
24
28
|
// default placeholders
|
|
25
29
|
this.logs({ device });
|
|
26
|
-
this.config({ device });
|
|
27
30
|
this.context();
|
|
28
31
|
this.disablePushOnChanges({ device });
|
|
29
32
|
this.disablePushOffChanges({ device });
|
|
33
|
+
this.config({ device });
|
|
30
34
|
|
|
31
35
|
// set accessory information
|
|
32
36
|
accessory
|
|
@@ -81,30 +85,34 @@ export class WaterHeater {
|
|
|
81
85
|
* WaterHeater "command" "turnOn" "default" set to ON state
|
|
82
86
|
*/
|
|
83
87
|
async pushWaterHeaterOnChanges(): Promise<void> {
|
|
84
|
-
this.debugLog(
|
|
85
|
-
|
|
88
|
+
this.debugLog(
|
|
89
|
+
`${this.device.remoteType}: ${this.accessory.displayName} pushWaterHeaterOnChanges Active: ${this.Active},` +
|
|
90
|
+
` disablePushOn: ${this.disablePushOn}`,
|
|
91
|
+
);
|
|
86
92
|
if (this.Active === this.platform.Characteristic.Active.ACTIVE && !this.disablePushOn) {
|
|
87
93
|
const commandType: string = await this.commandType();
|
|
88
94
|
const command: string = await this.commandOn();
|
|
89
95
|
const bodyChange = JSON.stringify({
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
96
|
+
command: command,
|
|
97
|
+
parameter: 'default',
|
|
98
|
+
commandType: commandType,
|
|
93
99
|
});
|
|
94
100
|
await this.pushChanges(bodyChange);
|
|
95
101
|
}
|
|
96
102
|
}
|
|
97
103
|
|
|
98
104
|
async pushWaterHeaterOffChanges(): Promise<void> {
|
|
99
|
-
this.debugLog(
|
|
100
|
-
|
|
105
|
+
this.debugLog(
|
|
106
|
+
`${this.device.remoteType}: ${this.accessory.displayName} pushWaterHeaterOffChanges Active: ${this.Active},` +
|
|
107
|
+
` disablePushOff: ${this.disablePushOff}`,
|
|
108
|
+
);
|
|
101
109
|
if (this.Active === this.platform.Characteristic.Active.INACTIVE && !this.disablePushOff) {
|
|
102
110
|
const commandType: string = await this.commandType();
|
|
103
111
|
const command: string = await this.commandOff();
|
|
104
112
|
const bodyChange = JSON.stringify({
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
113
|
+
command: command,
|
|
114
|
+
parameter: 'default',
|
|
115
|
+
commandType: commandType,
|
|
108
116
|
});
|
|
109
117
|
await this.pushChanges(bodyChange);
|
|
110
118
|
}
|
|
@@ -113,7 +121,7 @@ export class WaterHeater {
|
|
|
113
121
|
async pushChanges(bodyChange: any): Promise<void> {
|
|
114
122
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushChanges`);
|
|
115
123
|
if (this.device.connectionType === 'OpenAPI') {
|
|
116
|
-
this.
|
|
124
|
+
this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
|
|
117
125
|
try {
|
|
118
126
|
const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
|
|
119
127
|
body: bodyChange,
|
|
@@ -127,13 +135,16 @@ export class WaterHeater {
|
|
|
127
135
|
this.updateHomeKitCharacteristics();
|
|
128
136
|
} catch (e: any) {
|
|
129
137
|
this.apiError(e);
|
|
130
|
-
this.errorLog(
|
|
131
|
-
|
|
138
|
+
this.errorLog(
|
|
139
|
+
`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}` +
|
|
140
|
+
` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
132
141
|
);
|
|
133
142
|
}
|
|
134
143
|
} else {
|
|
135
|
-
this.warnLog(
|
|
136
|
-
|
|
144
|
+
this.warnLog(
|
|
145
|
+
`${this.device.remoteType}: ${this.accessory.displayName}` +
|
|
146
|
+
` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`,
|
|
147
|
+
);
|
|
137
148
|
}
|
|
138
149
|
}
|
|
139
150
|
|
|
@@ -147,7 +158,7 @@ export class WaterHeater {
|
|
|
147
158
|
}
|
|
148
159
|
}
|
|
149
160
|
|
|
150
|
-
async disablePushOnChanges({ device }: { device: irdevice & irDevicesConfig
|
|
161
|
+
async disablePushOnChanges({ device }: { device: irdevice & irDevicesConfig }): Promise<void> {
|
|
151
162
|
if (device.disablePushOn === undefined) {
|
|
152
163
|
this.disablePushOn = false;
|
|
153
164
|
} else {
|
|
@@ -155,7 +166,7 @@ export class WaterHeater {
|
|
|
155
166
|
}
|
|
156
167
|
}
|
|
157
168
|
|
|
158
|
-
async disablePushOffChanges({ device }: { device: irdevice & irDevicesConfig
|
|
169
|
+
async disablePushOffChanges({ device }: { device: irdevice & irDevicesConfig }): Promise<void> {
|
|
159
170
|
if (device.disablePushOff === undefined) {
|
|
160
171
|
this.disablePushOff = false;
|
|
161
172
|
} else {
|
|
@@ -208,8 +219,10 @@ export class WaterHeater {
|
|
|
208
219
|
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
209
220
|
break;
|
|
210
221
|
case 171:
|
|
211
|
-
this.errorLog(
|
|
212
|
-
|
|
222
|
+
this.errorLog(
|
|
223
|
+
`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
|
|
224
|
+
`Hub: ${this.device.hubDeviceId}`,
|
|
225
|
+
);
|
|
213
226
|
break;
|
|
214
227
|
case 190:
|
|
215
228
|
this.errorLog(
|
|
@@ -224,19 +237,22 @@ export class WaterHeater {
|
|
|
224
237
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
225
238
|
break;
|
|
226
239
|
default:
|
|
227
|
-
this.infoLog(
|
|
228
|
-
|
|
240
|
+
this.infoLog(
|
|
241
|
+
`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode: ` +
|
|
242
|
+
`${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`,
|
|
243
|
+
);
|
|
229
244
|
}
|
|
230
245
|
}
|
|
231
246
|
|
|
232
|
-
async apiError({ e }: { e: any
|
|
247
|
+
async apiError({ e }: { e: any }): Promise<void> {
|
|
233
248
|
this.valveService.updateCharacteristic(this.platform.Characteristic.Active, e);
|
|
234
249
|
}
|
|
235
250
|
|
|
236
|
-
FirmwareRevision({ accessory, device }: { accessory: PlatformAccessory; device: irdevice & irDevicesConfig
|
|
251
|
+
FirmwareRevision({ accessory, device }: { accessory: PlatformAccessory; device: irdevice & irDevicesConfig }): string {
|
|
237
252
|
let FirmwareRevision: string;
|
|
238
|
-
this.debugLog(
|
|
239
|
-
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}
|
|
253
|
+
this.debugLog(
|
|
254
|
+
`${this.device.remoteType}: ${this.accessory.displayName}` + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`,
|
|
255
|
+
);
|
|
240
256
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
241
257
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
242
258
|
if (accessory.context.FirmwareRevision) {
|
|
@@ -257,7 +273,7 @@ export class WaterHeater {
|
|
|
257
273
|
}
|
|
258
274
|
}
|
|
259
275
|
|
|
260
|
-
async config({ device }: { device: irdevice & irDevicesConfig
|
|
276
|
+
async config({ device }: { device: irdevice & irDevicesConfig }): Promise<void> {
|
|
261
277
|
let config = {};
|
|
262
278
|
if (device.irwh) {
|
|
263
279
|
config = device.irwh;
|
|
@@ -287,11 +303,11 @@ export class WaterHeater {
|
|
|
287
303
|
config['disablePushOff'] = device.disablePushOff;
|
|
288
304
|
}
|
|
289
305
|
if (Object.entries(config).length !== 0) {
|
|
290
|
-
this.
|
|
306
|
+
this.debugWarnLog({ log: [`${this.device.remoteType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`] });
|
|
291
307
|
}
|
|
292
308
|
}
|
|
293
309
|
|
|
294
|
-
async logs({ device }: { device: irdevice & irDevicesConfig
|
|
310
|
+
async logs({ device }: { device: irdevice & irDevicesConfig }): Promise<void> {
|
|
295
311
|
if (this.platform.debugMode) {
|
|
296
312
|
this.deviceLogging = this.accessory.context.logging = 'debugMode';
|
|
297
313
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
package/src/platform.ts
CHANGED
|
@@ -32,8 +32,7 @@ import { EveHomeKitTypes } from 'homebridge-lib';
|
|
|
32
32
|
|
|
33
33
|
import { readFileSync, writeFileSync } from 'fs';
|
|
34
34
|
import { API, DynamicPlatformPlugin, Logger, PlatformAccessory, Service, Characteristic } from 'homebridge';
|
|
35
|
-
import {
|
|
36
|
-
PLATFORM_NAME, PLUGIN_NAME, irdevice, device, SwitchBotPlatformConfig, devicesConfig, irDevicesConfig, Devices } from './settings';
|
|
35
|
+
import { PLATFORM_NAME, PLUGIN_NAME, irdevice, device, SwitchBotPlatformConfig, devicesConfig, irDevicesConfig, Devices } from './settings';
|
|
37
36
|
|
|
38
37
|
/**
|
|
39
38
|
* HomebridgePlatform
|
|
@@ -54,7 +53,11 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
54
53
|
public readonly fakegatoAPI: any;
|
|
55
54
|
public readonly eve: any;
|
|
56
55
|
|
|
57
|
-
constructor(
|
|
56
|
+
constructor(
|
|
57
|
+
public readonly log: Logger,
|
|
58
|
+
public readonly config: SwitchBotPlatformConfig,
|
|
59
|
+
public readonly api: API,
|
|
60
|
+
) {
|
|
58
61
|
this.logs();
|
|
59
62
|
this.debugLog('Finished initializing platform:', this.config.name);
|
|
60
63
|
// only load if configured
|
|
@@ -64,8 +67,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
64
67
|
|
|
65
68
|
// HOOBS notice
|
|
66
69
|
if (__dirname.includes('hoobs')) {
|
|
67
|
-
this.warnLog(
|
|
68
|
-
|
|
70
|
+
this.warnLog(
|
|
71
|
+
'This plugin has not been tested under HOOBS, it is highly recommended that you switch to Homebridge: ' +
|
|
72
|
+
'https://tinyurl.com/HOOBS2Homebridge',
|
|
73
|
+
);
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
// verify the config
|
|
@@ -94,7 +99,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
94
99
|
await this.updateToken();
|
|
95
100
|
} else if (this.config.credentials?.token && !this.config.credentials?.secret) {
|
|
96
101
|
// eslint-disable-next-line no-useless-escape
|
|
97
|
-
this.errorLog('
|
|
102
|
+
this.errorLog('"secret" config is not populated, you must populate then please restart Homebridge.');
|
|
98
103
|
} else {
|
|
99
104
|
this.discoverDevices();
|
|
100
105
|
}
|
|
@@ -133,7 +138,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
133
138
|
platformConfig['pushRate'] = this.config.options.pushRate;
|
|
134
139
|
}
|
|
135
140
|
if (Object.entries(platformConfig).length !== 0) {
|
|
136
|
-
this.
|
|
141
|
+
this.debugWarnLog(`Platform Config: ${JSON.stringify(platformConfig)}`);
|
|
137
142
|
}
|
|
138
143
|
|
|
139
144
|
if (this.config.options) {
|
|
@@ -177,9 +182,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
177
182
|
}
|
|
178
183
|
|
|
179
184
|
if (!this.config.options.pushRate) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
185
|
+
// default 100 milliseconds
|
|
186
|
+
this.config.options!.pushRate! = 0.1;
|
|
187
|
+
this.debugWarnLog('Using Default Push Rate.');
|
|
183
188
|
}
|
|
184
189
|
|
|
185
190
|
if (!this.config.credentials && !this.config.options) {
|
|
@@ -230,14 +235,19 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
230
235
|
throw new Error('pluginConfig.credentials is not an object');
|
|
231
236
|
}
|
|
232
237
|
// Move openToken to token
|
|
233
|
-
if (!this.config.credentials.secret){
|
|
238
|
+
if (!this.config.credentials.secret) {
|
|
234
239
|
// eslint-disable-next-line no-useless-escape, max-len
|
|
235
|
-
this.warnLog(
|
|
240
|
+
this.warnLog(
|
|
241
|
+
'This plugin has been updated to use OpenAPI v1.1, config is set with openToken, "openToken" cconfig has been moved to the "token" config',
|
|
242
|
+
);
|
|
236
243
|
// eslint-disable-next-line no-useless-escape
|
|
237
|
-
this.errorLog('
|
|
244
|
+
this.errorLog('"secret" config is not populated, you must populate then please restart Homebridge.');
|
|
238
245
|
} else {
|
|
239
246
|
// eslint-disable-next-line no-useless-escape, max-len
|
|
240
|
-
this.warnLog(
|
|
247
|
+
this.warnLog(
|
|
248
|
+
'This plugin has been updated to use OpenAPI v1.1, config is set with openToken, '
|
|
249
|
+
+ '"openToken" config has been moved to the "token" config, please restart Homebridge.',
|
|
250
|
+
);
|
|
241
251
|
}
|
|
242
252
|
|
|
243
253
|
// set the refresh token
|
|
@@ -260,14 +270,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
260
270
|
const t = `${Date.now()}`;
|
|
261
271
|
const nonce = randomUUID();
|
|
262
272
|
const data = this.config.credentials?.token + t + nonce;
|
|
263
|
-
const signTerm = crypto
|
|
273
|
+
const signTerm = crypto
|
|
274
|
+
.createHmac('sha256', this.config.credentials?.secret)
|
|
275
|
+
.update(Buffer.from(data, 'utf-8'))
|
|
276
|
+
.digest();
|
|
264
277
|
const sign = signTerm.toString('base64');
|
|
265
278
|
|
|
266
279
|
return {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
280
|
+
Authorization: this.config.credentials?.token,
|
|
281
|
+
sign: sign,
|
|
282
|
+
nonce: nonce,
|
|
283
|
+
t: t,
|
|
271
284
|
'Content-Type': 'application/json',
|
|
272
285
|
};
|
|
273
286
|
};
|
|
@@ -374,10 +387,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
374
387
|
} else {
|
|
375
388
|
this.debugLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
|
|
376
389
|
}
|
|
377
|
-
|
|
378
390
|
} catch (e: any) {
|
|
379
|
-
this.debugErrorLog(
|
|
380
|
-
|
|
391
|
+
this.debugErrorLog(
|
|
392
|
+
`Failed to Discover Devices, Error Message: ${JSON.stringify(e.message)}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug',
|
|
393
|
+
);
|
|
381
394
|
this.debugErrorLog(`Failed to Discover Devices, Error: ${e}`);
|
|
382
395
|
}
|
|
383
396
|
} else if (!this.config.credentials?.token && this.config.options?.devices) {
|
|
@@ -624,7 +637,6 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
624
637
|
if (existingAccessory) {
|
|
625
638
|
// the accessory already exists
|
|
626
639
|
if (await this.registerDevice(device)) {
|
|
627
|
-
|
|
628
640
|
// if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
|
|
629
641
|
existingAccessory.context.model = device.deviceType;
|
|
630
642
|
existingAccessory.context.deviceID = device.deviceId;
|
|
@@ -1043,8 +1055,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
1043
1055
|
}
|
|
1044
1056
|
|
|
1045
1057
|
if (device.group && !device.curtain?.disable_group) {
|
|
1046
|
-
this.debugLog(
|
|
1047
|
-
|
|
1058
|
+
this.debugLog(
|
|
1059
|
+
'Your Curtains are grouped, ' +
|
|
1060
|
+
`, Secondary curtain automatically hidden. Main Curtain: ${device.deviceName}, DeviceID: ${device.deviceId}`,
|
|
1061
|
+
);
|
|
1048
1062
|
} else {
|
|
1049
1063
|
if (device.master) {
|
|
1050
1064
|
this.warnLog(`Main Curtain: ${device.deviceName}, DeviceID: ${device.deviceId}`);
|
|
@@ -1110,8 +1124,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
1110
1124
|
}
|
|
1111
1125
|
|
|
1112
1126
|
if (device.group && !device.curtain?.disable_group) {
|
|
1113
|
-
this.debugLog(
|
|
1114
|
-
|
|
1127
|
+
this.debugLog(
|
|
1128
|
+
'Your Curtains are grouped, ' +
|
|
1129
|
+
`, Secondary curtain automatically hidden. Main Curtain: ${device.deviceName}, DeviceID: ${device.deviceId}`,
|
|
1130
|
+
);
|
|
1115
1131
|
} else {
|
|
1116
1132
|
if (device.master) {
|
|
1117
1133
|
this.warnLog(`Main Curtain: ${device.deviceName}, DeviceID: ${device.deviceId}`);
|
|
@@ -1983,42 +1999,56 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
1983
1999
|
|
|
1984
2000
|
async registerCurtains(device: device & devicesConfig) {
|
|
1985
2001
|
if (device.deviceType === 'Curtain') {
|
|
1986
|
-
this.debugWarnLog(
|
|
1987
|
-
|
|
2002
|
+
this.debugWarnLog(
|
|
2003
|
+
`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, curtainDevicesIds: ${device.curtainDevicesIds}, master: ` +
|
|
2004
|
+
`${device.master}, group: ${device.group}, disable_group: ${device.curtain?.disable_group}, connectionType: ${device.connectionType}`,
|
|
2005
|
+
);
|
|
1988
2006
|
} else {
|
|
1989
|
-
this.debugWarnLog(
|
|
1990
|
-
|
|
2007
|
+
this.debugWarnLog(
|
|
2008
|
+
`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, blindTiltDevicesIds: ${device.blindTiltDevicesIds}, master: ` +
|
|
2009
|
+
`${device.master}, group: ${device.group}, disable_group: ${device.curtain?.disable_group}, connectionType: ${device.connectionType}`,
|
|
2010
|
+
);
|
|
1991
2011
|
}
|
|
1992
2012
|
|
|
1993
2013
|
let registerCurtain: boolean;
|
|
1994
2014
|
if (device.master && device.group) {
|
|
1995
2015
|
// OpenAPI: Master Curtains/Blind Tilt in Group
|
|
1996
2016
|
registerCurtain = true;
|
|
1997
|
-
this.debugLog(
|
|
1998
|
-
|
|
2017
|
+
this.debugLog(
|
|
2018
|
+
`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, device.group: ${device.group}` +
|
|
2019
|
+
` connectionType; ${device.connectionType}`,
|
|
2020
|
+
);
|
|
1999
2021
|
this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
|
|
2000
|
-
} else if (!device.master && device.curtain?.disable_group) {
|
|
2022
|
+
} else if (!device.master && device.curtain?.disable_group) {
|
|
2023
|
+
//!device.group && device.connectionType === 'BLE'
|
|
2001
2024
|
// OpenAPI: Non-Master Curtains/Blind Tilts that has Disable Grouping Checked
|
|
2002
2025
|
registerCurtain = true;
|
|
2003
|
-
this.debugLog(
|
|
2004
|
-
|
|
2026
|
+
this.debugLog(
|
|
2027
|
+
`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, disable_group: ` +
|
|
2028
|
+
`${device.curtain?.disable_group}, connectionType; ${device.connectionType}`,
|
|
2029
|
+
);
|
|
2005
2030
|
this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
|
|
2006
2031
|
} else if (device.master && !device.group) {
|
|
2007
2032
|
// OpenAPI: Master Curtains/Blind Tilts not in Group
|
|
2008
2033
|
registerCurtain = true;
|
|
2009
|
-
this.debugLog(
|
|
2010
|
-
|
|
2034
|
+
this.debugLog(
|
|
2035
|
+
`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, device.group: ${device.group}` +
|
|
2036
|
+
` connectionType; ${device.connectionType}`,
|
|
2037
|
+
);
|
|
2011
2038
|
this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
|
|
2012
2039
|
} else if (device.connectionType === 'BLE') {
|
|
2013
2040
|
// BLE: Curtains/Blind Tilt
|
|
2014
2041
|
registerCurtain = true;
|
|
2015
|
-
this.debugLog(
|
|
2016
|
-
|
|
2042
|
+
this.debugLog(
|
|
2043
|
+
`deviceName: ${device.deviceName} [${device.deviceType} Config] connectionType: ${device.connectionType}, ` + ` group: ${device.group}`,
|
|
2044
|
+
);
|
|
2017
2045
|
this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
|
|
2018
2046
|
} else {
|
|
2019
2047
|
registerCurtain = false;
|
|
2020
|
-
this.debugErrorLog(
|
|
2021
|
-
|
|
2048
|
+
this.debugErrorLog(
|
|
2049
|
+
`deviceName: ${device.deviceName} [${device.deviceType} Config] disable_group: ${device.curtain?.disable_group},` +
|
|
2050
|
+
` device.master: ${device.master}, device.group: ${device.group}`,
|
|
2051
|
+
);
|
|
2022
2052
|
this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}, device.connectionType: ${device.connectionType}`);
|
|
2023
2053
|
}
|
|
2024
2054
|
return registerCurtain;
|
|
@@ -2046,8 +2076,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
2046
2076
|
this.debugWarnLog(`Device: ${device.deviceName} registerDevice: ${registerDevice}`);
|
|
2047
2077
|
}
|
|
2048
2078
|
this.debugWarnLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will display in HomeKit`);
|
|
2049
|
-
} else if (!device.hide_device && device.deviceId && device.configDeviceType && device.configDeviceName
|
|
2050
|
-
&& device.connectionType === 'BLE') {
|
|
2079
|
+
} else if (!device.hide_device && device.deviceId && device.configDeviceType && device.configDeviceName && device.connectionType === 'BLE') {
|
|
2051
2080
|
if (device.deviceType === 'Curtain' || device.deviceType === 'Blind Tilt') {
|
|
2052
2081
|
registerDevice = await this.registerCurtains(device);
|
|
2053
2082
|
this.debugWarnLog(`Device: ${device.deviceName} ${device.deviceType} registerDevice: ${registerDevice}`);
|
|
@@ -2077,23 +2106,25 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
2077
2106
|
} else if (!device.connectionType && !device.hide_device) {
|
|
2078
2107
|
registerDevice = false;
|
|
2079
2108
|
this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will not display in HomeKit`);
|
|
2080
|
-
} else if (device.hide_device){
|
|
2109
|
+
} else if (device.hide_device) {
|
|
2081
2110
|
registerDevice = false;
|
|
2082
2111
|
this.debugErrorLog(`Device: ${device.deviceName} hide_device: ${device.hide_device}, will not display in HomeKit`);
|
|
2083
2112
|
} else {
|
|
2084
2113
|
registerDevice = false;
|
|
2085
|
-
this.debugErrorLog(
|
|
2086
|
-
|
|
2114
|
+
this.debugErrorLog(
|
|
2115
|
+
`Device: ${device.deviceName} connectionType: ${device.connectionType}, hide_device: ` +
|
|
2116
|
+
`${device.hide_device}, will not display in HomeKit`,
|
|
2117
|
+
);
|
|
2087
2118
|
}
|
|
2088
2119
|
return registerDevice;
|
|
2089
2120
|
}
|
|
2090
2121
|
|
|
2091
2122
|
public async externalOrPlatformIR(device: device & irDevicesConfig, accessory: PlatformAccessory) {
|
|
2092
2123
|
/**
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2124
|
+
* Publish as external accessory
|
|
2125
|
+
* Only one TV can exist per bridge, to bypass this limitation, you should
|
|
2126
|
+
* publish your TV as an external accessory.
|
|
2127
|
+
*/
|
|
2097
2128
|
if (device.external) {
|
|
2098
2129
|
this.debugWarnLog(`${accessory.displayName} External Accessory Mode`);
|
|
2099
2130
|
this.externalAccessory(accessory);
|
|
@@ -2126,8 +2157,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
2126
2157
|
async statusCode(statusCode: number): Promise<void> {
|
|
2127
2158
|
switch (statusCode) {
|
|
2128
2159
|
case 151:
|
|
2129
|
-
this.errorLog(
|
|
2130
|
-
|
|
2160
|
+
this.errorLog(
|
|
2161
|
+
`Command not supported by this device type, statusCode: ${statusCode}, Submit Feature Request Here: ` +
|
|
2162
|
+
'https://tinyurl.com/SwitchBotFeatureRequest',
|
|
2163
|
+
);
|
|
2131
2164
|
break;
|
|
2132
2165
|
case 152:
|
|
2133
2166
|
this.errorLog(`Device not found, statusCode: ${statusCode}`);
|
|
@@ -2161,9 +2194,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
2161
2194
|
let switchbot: any;
|
|
2162
2195
|
try {
|
|
2163
2196
|
Switchbot = require('node-switchbot');
|
|
2164
|
-
queueScheduler.schedule(() =>
|
|
2165
|
-
switchbot = new Switchbot(),
|
|
2166
|
-
);
|
|
2197
|
+
queueScheduler.schedule(() => (switchbot = new Switchbot()));
|
|
2167
2198
|
} catch (e: any) {
|
|
2168
2199
|
switchbot = false;
|
|
2169
2200
|
this.errorLog(`Was 'node-switchbot' found: ${switchbot}`);
|
package/src/settings.ts
CHANGED
|
@@ -151,6 +151,7 @@ export type lock = {
|
|
|
151
151
|
export type hub = {
|
|
152
152
|
hide_temperature?: boolean;
|
|
153
153
|
hide_humidity?: boolean;
|
|
154
|
+
hide_lightsensor?: boolean;
|
|
154
155
|
};
|
|
155
156
|
|
|
156
157
|
export interface irDevicesConfig extends irdevice {
|
|
@@ -201,7 +202,7 @@ export type body = {
|
|
|
201
202
|
command: string;
|
|
202
203
|
parameter: string;
|
|
203
204
|
commandType: string;
|
|
204
|
-
}
|
|
205
|
+
};
|
|
205
206
|
|
|
206
207
|
//a list of physical devices.
|
|
207
208
|
export type deviceList = {
|
|
@@ -254,45 +255,45 @@ export type irdevice = {
|
|
|
254
255
|
};
|
|
255
256
|
|
|
256
257
|
export type deviceStatus = {
|
|
257
|
-
//v1.1 of API
|
|
258
|
-
deviceId:
|
|
259
|
-
deviceType:
|
|
260
|
-
hubDeviceId:
|
|
261
|
-
power?: string;
|
|
262
|
-
calibrate?:
|
|
263
|
-
group?:
|
|
264
|
-
moving?:
|
|
265
|
-
slidePosition?:
|
|
266
|
-
temperature?:
|
|
267
|
-
humidity?:
|
|
268
|
-
lockState?:
|
|
269
|
-
doorState?:
|
|
270
|
-
moveDetected?:
|
|
271
|
-
brightness?:
|
|
272
|
-
openState?:
|
|
273
|
-
colorTemperature?:
|
|
274
|
-
voltage?:
|
|
275
|
-
weight?:
|
|
276
|
-
electricityOfDay?:
|
|
277
|
-
electricCurrent?:
|
|
278
|
-
color?:
|
|
279
|
-
workingStatus?:
|
|
280
|
-
onlineStatus?:
|
|
281
|
-
battery?:
|
|
282
|
-
deviceName?:
|
|
283
|
-
nebulizationEfficiency?:
|
|
284
|
-
auto?:
|
|
285
|
-
childLock?:
|
|
286
|
-
sound?:
|
|
287
|
-
lackWater?:
|
|
288
|
-
version?:
|
|
289
|
-
direction?:
|
|
290
|
-
runStatus?: string
|
|
291
|
-
mode?: number; //available for devices. the fan mode. (Used by the following deviceTypes: Smart Fan)
|
|
292
|
-
speed?: number
|
|
293
|
-
shaking?: boolean
|
|
294
|
-
shakeCenter?: string
|
|
295
|
-
shakeRange?: string
|
|
258
|
+
//v1.1 of API
|
|
259
|
+
deviceId: string; //device ID. (Used by the following deviceTypes: Bot, Curtain, Meter, Meter Plus, Lock, Keypad, Keypad Touch, Motion Sensor, Contact Sensor, Ceiling Light, Ceiling Light Pro, Plug Mini (US), Plug Mini (JP), Strip Light, Color Bulb, Robot Vacuum Cleaner S1, Robot Vacuum Cleaner S1 Plus, Humidifier, Blind Tilt)
|
|
260
|
+
deviceType: string; //device type. (Used by the following deviceTypes: Bot, Curtain, Meter, Meter Plus, Lock, Keypad, Keypad Touch, Motion Sensor, Contact Sensor, Ceiling Light, Ceiling Light Pro, Plug Mini (US), Plug Mini (JP), Strip Light, Color Bulb, Robot Vacuum Cleaner S1, Robot Vacuum Cleaner S1 Plus, Humidifier, Blind Tilt)
|
|
261
|
+
hubDeviceId: string; //device's parent Hub ID. 000000000000 when the device itself is a Hub or it is connected through Wi-Fi. (Used by the following deviceTypes: Bot, Curtain, Meter, Meter Plus, Lock, Keypad, Keypad Touch, Motion Sensor, Contact Sensor, Ceiling Light, Ceiling Light Pro, Plug Mini (JP), Strip Light, Color Bulb, Robot Vacuum Cleaner S1, Robot Vacuum Cleaner S1 Plus, Humidifier, Blind Tilt)
|
|
262
|
+
power?: string; //ON/OFF state. (Used by the following deviceTypes: Bot, Ceiling Light, Ceiling Light Pro, PLug, Plug Mini (US), Plug Mini (JP), Strip Light, Color Bulb, Humidifier)
|
|
263
|
+
calibrate?: boolean; //determines if device has been calibrated or not. (Used by the following deviceTypes: Curtain, Lock, Blind Tilt)
|
|
264
|
+
group?: boolean; //determines if a device is paired with or grouped with another device or not. (Used by the following deviceTypes: Curtain, Blind Tilt)
|
|
265
|
+
moving?: boolean; //determines if a device is moving or not. (Used by the following deviceTypes: Curtain, Blind Tilt)
|
|
266
|
+
slidePosition?: number; //the current position (0-100) the percentage of the distance between the calibrated open position and closed position. (Used by the following deviceTypes: Curtain, Blind Tilt)
|
|
267
|
+
temperature?: number; //temperature in celsius (Used by the following deviceTypes: Meter, Meter Plus, Humidifier, IOSensor)
|
|
268
|
+
humidity?: number; //humidity percentage. (Used by the following deviceTypes: Meter, Meter Plus, Humidifier, IOSensor)
|
|
269
|
+
lockState?: string; //determines if locked or not. (Used by the following deviceTypes: Lock)
|
|
270
|
+
doorState?: string; //determines if the door is closed or not. (Used by the following deviceTypes: Lock)
|
|
271
|
+
moveDetected?: boolean; //determines if motion is detected. (Used by the following deviceTypes: Motion Sensor, Contact Sensor)
|
|
272
|
+
brightness?: string | number; //the ambient brightness picked up by the sensor. bright or dim. (Used by the following deviceTypes: Motion Sensor, Contact Sensor) | the brightness value, range from 1 to 100. (Used by the following deviceTypes: Ceiling Light, Ceiling Light Pro, Strip Light, Color Bulb)
|
|
273
|
+
openState?: string; //the open state of the sensor. open, close, or timeOutNotClose. (Used by the following deviceTypes: Contact Sensor)
|
|
274
|
+
colorTemperature?: number; //the color temperature value, range from 2700 to 6500. (Used by the following deviceTypes: Ceiling Light, Ceiling Light Pro, Color Bulb)
|
|
275
|
+
voltage?: number; //the voltage of the device, measured in Volt. (Used by the following deviceTypes: Plug Mini (US), Plug Mini (JP))
|
|
276
|
+
weight?: number; //the power consumed in a day, measured in Watts. (Used by the following deviceTypes: Plug Mini (US), Plug Mini (JP))
|
|
277
|
+
electricityOfDay?: number; //the duration that the device has been used during a day, measured in minutes. (Used by the following deviceTypes: Plug Mini (US), Plug Mini (JP))
|
|
278
|
+
electricCurrent?: number; //the current of the device at the moment, measured in Amp. (Used by the following deviceTypes: Plug Mini (US), Plug Mini (JP))
|
|
279
|
+
color?: string; //the color value, RGB "255:255:255". (Used by the following deviceTypes: Strip Light, Color Bulb)
|
|
280
|
+
workingStatus?: string; //the working status of the device. StandBy, Clearing, Paused, GotoChargeBase, Charging, ChargeDone, Dormant, InTrouble, InRemoteControl, or InDustCollecting. (Used by the following deviceTypes: Robot Vacuum Cleaner S1, Robot Vacuum Cleaner S1 Plus)
|
|
281
|
+
onlineStatus?: string; //the connection status of the device. online or offline. (Used by the following deviceTypes: Robot Vacuum Cleaner S1, Robot Vacuum Cleaner S1 Plus)
|
|
282
|
+
battery?: number; //the current battery level. (Used by the following deviceTypes: Robot Vacuum Cleaner S1, Robot Vacuum Cleaner S1 Plus, Blind Tilt, IOSensor)
|
|
283
|
+
deviceName?: string; //device name. (Used by the following deviceTypes: Robot Vacuum Cleaner S1 Plus)
|
|
284
|
+
nebulizationEfficiency?: number; //atomization efficiency percentage. (Used by the following deviceTypes: Humidifier)
|
|
285
|
+
auto?: boolean; //determines if a Humidifier is in Auto Mode or not. (Used by the following deviceTypes: Humidifier)
|
|
286
|
+
childLock?: boolean; //determines if a Humidifier's safety lock is on or not. (Used by the following deviceTypes: Humidifier)
|
|
287
|
+
sound?: boolean; //determines if a Humidifier is muted or not. (Used by the following deviceTypes: Humidifier)
|
|
288
|
+
lackWater?: boolean; //determines if the water tank is empty or not. (Used by the following deviceTypes: Humidifier)
|
|
289
|
+
version?: number; //the version of the device. (Used by the following deviceTypes: Blind Tilt, Meter, MeterPlus, IOSensor)
|
|
290
|
+
direction?: string; //the opening direction of a Blind Tilt device. (Used by the following deviceTypes: Blind Tilt)
|
|
291
|
+
runStatus?: string; //'static' when not moving. (Used by the following deviceTypes: Blind Tilt)
|
|
292
|
+
mode?: number; //available for devices. the fan mode. (Used by the following deviceTypes: Smart Fan)
|
|
293
|
+
speed?: number; //the fan speed. (Used by the following deviceTypes: Smart Fan)
|
|
294
|
+
shaking?: boolean; //determines if the fan is swinging or not. (Used by the following deviceTypes: Smart Fan)
|
|
295
|
+
shakeCenter?: string; //the fan's swing direciton. (Used by the following deviceTypes: Smart Fan)
|
|
296
|
+
shakeRange?: string; //the fan's swing range, 0~120°. (Used by the following deviceTypes: Smart Fan)
|
|
296
297
|
};
|
|
297
298
|
|
|
298
299
|
export type ad = {
|
package/src/utils.ts
CHANGED