tsvesync 1.0.19 → 1.0.22
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/dist/lib/vesync.d.ts +2 -2
- package/dist/lib/vesync.js +69 -53
- package/dist/lib/vesyncOutlet.js +19 -2
- package/dist/lib/vesyncOutletImpl.d.ts +3 -0
- package/dist/lib/vesyncOutletImpl.js +13 -2
- package/package.json +1 -1
- package/src/lib/vesync.ts +72 -58
- package/src/lib/vesyncOutlet.ts +23 -4
- package/src/lib/vesyncOutletImpl.ts +19 -2
package/dist/lib/vesync.d.ts
CHANGED
|
@@ -71,9 +71,9 @@ export declare class VeSync {
|
|
|
71
71
|
*/
|
|
72
72
|
static setDevId(devices: any[]): any[];
|
|
73
73
|
/**
|
|
74
|
-
* Process
|
|
74
|
+
* Process devices from API response
|
|
75
75
|
*/
|
|
76
|
-
processDevices
|
|
76
|
+
private processDevices;
|
|
77
77
|
/**
|
|
78
78
|
* Get list of VeSync devices
|
|
79
79
|
*/
|
package/dist/lib/vesync.js
CHANGED
|
@@ -84,8 +84,31 @@ function objectFactory(details, manager) {
|
|
|
84
84
|
try {
|
|
85
85
|
// Add category to device details
|
|
86
86
|
details.deviceCategory = category;
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
// Handle outdoor plug sub-devices
|
|
88
|
+
if (deviceType === 'ESO15-TB' && details.subDevices) {
|
|
89
|
+
const devices = [];
|
|
90
|
+
// Create a device instance for each sub-device
|
|
91
|
+
details.subDevices.forEach((subDevice) => {
|
|
92
|
+
const subDeviceDetails = {
|
|
93
|
+
...details,
|
|
94
|
+
deviceName: subDevice.subDeviceName,
|
|
95
|
+
deviceStatus: subDevice.subDeviceStatus,
|
|
96
|
+
subDeviceNo: subDevice.subDeviceNo,
|
|
97
|
+
isSubDevice: true,
|
|
98
|
+
parentCid: details.cid,
|
|
99
|
+
// Generate a unique CID for the sub-device
|
|
100
|
+
cid: `${details.cid}_${subDevice.subDeviceNo}`
|
|
101
|
+
};
|
|
102
|
+
const device = new DeviceClass(subDeviceDetails, manager);
|
|
103
|
+
devices.push([category, device]);
|
|
104
|
+
});
|
|
105
|
+
// Return array of sub-devices
|
|
106
|
+
return devices[0]; // Return first device, manager will handle adding all devices
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
const device = new DeviceClass(details, manager);
|
|
110
|
+
return [category, device];
|
|
111
|
+
}
|
|
89
112
|
}
|
|
90
113
|
catch (error) {
|
|
91
114
|
logger_1.logger.error(`Error creating device instance for ${deviceType}:`, error);
|
|
@@ -265,57 +288,52 @@ class VeSync {
|
|
|
265
288
|
return devices;
|
|
266
289
|
}
|
|
267
290
|
/**
|
|
268
|
-
* Process
|
|
291
|
+
* Process devices from API response
|
|
269
292
|
*/
|
|
270
|
-
processDevices(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
logger_1.logger.warn('No devices found in api return');
|
|
280
|
-
return false;
|
|
281
|
-
}
|
|
282
|
-
// Initialize new device list or remove old devices
|
|
283
|
-
if (numDevices === 0) {
|
|
284
|
-
logger_1.logger.debug('New device list initialized');
|
|
285
|
-
}
|
|
286
|
-
else {
|
|
287
|
-
this.removeOldDevices(devices);
|
|
288
|
-
}
|
|
289
|
-
// Filter out devices that already exist
|
|
290
|
-
const newDevices = devices.filter(dev => this.addDevTest(dev));
|
|
291
|
-
// Required keys for device instantiation
|
|
292
|
-
const requiredKeys = ['deviceType', 'deviceName', 'deviceStatus', 'cid'];
|
|
293
|
-
// Process each new device
|
|
294
|
-
for (const dev of newDevices) {
|
|
295
|
-
// Verify required device properties
|
|
296
|
-
if (!requiredKeys.every(key => key in dev)) {
|
|
297
|
-
logger_1.logger.debug(`Error adding device - missing required properties: ${dev.deviceName || 'Unknown'}`);
|
|
298
|
-
continue;
|
|
293
|
+
processDevices(deviceList) {
|
|
294
|
+
try {
|
|
295
|
+
// Clear existing devices
|
|
296
|
+
for (const category of Object.keys(this._devList)) {
|
|
297
|
+
this._devList[category].length = 0;
|
|
298
|
+
}
|
|
299
|
+
if (!deviceList || deviceList.length === 0) {
|
|
300
|
+
logger_1.logger.warn('No devices found in API response');
|
|
301
|
+
return false;
|
|
299
302
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
303
|
+
// Process each device
|
|
304
|
+
deviceList.forEach(dev => {
|
|
305
|
+
const [category, device] = objectFactory(dev, this);
|
|
306
|
+
// Handle outdoor plug sub-devices
|
|
307
|
+
if (dev.deviceType === 'ESO15-TB' && dev.subDevices) {
|
|
308
|
+
dev.subDevices.forEach((subDev) => {
|
|
309
|
+
const subDeviceDetails = {
|
|
310
|
+
...dev,
|
|
311
|
+
deviceName: subDev.subDeviceName,
|
|
312
|
+
deviceStatus: subDev.subDeviceStatus,
|
|
313
|
+
subDeviceNo: subDev.subDeviceNo,
|
|
314
|
+
isSubDevice: true,
|
|
315
|
+
parentCid: dev.cid,
|
|
316
|
+
cid: `${dev.cid}_${subDev.subDeviceNo}`
|
|
317
|
+
};
|
|
318
|
+
const [subCategory, subDevice] = objectFactory(subDeviceDetails, this);
|
|
319
|
+
if (subDevice && subCategory in this._devList) {
|
|
320
|
+
this._devList[subCategory].push(subDevice);
|
|
321
|
+
}
|
|
322
|
+
});
|
|
308
323
|
}
|
|
309
|
-
else if (category
|
|
310
|
-
|
|
324
|
+
else if (device && category in this._devList) {
|
|
325
|
+
this._devList[category].push(device);
|
|
311
326
|
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
327
|
+
});
|
|
328
|
+
// Update device list reference
|
|
329
|
+
this.devices = Object.values(this._devList).flat();
|
|
330
|
+
// Return true if we processed at least one device successfully
|
|
331
|
+
return this.devices.length > 0;
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
logger_1.logger.error('Error processing devices:', error);
|
|
335
|
+
return false;
|
|
317
336
|
}
|
|
318
|
-
return true;
|
|
319
337
|
}
|
|
320
338
|
/**
|
|
321
339
|
* Get list of VeSync devices
|
|
@@ -327,14 +345,12 @@ class VeSync {
|
|
|
327
345
|
return false;
|
|
328
346
|
}
|
|
329
347
|
this._inProcess = true;
|
|
330
|
-
let
|
|
348
|
+
let success = false;
|
|
331
349
|
try {
|
|
332
350
|
const [response] = await helpers_1.Helpers.callApi('/cloud/v2/deviceManaged/devices', 'post', helpers_1.Helpers.reqBody(this, 'devicelist'), helpers_1.Helpers.reqHeaders(this));
|
|
333
351
|
if ((_a = response === null || response === void 0 ? void 0 : response.result) === null || _a === void 0 ? void 0 : _a.list) {
|
|
334
352
|
const deviceList = response.result.list;
|
|
335
|
-
|
|
336
|
-
// Update the main devices array with all devices
|
|
337
|
-
this.devices = Object.values(this._devList).flat();
|
|
353
|
+
success = this.processDevices(deviceList);
|
|
338
354
|
// Log device discovery results
|
|
339
355
|
logger_1.logger.debug('\n=== Device Discovery Summary ===');
|
|
340
356
|
logger_1.logger.debug(`Total devices processed: ${deviceList.length}`);
|
|
@@ -372,7 +388,7 @@ class VeSync {
|
|
|
372
388
|
logger_1.logger.error('Unable to get device list:', error);
|
|
373
389
|
}
|
|
374
390
|
this._inProcess = false;
|
|
375
|
-
return
|
|
391
|
+
return success;
|
|
376
392
|
}
|
|
377
393
|
/**
|
|
378
394
|
* Login to VeSync server
|
package/dist/lib/vesyncOutlet.js
CHANGED
|
@@ -81,10 +81,27 @@ class VeSyncOutlet extends vesyncBaseDevice_1.VeSyncBaseDevice {
|
|
|
81
81
|
this.details = response;
|
|
82
82
|
// Handle outdoor plugs with subdevices
|
|
83
83
|
if (response.subDevices) {
|
|
84
|
-
const subDevice = response.subDevices.find((dev) =>
|
|
84
|
+
const subDevice = response.subDevices.find((dev) => {
|
|
85
|
+
// Match by name (primary identifier)
|
|
86
|
+
if (dev.subDeviceName === this.deviceName) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
// Match by subDeviceNo if available
|
|
90
|
+
if ('subDeviceNo' in this && this.subDeviceNo === dev.subDeviceNo) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
// Match by cid/uuid if available (cid might be in format parentCid_subDeviceNo)
|
|
94
|
+
if (this.cid && this.cid.includes('_')) {
|
|
95
|
+
const [_, subId] = this.cid.split('_');
|
|
96
|
+
if (subId && dev.subDeviceNo === parseInt(subId)) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
});
|
|
85
102
|
if (subDevice) {
|
|
86
103
|
this.deviceStatus = subDevice.subDeviceStatus;
|
|
87
|
-
logger_1.logger.info(`[${this.deviceName}] Successfully retrieved
|
|
104
|
+
logger_1.logger.info(`[${this.deviceName}] Successfully retrieved sub-device status: ${this.deviceStatus}`);
|
|
88
105
|
return;
|
|
89
106
|
}
|
|
90
107
|
}
|
|
@@ -57,6 +57,9 @@ export declare class VeSyncOutlet15A extends VeSyncOutlet {
|
|
|
57
57
|
* VeSync Outdoor Plug
|
|
58
58
|
*/
|
|
59
59
|
export declare class VeSyncOutdoorPlug extends VeSyncOutlet {
|
|
60
|
+
protected subDeviceNo?: number;
|
|
61
|
+
protected isSubDevice: boolean;
|
|
62
|
+
protected parentCid?: string;
|
|
60
63
|
constructor(details: Record<string, any>, manager: VeSync);
|
|
61
64
|
/**
|
|
62
65
|
* Turn outlet on
|
|
@@ -192,17 +192,24 @@ exports.VeSyncOutlet15A = VeSyncOutlet15A;
|
|
|
192
192
|
class VeSyncOutdoorPlug extends vesyncOutlet_1.VeSyncOutlet {
|
|
193
193
|
constructor(details, manager) {
|
|
194
194
|
super(details, manager);
|
|
195
|
+
this.isSubDevice = details.isSubDevice || false;
|
|
196
|
+
this.subDeviceNo = details.subDeviceNo;
|
|
197
|
+
this.parentCid = details.parentCid;
|
|
195
198
|
}
|
|
196
199
|
/**
|
|
197
200
|
* Turn outlet on
|
|
198
201
|
*/
|
|
199
202
|
async turnOn() {
|
|
203
|
+
if (!this.isSubDevice) {
|
|
204
|
+
logger_1.logger.error(`[${this.deviceName}] Cannot control parent device directly`);
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
200
207
|
logger_1.logger.debug(`[${this.deviceName}] Turning outlet on`);
|
|
201
208
|
const body = {
|
|
202
209
|
...helpers_1.Helpers.reqBody(this.manager, 'devicestatus'),
|
|
203
210
|
uuid: this.uuid,
|
|
204
211
|
status: 'on',
|
|
205
|
-
switchNo:
|
|
212
|
+
switchNo: this.subDeviceNo
|
|
206
213
|
};
|
|
207
214
|
const [response] = await helpers_1.Helpers.callApi('/outdoorsocket15a/v1/device/devicestatus', 'put', body, helpers_1.Helpers.reqHeaders(this.manager));
|
|
208
215
|
if ((response === null || response === void 0 ? void 0 : response.code) === 0) {
|
|
@@ -217,12 +224,16 @@ class VeSyncOutdoorPlug extends vesyncOutlet_1.VeSyncOutlet {
|
|
|
217
224
|
* Turn outlet off
|
|
218
225
|
*/
|
|
219
226
|
async turnOff() {
|
|
227
|
+
if (!this.isSubDevice) {
|
|
228
|
+
logger_1.logger.error(`[${this.deviceName}] Cannot control parent device directly`);
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
220
231
|
logger_1.logger.debug(`[${this.deviceName}] Turning outlet off`);
|
|
221
232
|
const body = {
|
|
222
233
|
...helpers_1.Helpers.reqBody(this.manager, 'devicestatus'),
|
|
223
234
|
uuid: this.uuid,
|
|
224
235
|
status: 'off',
|
|
225
|
-
switchNo:
|
|
236
|
+
switchNo: this.subDeviceNo
|
|
226
237
|
};
|
|
227
238
|
const [response] = await helpers_1.Helpers.callApi('/outdoorsocket15a/v1/device/devicestatus', 'put', body, helpers_1.Helpers.reqHeaders(this.manager));
|
|
228
239
|
if ((response === null || response === void 0 ? void 0 : response.code) === 0) {
|
package/package.json
CHANGED
package/src/lib/vesync.ts
CHANGED
|
@@ -103,8 +103,33 @@ function objectFactory(details: Record<string, any>, manager: VeSync): [string,
|
|
|
103
103
|
try {
|
|
104
104
|
// Add category to device details
|
|
105
105
|
details.deviceCategory = category;
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
|
|
107
|
+
// Handle outdoor plug sub-devices
|
|
108
|
+
if (deviceType === 'ESO15-TB' && details.subDevices) {
|
|
109
|
+
const devices: [string, VeSyncBaseDevice | null][] = [];
|
|
110
|
+
|
|
111
|
+
// Create a device instance for each sub-device
|
|
112
|
+
details.subDevices.forEach((subDevice: any) => {
|
|
113
|
+
const subDeviceDetails = {
|
|
114
|
+
...details,
|
|
115
|
+
deviceName: subDevice.subDeviceName,
|
|
116
|
+
deviceStatus: subDevice.subDeviceStatus,
|
|
117
|
+
subDeviceNo: subDevice.subDeviceNo,
|
|
118
|
+
isSubDevice: true,
|
|
119
|
+
parentCid: details.cid,
|
|
120
|
+
// Generate a unique CID for the sub-device
|
|
121
|
+
cid: `${details.cid}_${subDevice.subDeviceNo}`
|
|
122
|
+
};
|
|
123
|
+
const device = new DeviceClass(subDeviceDetails, manager);
|
|
124
|
+
devices.push([category, device]);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Return array of sub-devices
|
|
128
|
+
return devices[0]; // Return first device, manager will handle adding all devices
|
|
129
|
+
} else {
|
|
130
|
+
const device = new DeviceClass(details, manager);
|
|
131
|
+
return [category, device];
|
|
132
|
+
}
|
|
108
133
|
} catch (error) {
|
|
109
134
|
logger.error(`Error creating device instance for ${deviceType}:`, error);
|
|
110
135
|
return [category, null];
|
|
@@ -331,63 +356,55 @@ export class VeSync {
|
|
|
331
356
|
}
|
|
332
357
|
|
|
333
358
|
/**
|
|
334
|
-
* Process
|
|
359
|
+
* Process devices from API response
|
|
335
360
|
*/
|
|
336
|
-
processDevices(
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
for (const deviceList of Object.values(this._devList)) {
|
|
343
|
-
numDevices += deviceList.length;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
if (!devices || devices.length === 0) {
|
|
347
|
-
logger.warn('No devices found in api return');
|
|
348
|
-
return false;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// Initialize new device list or remove old devices
|
|
352
|
-
if (numDevices === 0) {
|
|
353
|
-
logger.debug('New device list initialized');
|
|
354
|
-
} else {
|
|
355
|
-
this.removeOldDevices(devices);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// Filter out devices that already exist
|
|
359
|
-
const newDevices = devices.filter(dev => this.addDevTest(dev));
|
|
361
|
+
private processDevices(deviceList: any[]): boolean {
|
|
362
|
+
try {
|
|
363
|
+
// Clear existing devices
|
|
364
|
+
for (const category of Object.keys(this._devList)) {
|
|
365
|
+
this._devList[category].length = 0;
|
|
366
|
+
}
|
|
360
367
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
// Process each new device
|
|
365
|
-
for (const dev of newDevices) {
|
|
366
|
-
// Verify required device properties
|
|
367
|
-
if (!requiredKeys.every(key => key in dev)) {
|
|
368
|
-
logger.debug(`Error adding device - missing required properties: ${dev.deviceName || 'Unknown'}`);
|
|
369
|
-
continue;
|
|
368
|
+
if (!deviceList || deviceList.length === 0) {
|
|
369
|
+
logger.warn('No devices found in API response');
|
|
370
|
+
return false;
|
|
370
371
|
}
|
|
371
372
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
const [category, deviceObj] = objectFactory(dev, this);
|
|
373
|
+
// Process each device
|
|
374
|
+
deviceList.forEach(dev => {
|
|
375
|
+
const [category, device] = objectFactory(dev, this);
|
|
376
376
|
|
|
377
|
-
//
|
|
378
|
-
if (
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
377
|
+
// Handle outdoor plug sub-devices
|
|
378
|
+
if (dev.deviceType === 'ESO15-TB' && dev.subDevices) {
|
|
379
|
+
dev.subDevices.forEach((subDev: any) => {
|
|
380
|
+
const subDeviceDetails = {
|
|
381
|
+
...dev,
|
|
382
|
+
deviceName: subDev.subDeviceName,
|
|
383
|
+
deviceStatus: subDev.subDeviceStatus,
|
|
384
|
+
subDeviceNo: subDev.subDeviceNo,
|
|
385
|
+
isSubDevice: true,
|
|
386
|
+
parentCid: dev.cid,
|
|
387
|
+
cid: `${dev.cid}_${subDev.subDeviceNo}`
|
|
388
|
+
};
|
|
389
|
+
const [subCategory, subDevice] = objectFactory(subDeviceDetails, this);
|
|
390
|
+
if (subDevice && subCategory in this._devList) {
|
|
391
|
+
this._devList[subCategory].push(subDevice);
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
} else if (device && category in this._devList) {
|
|
395
|
+
this._devList[category].push(device);
|
|
383
396
|
}
|
|
384
|
-
}
|
|
385
|
-
logger.error(`Error creating device ${devType}:`, err);
|
|
386
|
-
continue;
|
|
387
|
-
}
|
|
388
|
-
}
|
|
397
|
+
});
|
|
389
398
|
|
|
390
|
-
|
|
399
|
+
// Update device list reference
|
|
400
|
+
this.devices = Object.values(this._devList).flat();
|
|
401
|
+
|
|
402
|
+
// Return true if we processed at least one device successfully
|
|
403
|
+
return this.devices.length > 0;
|
|
404
|
+
} catch (error) {
|
|
405
|
+
logger.error('Error processing devices:', error);
|
|
406
|
+
return false;
|
|
407
|
+
}
|
|
391
408
|
}
|
|
392
409
|
|
|
393
410
|
/**
|
|
@@ -400,7 +417,7 @@ export class VeSync {
|
|
|
400
417
|
}
|
|
401
418
|
|
|
402
419
|
this._inProcess = true;
|
|
403
|
-
let
|
|
420
|
+
let success = false;
|
|
404
421
|
|
|
405
422
|
try {
|
|
406
423
|
const [response] = await Helpers.callApi(
|
|
@@ -412,10 +429,7 @@ export class VeSync {
|
|
|
412
429
|
|
|
413
430
|
if (response?.result?.list) {
|
|
414
431
|
const deviceList = response.result.list;
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
// Update the main devices array with all devices
|
|
418
|
-
this.devices = Object.values(this._devList).flat();
|
|
432
|
+
success = this.processDevices(deviceList);
|
|
419
433
|
|
|
420
434
|
// Log device discovery results
|
|
421
435
|
logger.debug('\n=== Device Discovery Summary ===');
|
|
@@ -457,7 +471,7 @@ export class VeSync {
|
|
|
457
471
|
}
|
|
458
472
|
|
|
459
473
|
this._inProcess = false;
|
|
460
|
-
return
|
|
474
|
+
return success;
|
|
461
475
|
}
|
|
462
476
|
|
|
463
477
|
/**
|
package/src/lib/vesyncOutlet.ts
CHANGED
|
@@ -101,12 +101,31 @@ export abstract class VeSyncOutlet extends VeSyncBaseDevice {
|
|
|
101
101
|
|
|
102
102
|
// Handle outdoor plugs with subdevices
|
|
103
103
|
if (response.subDevices) {
|
|
104
|
-
const subDevice = response.subDevices.find(
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
const subDevice = response.subDevices.find((dev: any) => {
|
|
105
|
+
// Match by name (primary identifier)
|
|
106
|
+
if (dev.subDeviceName === this.deviceName) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Match by subDeviceNo if available
|
|
111
|
+
if ('subDeviceNo' in this && (this as any).subDeviceNo === dev.subDeviceNo) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Match by cid/uuid if available (cid might be in format parentCid_subDeviceNo)
|
|
116
|
+
if (this.cid && this.cid.includes('_')) {
|
|
117
|
+
const [_, subId] = this.cid.split('_');
|
|
118
|
+
if (subId && dev.subDeviceNo === parseInt(subId)) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return false;
|
|
124
|
+
});
|
|
125
|
+
|
|
107
126
|
if (subDevice) {
|
|
108
127
|
this.deviceStatus = subDevice.subDeviceStatus;
|
|
109
|
-
logger.info(`[${this.deviceName}] Successfully retrieved
|
|
128
|
+
logger.info(`[${this.deviceName}] Successfully retrieved sub-device status: ${this.deviceStatus}`);
|
|
110
129
|
return;
|
|
111
130
|
}
|
|
112
131
|
}
|
|
@@ -254,20 +254,32 @@ export class VeSyncOutlet15A extends VeSyncOutlet {
|
|
|
254
254
|
* VeSync Outdoor Plug
|
|
255
255
|
*/
|
|
256
256
|
export class VeSyncOutdoorPlug extends VeSyncOutlet {
|
|
257
|
+
protected subDeviceNo?: number;
|
|
258
|
+
protected isSubDevice: boolean;
|
|
259
|
+
protected parentCid?: string;
|
|
260
|
+
|
|
257
261
|
constructor(details: Record<string, any>, manager: VeSync) {
|
|
258
262
|
super(details, manager);
|
|
263
|
+
this.isSubDevice = details.isSubDevice || false;
|
|
264
|
+
this.subDeviceNo = details.subDeviceNo;
|
|
265
|
+
this.parentCid = details.parentCid;
|
|
259
266
|
}
|
|
260
267
|
|
|
261
268
|
/**
|
|
262
269
|
* Turn outlet on
|
|
263
270
|
*/
|
|
264
271
|
async turnOn(): Promise<boolean> {
|
|
272
|
+
if (!this.isSubDevice) {
|
|
273
|
+
logger.error(`[${this.deviceName}] Cannot control parent device directly`);
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
265
277
|
logger.debug(`[${this.deviceName}] Turning outlet on`);
|
|
266
278
|
const body = {
|
|
267
279
|
...Helpers.reqBody(this.manager, 'devicestatus'),
|
|
268
280
|
uuid: this.uuid,
|
|
269
281
|
status: 'on',
|
|
270
|
-
switchNo:
|
|
282
|
+
switchNo: this.subDeviceNo
|
|
271
283
|
};
|
|
272
284
|
|
|
273
285
|
const [response] = await Helpers.callApi(
|
|
@@ -290,12 +302,17 @@ export class VeSyncOutdoorPlug extends VeSyncOutlet {
|
|
|
290
302
|
* Turn outlet off
|
|
291
303
|
*/
|
|
292
304
|
async turnOff(): Promise<boolean> {
|
|
305
|
+
if (!this.isSubDevice) {
|
|
306
|
+
logger.error(`[${this.deviceName}] Cannot control parent device directly`);
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
|
|
293
310
|
logger.debug(`[${this.deviceName}] Turning outlet off`);
|
|
294
311
|
const body = {
|
|
295
312
|
...Helpers.reqBody(this.manager, 'devicestatus'),
|
|
296
313
|
uuid: this.uuid,
|
|
297
314
|
status: 'off',
|
|
298
|
-
switchNo:
|
|
315
|
+
switchNo: this.subDeviceNo
|
|
299
316
|
};
|
|
300
317
|
|
|
301
318
|
const [response] = await Helpers.callApi(
|