@switchbot/homebridge-switchbot 2.6.0-beta.4 → 2.6.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/.vscode/tasks.json +13 -0
- package/CHANGELOG.md +4 -2
- package/README.md +18 -9
- package/dist/device/blindtilt.d.ts +1 -5
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +80 -140
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +1 -5
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +79 -138
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +2 -6
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +157 -304
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +2 -6
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +164 -311
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +1 -5
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +36 -72
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +1 -5
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +78 -138
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/hub.d.ts +2 -6
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +30 -63
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +1 -5
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +115 -228
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +1 -5
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +38 -74
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/{striplight.d.ts → lightstrip.d.ts} +2 -10
- package/dist/device/lightstrip.d.ts.map +1 -0
- package/dist/device/{striplight.js → lightstrip.js} +138 -194
- package/dist/device/lightstrip.js.map +1 -0
- package/dist/device/lock.d.ts +1 -5
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +66 -126
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +1 -5
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +38 -74
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +1 -5
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +39 -75
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +1 -5
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +35 -72
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +1 -5
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +65 -126
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +1 -5
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +79 -151
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +3 -7
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +34 -62
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +3 -7
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +31 -59
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +1 -5
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +30 -57
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +2 -6
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +39 -66
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/light.d.ts +1 -5
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +32 -59
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +1 -5
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +30 -57
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +3 -7
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +46 -76
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +2 -6
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +30 -58
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +7 -23
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +41 -74
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +14 -5
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +156 -149
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +4 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +5 -1
- package/dist/settings.js.map +1 -1
- package/nodemon.json +1 -1
- package/package.json +10 -10
- package/src/device/blindtilt.ts +122 -181
- package/src/device/bot.ts +96 -149
- package/src/device/ceilinglight.ts +172 -315
- package/src/device/colorbulb.ts +178 -324
- package/src/device/contact.ts +48 -78
- package/src/device/curtain.ts +93 -148
- package/src/device/hub.ts +34 -63
- package/src/device/humidifier.ts +135 -243
- package/src/device/iosensor.ts +49 -79
- package/src/device/{striplight.ts → lightstrip.ts} +148 -200
- package/src/device/lock.ts +78 -134
- package/src/device/meter.ts +48 -78
- package/src/device/meterplus.ts +50 -80
- package/src/device/motion.ts +46 -77
- package/src/device/plug.ts +76 -134
- package/src/device/robotvacuumcleaner.ts +91 -159
- package/src/irdevice/airconditioner.ts +56 -81
- package/src/irdevice/airpurifier.ts +41 -67
- package/src/irdevice/camera.ts +35 -60
- package/src/irdevice/fan.ts +46 -71
- package/src/irdevice/light.ts +38 -63
- package/src/irdevice/other.ts +35 -60
- package/src/irdevice/tv.ts +52 -80
- package/src/irdevice/vacuumcleaner.ts +36 -62
- package/src/irdevice/waterheater.ts +46 -76
- package/src/platform.ts +144 -158
- package/src/settings.ts +5 -0
- package/.github/npm-version-script.js +0 -81
- package/dist/device/striplight.d.ts.map +0 -1
- package/dist/device/striplight.js.map +0 -1
package/src/irdevice/camera.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import crypto from 'crypto';
|
|
3
|
-
import { IncomingMessage } from 'http';
|
|
4
|
-
import superStringify from 'super-stringify';
|
|
1
|
+
import { request } from 'undici';
|
|
5
2
|
import { SwitchBotPlatform } from '../platform';
|
|
6
|
-
import { irDevicesConfig, irdevice,
|
|
3
|
+
import { irDevicesConfig, irdevice, Devices } from '../settings';
|
|
7
4
|
import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
|
|
8
5
|
|
|
9
6
|
/**
|
|
@@ -84,11 +81,11 @@ export class Camera {
|
|
|
84
81
|
*/
|
|
85
82
|
async pushOnChanges(): Promise<void> {
|
|
86
83
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushOnChanges On: ${this.On},`
|
|
87
|
-
|
|
84
|
+
+ ` disablePushOn: ${this.disablePushOn}`);
|
|
88
85
|
if (this.On && !this.disablePushOn) {
|
|
89
86
|
const commandType: string = await this.commandType();
|
|
90
87
|
const command: string = await this.commandOn();
|
|
91
|
-
const body =
|
|
88
|
+
const body = JSON.stringify({
|
|
92
89
|
'command': command,
|
|
93
90
|
'parameter': 'default',
|
|
94
91
|
'commandType': commandType,
|
|
@@ -99,11 +96,11 @@ export class Camera {
|
|
|
99
96
|
|
|
100
97
|
async pushOffChanges(): Promise<void> {
|
|
101
98
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushOffChanges On: ${this.On},`
|
|
102
|
-
|
|
99
|
+
+ ` disablePushOff: ${this.disablePushOff}`);
|
|
103
100
|
if (!this.On && !this.disablePushOff) {
|
|
104
101
|
const commandType: string = await this.commandType();
|
|
105
102
|
const command: string = await this.commandOff();
|
|
106
|
-
const body =
|
|
103
|
+
const body = JSON.stringify({
|
|
107
104
|
'command': command,
|
|
108
105
|
'parameter': 'default',
|
|
109
106
|
'commandType': commandType,
|
|
@@ -113,55 +110,28 @@ export class Camera {
|
|
|
113
110
|
}
|
|
114
111
|
|
|
115
112
|
async pushChanges(body: any): Promise<void> {
|
|
113
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushChanges`);
|
|
116
114
|
if (this.device.connectionType === 'OpenAPI') {
|
|
115
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
|
|
117
116
|
try {
|
|
118
|
-
|
|
119
|
-
const t = Date.now();
|
|
120
|
-
const nonce = 'requestID';
|
|
121
|
-
const data = this.platform.config.credentials?.token + t + nonce;
|
|
122
|
-
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
|
|
123
|
-
.update(Buffer.from(data, 'utf-8'))
|
|
124
|
-
.digest();
|
|
125
|
-
const sign = signTerm.toString('base64');
|
|
126
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
127
|
-
this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
|
|
128
|
-
const options = {
|
|
129
|
-
hostname: HostDomain,
|
|
130
|
-
port: 443,
|
|
131
|
-
path: `${DevicePath}/${this.device.deviceId}/commands`,
|
|
117
|
+
const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
|
|
132
118
|
method: 'POST',
|
|
133
|
-
headers:
|
|
134
|
-
'Authorization': this.platform.config.credentials?.token,
|
|
135
|
-
'sign': sign,
|
|
136
|
-
'nonce': nonce,
|
|
137
|
-
't': t,
|
|
138
|
-
'Content-Type': 'application/json',
|
|
139
|
-
'Content-Length': body.length,
|
|
140
|
-
},
|
|
141
|
-
};
|
|
142
|
-
const req = https.request(options, res => {
|
|
143
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges statusCode: ${res.statusCode}`);
|
|
144
|
-
this.statusCode({ res });
|
|
145
|
-
res.on('data', d => {
|
|
146
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} d: ${d}`);
|
|
147
|
-
});
|
|
119
|
+
headers: this.platform.generateHeaders(),
|
|
148
120
|
});
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
req.end();
|
|
154
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
|
|
121
|
+
const deviceStatus = await body.json();
|
|
122
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
|
|
123
|
+
this.statusCode(statusCode);
|
|
124
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
|
|
155
125
|
this.updateHomeKitCharacteristics();
|
|
156
126
|
} catch (e: any) {
|
|
157
127
|
this.apiError(e);
|
|
158
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}
|
|
159
|
-
|
|
128
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
|
|
129
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
160
130
|
);
|
|
161
131
|
}
|
|
162
132
|
} else {
|
|
163
133
|
this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
|
|
164
|
-
|
|
134
|
+
+ ` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`);
|
|
165
135
|
}
|
|
166
136
|
}
|
|
167
137
|
|
|
@@ -221,34 +191,39 @@ export class Camera {
|
|
|
221
191
|
return command;
|
|
222
192
|
}
|
|
223
193
|
|
|
224
|
-
async statusCode(
|
|
225
|
-
switch (
|
|
194
|
+
async statusCode(statusCode: number): Promise<void> {
|
|
195
|
+
switch (statusCode) {
|
|
226
196
|
case 151:
|
|
227
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this
|
|
197
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
228
198
|
break;
|
|
229
199
|
case 152:
|
|
230
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found
|
|
200
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
231
201
|
break;
|
|
232
202
|
case 160:
|
|
233
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported
|
|
203
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
234
204
|
break;
|
|
235
205
|
case 161:
|
|
236
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline
|
|
206
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
237
207
|
break;
|
|
238
208
|
case 171:
|
|
239
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline
|
|
209
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
|
|
210
|
+
+ `Hub: ${this.device.hubDeviceId}`);
|
|
240
211
|
break;
|
|
241
212
|
case 190:
|
|
242
213
|
this.errorLog(
|
|
243
|
-
`${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized
|
|
244
|
-
|
|
214
|
+
`${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
215
|
+
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
245
216
|
);
|
|
246
217
|
break;
|
|
247
218
|
case 100:
|
|
248
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent
|
|
219
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
220
|
+
break;
|
|
221
|
+
case 200:
|
|
222
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
249
223
|
break;
|
|
250
224
|
default:
|
|
251
|
-
this.
|
|
225
|
+
this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode: `
|
|
226
|
+
+ `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
|
|
252
227
|
}
|
|
253
228
|
}
|
|
254
229
|
|
|
@@ -259,7 +234,7 @@ export class Camera {
|
|
|
259
234
|
FirmwareRevision(accessory: PlatformAccessory, device: irdevice & irDevicesConfig): string {
|
|
260
235
|
let FirmwareRevision: string;
|
|
261
236
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName}`
|
|
262
|
-
|
|
237
|
+
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
263
238
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
264
239
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
265
240
|
if (accessory.context.FirmwareRevision) {
|
|
@@ -310,7 +285,7 @@ export class Camera {
|
|
|
310
285
|
config['disablePushOff'] = device.disablePushOff;
|
|
311
286
|
}
|
|
312
287
|
if (Object.entries(config).length !== 0) {
|
|
313
|
-
this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${
|
|
288
|
+
this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
314
289
|
}
|
|
315
290
|
}
|
|
316
291
|
|
package/src/irdevice/fan.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import crypto from 'crypto';
|
|
3
|
-
import { IncomingMessage } from 'http';
|
|
4
|
-
import superStringify from 'super-stringify';
|
|
1
|
+
import { request } from 'undici';
|
|
5
2
|
import { SwitchBotPlatform } from '../platform';
|
|
6
3
|
import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
|
|
7
|
-
import { irdevice, irDevicesConfig,
|
|
4
|
+
import { irdevice, irDevicesConfig, Devices } from '../settings';
|
|
8
5
|
|
|
9
6
|
/**
|
|
10
7
|
* Platform Accessory
|
|
@@ -103,7 +100,7 @@ export class Fan {
|
|
|
103
100
|
// eslint-disable-next-line max-len
|
|
104
101
|
this.debugLog(
|
|
105
102
|
`${this.device.remoteType}: ${this.accessory.displayName} RotationSpeed Characteristic was not removed/added, ` +
|
|
106
|
-
|
|
103
|
+
`Clear Cache on ${this.accessory.displayName} to remove Chracteristic`,
|
|
107
104
|
);
|
|
108
105
|
}
|
|
109
106
|
|
|
@@ -118,7 +115,7 @@ export class Fan {
|
|
|
118
115
|
// eslint-disable-next-line max-len
|
|
119
116
|
this.debugLog(
|
|
120
117
|
`${this.device.remoteType}: ${this.accessory.displayName} Swing Mode Characteristic was not removed/added, ` +
|
|
121
|
-
|
|
118
|
+
`Clear Cache on ${this.accessory.displayName} To Remove Chracteristic`,
|
|
122
119
|
);
|
|
123
120
|
}
|
|
124
121
|
}
|
|
@@ -174,111 +171,84 @@ export class Fan {
|
|
|
174
171
|
*/
|
|
175
172
|
async pushFanOnChanges(): Promise<void> {
|
|
176
173
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushFanOnChanges Active: ${this.Active},`
|
|
177
|
-
|
|
174
|
+
+ ` disablePushOn: ${this.disablePushOn}`);
|
|
178
175
|
if (this.Active === this.platform.Characteristic.Active.ACTIVE && !this.disablePushOn) {
|
|
179
176
|
const commandType: string = await this.commandType();
|
|
180
177
|
const command: string = await this.commandOn();
|
|
181
|
-
const body =
|
|
178
|
+
const body = JSON.stringify({
|
|
182
179
|
'command': command,
|
|
183
180
|
'parameter': 'default',
|
|
184
181
|
'commandType': commandType,
|
|
185
182
|
});
|
|
186
|
-
await this.
|
|
183
|
+
await this.pushChanges(body);
|
|
187
184
|
}
|
|
188
185
|
}
|
|
189
186
|
|
|
190
187
|
async pushFanOffChanges(): Promise<void> {
|
|
191
188
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushLightOffChanges Active: ${this.Active},`
|
|
192
|
-
|
|
189
|
+
+ ` disablePushOff: ${this.disablePushOff}`);
|
|
193
190
|
if (this.Active === this.platform.Characteristic.Active.INACTIVE && !this.disablePushOff) {
|
|
194
191
|
const commandType: string = await this.commandType();
|
|
195
192
|
const command: string = await this.commandOff();
|
|
196
|
-
const body =
|
|
193
|
+
const body = JSON.stringify({
|
|
197
194
|
'command': command,
|
|
198
195
|
'parameter': 'default',
|
|
199
196
|
'commandType': commandType,
|
|
200
197
|
});
|
|
201
|
-
await this.
|
|
198
|
+
await this.pushChanges(body);
|
|
202
199
|
}
|
|
203
200
|
}
|
|
204
201
|
|
|
205
202
|
async pushFanSpeedUpChanges(): Promise<void> {
|
|
206
|
-
const body =
|
|
203
|
+
const body = JSON.stringify({
|
|
207
204
|
'command': 'highSpeed',
|
|
208
205
|
'parameter': 'default',
|
|
209
206
|
'commandType': 'command',
|
|
210
207
|
});
|
|
211
|
-
await this.
|
|
208
|
+
await this.pushChanges(body);
|
|
212
209
|
}
|
|
213
210
|
|
|
214
211
|
async pushFanSpeedDownChanges(): Promise<void> {
|
|
215
|
-
const body =
|
|
212
|
+
const body = JSON.stringify({
|
|
216
213
|
'command': 'lowSpeed',
|
|
217
214
|
'parameter': 'default',
|
|
218
215
|
'commandType': 'command',
|
|
219
216
|
});
|
|
220
|
-
await this.
|
|
217
|
+
await this.pushChanges(body);
|
|
221
218
|
}
|
|
222
219
|
|
|
223
220
|
async pushFanSwingChanges(): Promise<void> {
|
|
224
|
-
const body =
|
|
221
|
+
const body = JSON.stringify({
|
|
225
222
|
'command': 'swing',
|
|
226
223
|
'parameter': 'default',
|
|
227
224
|
'commandType': 'command',
|
|
228
225
|
});
|
|
229
|
-
await this.
|
|
226
|
+
await this.pushChanges(body);
|
|
230
227
|
}
|
|
231
228
|
|
|
232
|
-
async
|
|
229
|
+
async pushChanges(body: any): Promise<void> {
|
|
230
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushChanges`);
|
|
233
231
|
if (this.device.connectionType === 'OpenAPI') {
|
|
232
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
|
|
234
233
|
try {
|
|
235
|
-
|
|
236
|
-
const t = Date.now();
|
|
237
|
-
const nonce = 'requestID';
|
|
238
|
-
const data = this.platform.config.credentials?.token + t + nonce;
|
|
239
|
-
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
|
|
240
|
-
.update(Buffer.from(data, 'utf-8'))
|
|
241
|
-
.digest();
|
|
242
|
-
const sign = signTerm.toString('base64');
|
|
243
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
244
|
-
this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
|
|
245
|
-
const options = {
|
|
246
|
-
hostname: HostDomain,
|
|
247
|
-
port: 443,
|
|
248
|
-
path: `${DevicePath}/${this.device.deviceId}/commands`,
|
|
234
|
+
const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
|
|
249
235
|
method: 'POST',
|
|
250
|
-
headers:
|
|
251
|
-
'Authorization': this.platform.config.credentials?.token,
|
|
252
|
-
'sign': sign,
|
|
253
|
-
'nonce': nonce,
|
|
254
|
-
't': t,
|
|
255
|
-
'Content-Type': 'application/json',
|
|
256
|
-
'Content-Length': body.length,
|
|
257
|
-
},
|
|
258
|
-
};
|
|
259
|
-
const req = https.request(options, res => {
|
|
260
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges statusCode: ${res.statusCode}`);
|
|
261
|
-
this.statusCode({ res });
|
|
262
|
-
res.on('data', d => {
|
|
263
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} d: ${d}`);
|
|
264
|
-
});
|
|
236
|
+
headers: this.platform.generateHeaders(),
|
|
265
237
|
});
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
req.end();
|
|
271
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
|
|
238
|
+
const deviceStatus = await body.json();
|
|
239
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
|
|
240
|
+
this.statusCode(statusCode);
|
|
241
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
|
|
272
242
|
this.updateHomeKitCharacteristics();
|
|
273
243
|
} catch (e: any) {
|
|
274
244
|
this.apiError(e);
|
|
275
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}
|
|
276
|
-
|
|
245
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
|
|
246
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
277
247
|
);
|
|
278
248
|
}
|
|
279
249
|
} else {
|
|
280
250
|
this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
|
|
281
|
-
|
|
251
|
+
+ ` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`);
|
|
282
252
|
}
|
|
283
253
|
}
|
|
284
254
|
|
|
@@ -352,34 +322,39 @@ export class Fan {
|
|
|
352
322
|
return command;
|
|
353
323
|
}
|
|
354
324
|
|
|
355
|
-
async statusCode(
|
|
356
|
-
switch (
|
|
325
|
+
async statusCode(statusCode: number): Promise<void> {
|
|
326
|
+
switch (statusCode) {
|
|
357
327
|
case 151:
|
|
358
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this
|
|
328
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
359
329
|
break;
|
|
360
330
|
case 152:
|
|
361
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found
|
|
331
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
362
332
|
break;
|
|
363
333
|
case 160:
|
|
364
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported
|
|
334
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
365
335
|
break;
|
|
366
336
|
case 161:
|
|
367
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline
|
|
337
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
368
338
|
break;
|
|
369
339
|
case 171:
|
|
370
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline
|
|
340
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
|
|
341
|
+
+ `Hub: ${this.device.hubDeviceId}`);
|
|
371
342
|
break;
|
|
372
343
|
case 190:
|
|
373
344
|
this.errorLog(
|
|
374
|
-
`${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized
|
|
375
|
-
|
|
345
|
+
`${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
346
|
+
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
376
347
|
);
|
|
377
348
|
break;
|
|
378
349
|
case 100:
|
|
379
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent
|
|
350
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
351
|
+
break;
|
|
352
|
+
case 200:
|
|
353
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
380
354
|
break;
|
|
381
355
|
default:
|
|
382
|
-
this.
|
|
356
|
+
this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode: `
|
|
357
|
+
+ `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
|
|
383
358
|
}
|
|
384
359
|
}
|
|
385
360
|
|
|
@@ -392,7 +367,7 @@ export class Fan {
|
|
|
392
367
|
FirmwareRevision(accessory: PlatformAccessory, device: irdevice & irDevicesConfig): string {
|
|
393
368
|
let FirmwareRevision: string;
|
|
394
369
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName}`
|
|
395
|
-
|
|
370
|
+
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
396
371
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
397
372
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
398
373
|
if (accessory.context.FirmwareRevision) {
|
|
@@ -444,7 +419,7 @@ export class Fan {
|
|
|
444
419
|
config['disablePushOff'] = device.disablePushOff;
|
|
445
420
|
}
|
|
446
421
|
if (Object.entries(config).length !== 0) {
|
|
447
|
-
this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${
|
|
422
|
+
this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
448
423
|
}
|
|
449
424
|
}
|
|
450
425
|
|
package/src/irdevice/light.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import crypto from 'crypto';
|
|
3
|
-
import { IncomingMessage } from 'http';
|
|
4
|
-
import superStringify from 'super-stringify';
|
|
1
|
+
import { request } from 'undici';
|
|
5
2
|
import { SwitchBotPlatform } from '../platform';
|
|
6
|
-
import { irDevicesConfig, irdevice,
|
|
3
|
+
import { irDevicesConfig, irdevice, Devices } from '../settings';
|
|
7
4
|
import { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
|
|
8
5
|
|
|
9
6
|
/**
|
|
@@ -88,11 +85,11 @@ export class Light {
|
|
|
88
85
|
*/
|
|
89
86
|
async pushLightOnChanges(): Promise<void> {
|
|
90
87
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushLightOnChanges On: ${this.On},`
|
|
91
|
-
|
|
88
|
+
+ ` disablePushOn: ${this.disablePushOn}`);
|
|
92
89
|
if (this.On && !this.disablePushOn) {
|
|
93
90
|
const commandType: string = await this.commandType();
|
|
94
91
|
const command: string = await this.commandOn();
|
|
95
|
-
const body =
|
|
92
|
+
const body = JSON.stringify({
|
|
96
93
|
'command': command,
|
|
97
94
|
'parameter': 'default',
|
|
98
95
|
'commandType': commandType,
|
|
@@ -103,11 +100,11 @@ export class Light {
|
|
|
103
100
|
|
|
104
101
|
async pushLightOffChanges(): Promise<void> {
|
|
105
102
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushLightOffChanges On: ${this.On},`
|
|
106
|
-
|
|
103
|
+
+ ` disablePushOff: ${this.disablePushOff}`);
|
|
107
104
|
if (!this.On && !this.disablePushOff) {
|
|
108
105
|
const commandType: string = await this.commandType();
|
|
109
106
|
const command: string = await this.commandOff();
|
|
110
|
-
const body =
|
|
107
|
+
const body = JSON.stringify({
|
|
111
108
|
'command': command,
|
|
112
109
|
'parameter': 'default',
|
|
113
110
|
'commandType': commandType,
|
|
@@ -117,7 +114,7 @@ export class Light {
|
|
|
117
114
|
}
|
|
118
115
|
|
|
119
116
|
async pushLightBrightnessUpChanges(): Promise<void> {
|
|
120
|
-
const body =
|
|
117
|
+
const body = JSON.stringify({
|
|
121
118
|
'command': 'brightnessUp',
|
|
122
119
|
'parameter': 'default',
|
|
123
120
|
'commandType': 'command',
|
|
@@ -126,7 +123,7 @@ export class Light {
|
|
|
126
123
|
}
|
|
127
124
|
|
|
128
125
|
async pushLightBrightnessDownChanges(): Promise<void> {
|
|
129
|
-
const body =
|
|
126
|
+
const body = JSON.stringify({
|
|
130
127
|
'command': 'brightnessDown',
|
|
131
128
|
'parameter': 'default',
|
|
132
129
|
'commandType': 'command',
|
|
@@ -134,57 +131,30 @@ export class Light {
|
|
|
134
131
|
await this.pushChanges(body);
|
|
135
132
|
}
|
|
136
133
|
|
|
137
|
-
async pushChanges(body): Promise<void> {
|
|
134
|
+
async pushChanges(body: any): Promise<void> {
|
|
135
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushChanges`);
|
|
138
136
|
if (this.device.connectionType === 'OpenAPI') {
|
|
137
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
|
|
139
138
|
try {
|
|
140
|
-
|
|
141
|
-
const t = Date.now();
|
|
142
|
-
const nonce = 'requestID';
|
|
143
|
-
const data = this.platform.config.credentials?.token + t + nonce;
|
|
144
|
-
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
|
|
145
|
-
.update(Buffer.from(data, 'utf-8'))
|
|
146
|
-
.digest();
|
|
147
|
-
const sign = signTerm.toString('base64');
|
|
148
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
149
|
-
this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
|
|
150
|
-
const options = {
|
|
151
|
-
hostname: HostDomain,
|
|
152
|
-
port: 443,
|
|
153
|
-
path: `${DevicePath}/${this.device.deviceId}/commands`,
|
|
139
|
+
const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
|
|
154
140
|
method: 'POST',
|
|
155
|
-
headers:
|
|
156
|
-
'Authorization': this.platform.config.credentials?.token,
|
|
157
|
-
'sign': sign,
|
|
158
|
-
'nonce': nonce,
|
|
159
|
-
't': t,
|
|
160
|
-
'Content-Type': 'application/json',
|
|
161
|
-
'Content-Length': body.length,
|
|
162
|
-
},
|
|
163
|
-
};
|
|
164
|
-
const req = https.request(options, res => {
|
|
165
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
166
|
-
this.statusCode({ res });
|
|
167
|
-
res.on('data', d => {
|
|
168
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} d: ${d}`);
|
|
169
|
-
});
|
|
141
|
+
headers: this.platform.generateHeaders(),
|
|
170
142
|
});
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
req.end();
|
|
176
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} pushchanges: ${superStringify(req)}`);
|
|
143
|
+
const deviceStatus = await body.json();
|
|
144
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
|
|
145
|
+
this.statusCode(statusCode);
|
|
146
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
|
|
177
147
|
this.accessory.context.On = this.On;
|
|
178
148
|
this.updateHomeKitCharacteristics();
|
|
179
149
|
} catch (e: any) {
|
|
180
150
|
this.apiError(e);
|
|
181
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}
|
|
182
|
-
|
|
151
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType}`
|
|
152
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
183
153
|
);
|
|
184
154
|
}
|
|
185
155
|
} else {
|
|
186
156
|
this.warnLog(`${this.device.remoteType}: ${this.accessory.displayName}`
|
|
187
|
-
|
|
157
|
+
+ ` Connection Type: ${this.device.connectionType}, commands will not be sent to OpenAPI`);
|
|
188
158
|
}
|
|
189
159
|
}
|
|
190
160
|
|
|
@@ -244,34 +214,39 @@ export class Light {
|
|
|
244
214
|
return command;
|
|
245
215
|
}
|
|
246
216
|
|
|
247
|
-
async statusCode(
|
|
248
|
-
switch (
|
|
217
|
+
async statusCode(statusCode: number): Promise<void> {
|
|
218
|
+
switch (statusCode) {
|
|
249
219
|
case 151:
|
|
250
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this
|
|
220
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
251
221
|
break;
|
|
252
222
|
case 152:
|
|
253
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found
|
|
223
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
254
224
|
break;
|
|
255
225
|
case 160:
|
|
256
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported
|
|
226
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
257
227
|
break;
|
|
258
228
|
case 161:
|
|
259
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline
|
|
229
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
260
230
|
break;
|
|
261
231
|
case 171:
|
|
262
|
-
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline
|
|
232
|
+
this.errorLog(`${this.device.remoteType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
|
|
233
|
+
+ `Hub: ${this.device.hubDeviceId}`);
|
|
263
234
|
break;
|
|
264
235
|
case 190:
|
|
265
236
|
this.errorLog(
|
|
266
|
-
`${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized
|
|
267
|
-
|
|
237
|
+
`${this.device.remoteType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
238
|
+
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
268
239
|
);
|
|
269
240
|
break;
|
|
270
241
|
case 100:
|
|
271
|
-
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent
|
|
242
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
243
|
+
break;
|
|
244
|
+
case 200:
|
|
245
|
+
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
272
246
|
break;
|
|
273
247
|
default:
|
|
274
|
-
this.
|
|
248
|
+
this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Unknown statusCode: `
|
|
249
|
+
+ `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
|
|
275
250
|
}
|
|
276
251
|
}
|
|
277
252
|
|
|
@@ -282,7 +257,7 @@ export class Light {
|
|
|
282
257
|
FirmwareRevision(accessory: PlatformAccessory, device: irdevice & irDevicesConfig): string {
|
|
283
258
|
let FirmwareRevision: string;
|
|
284
259
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName}`
|
|
285
|
-
|
|
260
|
+
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
286
261
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
287
262
|
this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
288
263
|
if (accessory.context.FirmwareRevision) {
|
|
@@ -333,7 +308,7 @@ export class Light {
|
|
|
333
308
|
config['disablePushOff'] = device.disablePushOff;
|
|
334
309
|
}
|
|
335
310
|
if (Object.entries(config).length !== 0) {
|
|
336
|
-
this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${
|
|
311
|
+
this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
337
312
|
}
|
|
338
313
|
}
|
|
339
314
|
|