tsvesync 1.0.11

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.
Files changed (138) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +227 -0
  3. package/api/vesync/VeSync.yaml +33 -0
  4. package/api/vesyncbulb/ESL100.yaml +74 -0
  5. package/api/vesyncbulb/ESL100CW.yaml +123 -0
  6. package/api/vesyncbulb/ESL100MC.yaml +169 -0
  7. package/api/vesyncbulb/XYD0001.yaml +193 -0
  8. package/api/vesyncfan/Classic200S.yaml +280 -0
  9. package/api/vesyncfan/Classic300S.yaml +278 -0
  10. package/api/vesyncfan/Core200S.yaml +256 -0
  11. package/api/vesyncfan/Core300S.yaml +281 -0
  12. package/api/vesyncfan/Core400S.yaml +281 -0
  13. package/api/vesyncfan/Core600S.yaml +281 -0
  14. package/api/vesyncfan/Dual200S.yaml +278 -0
  15. package/api/vesyncfan/LAP-C201S-AUSR.yaml +256 -0
  16. package/api/vesyncfan/LAP-C202S-WUSR.yaml +256 -0
  17. package/api/vesyncfan/LAP-C301S-WAAA.yaml +281 -0
  18. package/api/vesyncfan/LAP-C301S-WJP.yaml +281 -0
  19. package/api/vesyncfan/LAP-C302S-WUSB.yaml +281 -0
  20. package/api/vesyncfan/LAP-C401S-WAAA.yaml +281 -0
  21. package/api/vesyncfan/LAP-C401S-WJP.yaml +281 -0
  22. package/api/vesyncfan/LAP-C401S-WUSR.yaml +281 -0
  23. package/api/vesyncfan/LAP-C601S-WEU.yaml +281 -0
  24. package/api/vesyncfan/LAP-C601S-WUS.yaml +281 -0
  25. package/api/vesyncfan/LAP-C601S-WUSR.yaml +281 -0
  26. package/api/vesyncfan/LAP-EL551S-AEUR.yaml +167 -0
  27. package/api/vesyncfan/LAP-EL551S-AUS.yaml +167 -0
  28. package/api/vesyncfan/LAP-EL551S-WEU.yaml +167 -0
  29. package/api/vesyncfan/LAP-EL551S-WUS.yaml +167 -0
  30. package/api/vesyncfan/LAP-V102S-AASR.yaml +167 -0
  31. package/api/vesyncfan/LAP-V102S-AUSR.yaml +167 -0
  32. package/api/vesyncfan/LAP-V102S-WEU.yaml +167 -0
  33. package/api/vesyncfan/LAP-V102S-WJP.yaml +167 -0
  34. package/api/vesyncfan/LAP-V102S-WUS.yaml +167 -0
  35. package/api/vesyncfan/LAP-V201-AUSR.yaml +167 -0
  36. package/api/vesyncfan/LAP-V201S-AASR.yaml +167 -0
  37. package/api/vesyncfan/LAP-V201S-AEUR.yaml +167 -0
  38. package/api/vesyncfan/LAP-V201S-AUSR.yaml +167 -0
  39. package/api/vesyncfan/LAP-V201S-WEU.yaml +167 -0
  40. package/api/vesyncfan/LAP-V201S-WJP.yaml +167 -0
  41. package/api/vesyncfan/LAP-V201S-WUS.yaml +167 -0
  42. package/api/vesyncfan/LEH-S601S-WUS.yaml +303 -0
  43. package/api/vesyncfan/LEH-S601S-WUSR.yaml +82 -0
  44. package/api/vesyncfan/LTF-F422S-KEU.yaml +165 -0
  45. package/api/vesyncfan/LTF-F422S-WUS.yaml +165 -0
  46. package/api/vesyncfan/LTF-F422S-WUSR.yaml +167 -0
  47. package/api/vesyncfan/LTF-F422_WJP.yaml +165 -0
  48. package/api/vesyncfan/LUH-A601S-AUSW.yaml +82 -0
  49. package/api/vesyncfan/LUH-A601S-WUSB.yaml +305 -0
  50. package/api/vesyncfan/LUH-A602S-WEU.yaml +305 -0
  51. package/api/vesyncfan/LUH-A602S-WEUR.yaml +305 -0
  52. package/api/vesyncfan/LUH-A602S-WJP.yaml +305 -0
  53. package/api/vesyncfan/LUH-A602S-WUS.yaml +305 -0
  54. package/api/vesyncfan/LUH-A602S-WUSC.yaml +305 -0
  55. package/api/vesyncfan/LUH-A602S-WUSR.yaml +305 -0
  56. package/api/vesyncfan/LUH-D301S-WEU.yaml +305 -0
  57. package/api/vesyncfan/LUH-D301S-WJP.yaml +305 -0
  58. package/api/vesyncfan/LUH-D301S-WUSR.yaml +305 -0
  59. package/api/vesyncfan/LUH-M101S-WUS.yaml +278 -0
  60. package/api/vesyncfan/LUH-O451S-WEU.yaml +278 -0
  61. package/api/vesyncfan/LUH-O451S-WUS.yaml +278 -0
  62. package/api/vesyncfan/LUH-O451S-WUSR.yaml +305 -0
  63. package/api/vesyncfan/LUH-O601S-KUS.yaml +305 -0
  64. package/api/vesyncfan/LUH-O601S-WUS.yaml +305 -0
  65. package/api/vesyncfan/LV-PUR131S.yaml +108 -0
  66. package/api/vesyncfan/LV-RH131S.yaml +108 -0
  67. package/api/vesyncoutlet/ESO15-TB.yaml +124 -0
  68. package/api/vesyncoutlet/ESW01-EU.yaml +122 -0
  69. package/api/vesyncoutlet/ESW03-USA.yaml +122 -0
  70. package/api/vesyncoutlet/ESW15-USA.yaml +156 -0
  71. package/api/vesyncoutlet/wifi-switch-1.3.yaml +60 -0
  72. package/api/vesyncswitch/ESWD16.yaml +128 -0
  73. package/api/vesyncswitch/ESWL01.yaml +56 -0
  74. package/api/vesyncswitch/ESWL03.yaml +56 -0
  75. package/dist/lib/helpers.d.ts +87 -0
  76. package/dist/lib/helpers.js +222 -0
  77. package/dist/lib/helpers.js.map +1 -0
  78. package/dist/lib/vesync.d.ts +47 -0
  79. package/dist/lib/vesync.js +309 -0
  80. package/dist/lib/vesync.js.map +1 -0
  81. package/dist/lib/vesyncBaseDevice.d.ts +68 -0
  82. package/dist/lib/vesyncBaseDevice.js +116 -0
  83. package/dist/lib/vesyncBaseDevice.js.map +1 -0
  84. package/dist/lib/vesyncBulb.d.ts +0 -0
  85. package/dist/lib/vesyncBulb.js +2 -0
  86. package/dist/lib/vesyncBulb.js.map +1 -0
  87. package/dist/lib/vesyncFan.d.ts +92 -0
  88. package/dist/lib/vesyncFan.js +265 -0
  89. package/dist/lib/vesyncFan.js.map +1 -0
  90. package/dist/lib/vesyncKitchen.d.ts +0 -0
  91. package/dist/lib/vesyncKitchen.js +2 -0
  92. package/dist/lib/vesyncKitchen.js.map +1 -0
  93. package/dist/lib/vesyncOutlet.d.ts +0 -0
  94. package/dist/lib/vesyncOutlet.js +2 -0
  95. package/dist/lib/vesyncOutlet.js.map +1 -0
  96. package/dist/lib/vesyncSwitch.d.ts +0 -0
  97. package/dist/lib/vesyncSwitch.js +2 -0
  98. package/dist/lib/vesyncSwitch.js.map +1 -0
  99. package/dist/src/lib/helpers.d.ts +88 -0
  100. package/dist/src/lib/helpers.js +244 -0
  101. package/dist/src/lib/vesync.d.ts +89 -0
  102. package/dist/src/lib/vesync.js +430 -0
  103. package/dist/src/lib/vesyncBaseDevice.d.ts +43 -0
  104. package/dist/src/lib/vesyncBaseDevice.js +87 -0
  105. package/dist/src/lib/vesyncBulb.d.ts +79 -0
  106. package/dist/src/lib/vesyncBulb.js +198 -0
  107. package/dist/src/lib/vesyncBulbImpl.d.ts +38 -0
  108. package/dist/src/lib/vesyncBulbImpl.js +161 -0
  109. package/dist/src/lib/vesyncFan.d.ts +80 -0
  110. package/dist/src/lib/vesyncFan.js +406 -0
  111. package/dist/src/lib/vesyncFanImpl.d.ts +137 -0
  112. package/dist/src/lib/vesyncFanImpl.js +643 -0
  113. package/dist/src/lib/vesyncOutlet.d.ts +53 -0
  114. package/dist/src/lib/vesyncOutlet.js +98 -0
  115. package/dist/src/lib/vesyncOutletImpl.d.ts +70 -0
  116. package/dist/src/lib/vesyncOutletImpl.js +206 -0
  117. package/dist/src/lib/vesyncSwitch.d.ts +169 -0
  118. package/dist/src/lib/vesyncSwitch.js +414 -0
  119. package/dist/src/lib/vesyncSwitchImpl.d.ts +82 -0
  120. package/dist/src/lib/vesyncSwitchImpl.js +290 -0
  121. package/dist/test/testFeatures.d.ts +4 -0
  122. package/dist/test/testFeatures.js +394 -0
  123. package/dist/test/testService.d.ts +62 -0
  124. package/dist/test/testService.js +540 -0
  125. package/dist/test/testSpecial.d.ts +5 -0
  126. package/dist/test/testSpecial.js +227 -0
  127. package/package.json +53 -0
  128. package/src/lib/helpers.ts +290 -0
  129. package/src/lib/vesync.ts +530 -0
  130. package/src/lib/vesyncBaseDevice.ts +114 -0
  131. package/src/lib/vesyncBulb.ts +252 -0
  132. package/src/lib/vesyncBulbImpl.ts +215 -0
  133. package/src/lib/vesyncFan.ts +447 -0
  134. package/src/lib/vesyncFanImpl.ts +848 -0
  135. package/src/lib/vesyncOutlet.ts +148 -0
  136. package/src/lib/vesyncOutletImpl.ts +284 -0
  137. package/src/lib/vesyncSwitch.ts +546 -0
  138. package/src/lib/vesyncSwitchImpl.ts +408 -0
@@ -0,0 +1,89 @@
1
+ /**
2
+ * VeSync API Device Library
3
+ */
4
+ import { VeSyncBaseDevice } from './vesyncBaseDevice';
5
+ /**
6
+ * VeSync Manager Class
7
+ */
8
+ export declare class VeSync {
9
+ private _debug;
10
+ private _redact;
11
+ private _energyUpdateInterval;
12
+ private _energyCheck;
13
+ private _devList;
14
+ private _lastUpdateTs;
15
+ private _inProcess;
16
+ username: string;
17
+ password: string;
18
+ token: string | null;
19
+ accountId: string | null;
20
+ countryCode: string | null;
21
+ devices: VeSyncBaseDevice[] | null;
22
+ enabled: boolean;
23
+ updateInterval: number;
24
+ timeZone: string;
25
+ fans: VeSyncBaseDevice[];
26
+ outlets: VeSyncBaseDevice[];
27
+ switches: VeSyncBaseDevice[];
28
+ bulbs: VeSyncBaseDevice[];
29
+ scales: VeSyncBaseDevice[];
30
+ /**
31
+ * Initialize VeSync Manager
32
+ */
33
+ constructor(username: string, password: string, timeZone?: string, debug?: boolean, redact?: boolean);
34
+ /**
35
+ * Get/Set debug mode
36
+ */
37
+ get debug(): boolean;
38
+ set debug(flag: boolean);
39
+ /**
40
+ * Get/Set redact mode
41
+ */
42
+ get redact(): boolean;
43
+ set redact(flag: boolean);
44
+ /**
45
+ * Get/Set energy update interval
46
+ */
47
+ get energyUpdateInterval(): number;
48
+ set energyUpdateInterval(interval: number);
49
+ /**
50
+ * Test if device should be removed
51
+ */
52
+ static removeDevTest(device: VeSyncBaseDevice, newList: any[]): boolean;
53
+ /**
54
+ * Test if new device should be added
55
+ */
56
+ addDevTest(newDev: Record<string, any>): boolean;
57
+ /**
58
+ * Remove devices not found in device list return
59
+ */
60
+ removeOldDevices(devices: any[]): boolean;
61
+ /**
62
+ * Correct devices without cid or uuid
63
+ */
64
+ static setDevId(devices: any[]): any[];
65
+ /**
66
+ * Process device list and instantiate device objects
67
+ */
68
+ processDevices(devList: any[]): boolean;
69
+ /**
70
+ * Get list of VeSync devices
71
+ */
72
+ getDevices(): Promise<boolean>;
73
+ /**
74
+ * Login to VeSync server
75
+ */
76
+ login(): Promise<boolean>;
77
+ /**
78
+ * Test if update interval has been exceeded
79
+ */
80
+ deviceTimeCheck(): boolean;
81
+ /**
82
+ * Update device list and details
83
+ */
84
+ update(): Promise<void>;
85
+ /**
86
+ * Create device instance from details
87
+ */
88
+ createDevice(details: Record<string, any>): VeSyncBaseDevice | null;
89
+ }
@@ -0,0 +1,430 @@
1
+ "use strict";
2
+ /**
3
+ * VeSync API Device Library
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.VeSync = void 0;
7
+ const helpers_1 = require("./helpers");
8
+ const vesyncFanImpl_1 = require("./vesyncFanImpl");
9
+ const vesyncOutletImpl_1 = require("./vesyncOutletImpl");
10
+ const vesyncSwitchImpl_1 = require("./vesyncSwitchImpl");
11
+ const vesyncBulbImpl_1 = require("./vesyncBulbImpl");
12
+ const DEFAULT_ENERGY_UPDATE_INTERVAL = 21600;
13
+ /**
14
+ * Create device instance based on type
15
+ */
16
+ function objectFactory(details, manager) {
17
+ const deviceType = details.deviceType;
18
+ let DeviceClass = null;
19
+ let category = 'unknown';
20
+ // Map of device categories to their module dictionaries
21
+ const allModules = {
22
+ outlets: vesyncOutletImpl_1.outletModules,
23
+ fans: vesyncFanImpl_1.fanModules,
24
+ bulbs: vesyncBulbImpl_1.bulbModules,
25
+ switches: vesyncSwitchImpl_1.switchModules
26
+ };
27
+ // First try exact match in all modules
28
+ for (const [cat, modules] of Object.entries(allModules)) {
29
+ if (deviceType in modules) {
30
+ DeviceClass = modules[deviceType];
31
+ category = cat;
32
+ console.debug(`Found exact match for ${deviceType} in ${cat} modules`);
33
+ break;
34
+ }
35
+ }
36
+ // If no exact match, try to find a base class
37
+ if (!DeviceClass) {
38
+ // Device type prefix mapping
39
+ const prefixMap = {
40
+ // Fans
41
+ 'Core': 'fans',
42
+ 'LAP': 'fans',
43
+ 'LTF': 'fans',
44
+ 'Classic': 'fans',
45
+ 'Dual': 'fans',
46
+ 'LUH': 'fans',
47
+ 'LEH': 'fans',
48
+ 'LV-PUR': 'fans',
49
+ 'LV-RH': 'fans',
50
+ // Outlets
51
+ 'wifi-switch': 'outlets',
52
+ 'ESW03': 'outlets',
53
+ 'ESW01': 'outlets',
54
+ 'ESW15': 'outlets',
55
+ 'ESO': 'outlets',
56
+ // Switches
57
+ 'ESWL': 'switches',
58
+ 'ESWD': 'switches',
59
+ // Bulbs
60
+ 'ESL': 'bulbs',
61
+ 'XYD': 'bulbs'
62
+ };
63
+ // Find category based on device type prefix
64
+ for (const [prefix, cat] of Object.entries(prefixMap)) {
65
+ if (deviceType.startsWith(prefix)) {
66
+ category = cat;
67
+ console.debug(`Device type ${deviceType} matched prefix ${prefix} -> category ${cat}`);
68
+ // Try to find a base class in this category's modules
69
+ const modules = allModules[cat];
70
+ for (const [moduleType, ModuleClass] of Object.entries(modules)) {
71
+ const baseType = moduleType.split('-')[0]; // e.g., ESL100 from ESL100-USA
72
+ if (deviceType.startsWith(baseType)) {
73
+ DeviceClass = ModuleClass;
74
+ console.debug(`Found base type match: ${deviceType} -> ${baseType}`);
75
+ break;
76
+ }
77
+ }
78
+ break;
79
+ }
80
+ }
81
+ }
82
+ if (DeviceClass) {
83
+ try {
84
+ // Add category to device details
85
+ details.deviceCategory = category;
86
+ const device = new DeviceClass(details, manager);
87
+ return [category, device];
88
+ }
89
+ catch (error) {
90
+ console.error(`Error creating device instance for ${deviceType}:`, error);
91
+ return [category, null];
92
+ }
93
+ }
94
+ else {
95
+ console.warn(`No device class found for type: ${deviceType}`);
96
+ return [category, null];
97
+ }
98
+ }
99
+ /**
100
+ * VeSync Manager Class
101
+ */
102
+ class VeSync {
103
+ /**
104
+ * Initialize VeSync Manager
105
+ */
106
+ constructor(username, password, timeZone = helpers_1.DEFAULT_TZ, debug = false, redact = true) {
107
+ this._debug = debug;
108
+ this._redact = redact;
109
+ this._energyUpdateInterval = DEFAULT_ENERGY_UPDATE_INTERVAL;
110
+ this._energyCheck = true;
111
+ this._lastUpdateTs = null;
112
+ this._inProcess = false;
113
+ this.username = username;
114
+ this.password = password;
115
+ this.token = null;
116
+ this.accountId = null;
117
+ this.countryCode = null;
118
+ this.devices = null;
119
+ this.enabled = false;
120
+ this.updateInterval = helpers_1.API_RATE_LIMIT;
121
+ this.fans = [];
122
+ this.outlets = [];
123
+ this.switches = [];
124
+ this.bulbs = [];
125
+ this.scales = [];
126
+ this._devList = {
127
+ fans: this.fans,
128
+ outlets: this.outlets,
129
+ switches: this.switches,
130
+ bulbs: this.bulbs
131
+ };
132
+ if (typeof timeZone === 'string' && timeZone) {
133
+ const regTest = /[^a-zA-Z/_]/;
134
+ if (regTest.test(timeZone)) {
135
+ this.timeZone = helpers_1.DEFAULT_TZ;
136
+ console.debug('Invalid characters in time zone - ', timeZone);
137
+ }
138
+ else {
139
+ this.timeZone = timeZone;
140
+ }
141
+ }
142
+ else {
143
+ this.timeZone = helpers_1.DEFAULT_TZ;
144
+ console.debug('Time zone is not a string');
145
+ }
146
+ if (debug) {
147
+ this.debug = true;
148
+ }
149
+ if (redact) {
150
+ this.redact = true;
151
+ }
152
+ }
153
+ /**
154
+ * Get/Set debug mode
155
+ */
156
+ get debug() {
157
+ return this._debug;
158
+ }
159
+ set debug(flag) {
160
+ this._debug = flag;
161
+ }
162
+ /**
163
+ * Get/Set redact mode
164
+ */
165
+ get redact() {
166
+ return this._redact;
167
+ }
168
+ set redact(flag) {
169
+ this._redact = flag;
170
+ helpers_1.Helpers.shouldRedact = flag;
171
+ }
172
+ /**
173
+ * Get/Set energy update interval
174
+ */
175
+ get energyUpdateInterval() {
176
+ return this._energyUpdateInterval;
177
+ }
178
+ set energyUpdateInterval(interval) {
179
+ if (interval > 0) {
180
+ this._energyUpdateInterval = interval;
181
+ }
182
+ }
183
+ /**
184
+ * Test if device should be removed
185
+ */
186
+ static removeDevTest(device, newList) {
187
+ if (Array.isArray(newList) && device.cid) {
188
+ for (const item of newList) {
189
+ if ('cid' in item && device.cid === item.cid) {
190
+ return true;
191
+ }
192
+ }
193
+ console.debug(`Device removed - ${device.deviceName} - ${device.deviceType}`);
194
+ return false;
195
+ }
196
+ return true;
197
+ }
198
+ /**
199
+ * Test if new device should be added
200
+ */
201
+ addDevTest(newDev) {
202
+ if ('cid' in newDev) {
203
+ for (const devices of Object.values(this._devList)) {
204
+ for (const dev of devices) {
205
+ if (dev.cid === newDev.cid) {
206
+ return false;
207
+ }
208
+ }
209
+ }
210
+ }
211
+ return true;
212
+ }
213
+ /**
214
+ * Remove devices not found in device list return
215
+ */
216
+ removeOldDevices(devices) {
217
+ for (const [key, deviceList] of Object.entries(this._devList)) {
218
+ const before = deviceList.length;
219
+ this._devList[key] = deviceList.filter(device => VeSync.removeDevTest(device, devices));
220
+ const after = this._devList[key].length;
221
+ if (before !== after) {
222
+ console.debug(`${before - after} ${key} removed`);
223
+ }
224
+ }
225
+ return true;
226
+ }
227
+ /**
228
+ * Correct devices without cid or uuid
229
+ */
230
+ static setDevId(devices) {
231
+ const devRem = [];
232
+ devices.forEach((dev, index) => {
233
+ if (!dev.cid) {
234
+ if (dev.macID) {
235
+ dev.cid = dev.macID;
236
+ }
237
+ else if (dev.uuid) {
238
+ dev.cid = dev.uuid;
239
+ }
240
+ else {
241
+ devRem.push(index);
242
+ console.warn(`Device with no ID - ${dev.deviceName || ''}`);
243
+ }
244
+ }
245
+ });
246
+ if (devRem.length > 0) {
247
+ return devices.filter((_, index) => !devRem.includes(index));
248
+ }
249
+ return devices;
250
+ }
251
+ /**
252
+ * Process device list and instantiate device objects
253
+ */
254
+ processDevices(devList) {
255
+ // Ensure devices have proper IDs
256
+ const devices = VeSync.setDevId(devList);
257
+ // Count current devices
258
+ let numDevices = 0;
259
+ for (const deviceList of Object.values(this._devList)) {
260
+ numDevices += deviceList.length;
261
+ }
262
+ if (!devices || devices.length === 0) {
263
+ console.warn('No devices found in api return');
264
+ return false;
265
+ }
266
+ // Initialize new device list or remove old devices
267
+ if (numDevices === 0) {
268
+ console.debug('New device list initialized');
269
+ }
270
+ else {
271
+ this.removeOldDevices(devices);
272
+ }
273
+ // Filter out devices that already exist
274
+ const newDevices = devices.filter(dev => this.addDevTest(dev));
275
+ // Required keys for device instantiation
276
+ const requiredKeys = ['deviceType', 'deviceName', 'deviceStatus', 'cid'];
277
+ // Process each new device
278
+ for (const dev of newDevices) {
279
+ // Verify required device properties
280
+ if (!requiredKeys.every(key => key in dev)) {
281
+ console.debug(`Error adding device - missing required properties: ${dev.deviceName || 'Unknown'}`);
282
+ continue;
283
+ }
284
+ const devType = dev.deviceType;
285
+ try {
286
+ // Create device instance using factory
287
+ const [category, deviceObj] = objectFactory(dev, this);
288
+ // Add device to appropriate category if valid
289
+ if (deviceObj && category in this._devList) {
290
+ this._devList[category].push(deviceObj);
291
+ console.debug(`Added ${devType} device to ${category} category`);
292
+ }
293
+ else if (category === 'unknown') {
294
+ console.debug(`Unknown device type: ${devType}`);
295
+ }
296
+ }
297
+ catch (err) {
298
+ console.error(`Error creating device ${devType}:`, err);
299
+ continue;
300
+ }
301
+ }
302
+ return true;
303
+ }
304
+ /**
305
+ * Get list of VeSync devices
306
+ */
307
+ async getDevices() {
308
+ if (!this.enabled) {
309
+ console.error('Not logged in to VeSync');
310
+ return false;
311
+ }
312
+ this._inProcess = true;
313
+ let procReturn = false;
314
+ try {
315
+ const [response] = await helpers_1.Helpers.callApi('/cloud/v2/deviceManaged/devices', 'post', helpers_1.Helpers.reqBody(this, 'devicelist'), helpers_1.Helpers.reqHeaders(this));
316
+ if (response?.result?.list) {
317
+ const deviceList = response.result.list;
318
+ procReturn = this.processDevices(deviceList);
319
+ // Update the main devices array with all devices
320
+ this.devices = Object.values(this._devList).flat();
321
+ // Log device discovery results
322
+ console.log('\n=== Device Discovery Summary ===');
323
+ console.log(`Total devices processed: ${deviceList.length}`);
324
+ // Log device types found
325
+ const deviceTypes = deviceList.map((d) => d.deviceType);
326
+ console.log('\nDevice types found:', deviceTypes);
327
+ // Log devices by category with details
328
+ console.log('\nDevices by Category:');
329
+ console.log('---------------------');
330
+ for (const [category, devices] of Object.entries(this._devList)) {
331
+ if (devices.length > 0) {
332
+ console.log(`\n${category.toUpperCase()} (${devices.length} devices):`);
333
+ devices.forEach((d) => {
334
+ console.log(` • ${d.deviceName}`);
335
+ console.log(` Type: ${d.deviceType}`);
336
+ console.log(` Status: ${d.deviceStatus}`);
337
+ console.log(` ID: ${d.cid}`);
338
+ });
339
+ }
340
+ }
341
+ // Log summary statistics
342
+ console.log('\nSummary Statistics:');
343
+ console.log('-------------------');
344
+ console.log(`Total Devices: ${this.devices?.length || 0}`);
345
+ for (const [category, devices] of Object.entries(this._devList)) {
346
+ console.log(`${category}: ${devices.length} devices`);
347
+ }
348
+ console.log('\n=== End of Device Discovery ===\n');
349
+ }
350
+ else {
351
+ console.error('No devices found in response');
352
+ }
353
+ }
354
+ catch (error) {
355
+ console.error('Unable to get device list:', error);
356
+ }
357
+ this._inProcess = false;
358
+ return procReturn;
359
+ }
360
+ /**
361
+ * Login to VeSync server
362
+ */
363
+ async login() {
364
+ const body = helpers_1.Helpers.reqBody(this, 'login');
365
+ console.log('Login request:', {
366
+ url: `${process.env.VESYNC_API_URL}/cloud/v1/user/login`,
367
+ body
368
+ });
369
+ try {
370
+ const [response, status] = await helpers_1.Helpers.callApi('/cloud/v1/user/login', 'post', body);
371
+ console.log('Login response:', { status, response });
372
+ if (response?.result?.token) {
373
+ this.token = response.result.token;
374
+ this.accountId = response.result.accountID;
375
+ this.countryCode = response.result.countryCode;
376
+ this.enabled = true;
377
+ return true;
378
+ }
379
+ console.error('Unable to login with supplied credentials');
380
+ return false;
381
+ }
382
+ catch (error) {
383
+ console.error('Login error:', error);
384
+ return false;
385
+ }
386
+ }
387
+ /**
388
+ * Test if update interval has been exceeded
389
+ */
390
+ deviceTimeCheck() {
391
+ return (this._lastUpdateTs === null ||
392
+ (Date.now() - this._lastUpdateTs) / 1000 > this.updateInterval);
393
+ }
394
+ /**
395
+ * Update device list and details
396
+ */
397
+ async update() {
398
+ if (this.deviceTimeCheck()) {
399
+ if (!this.enabled) {
400
+ console.error('Not logged in to VeSync');
401
+ return;
402
+ }
403
+ await this.getDevices();
404
+ console.debug('Start updating the device details one by one');
405
+ for (const deviceList of Object.values(this._devList)) {
406
+ for (const device of deviceList) {
407
+ try {
408
+ await device.getDetails();
409
+ }
410
+ catch (error) {
411
+ console.error(`Error updating ${device.deviceName}:`, error);
412
+ }
413
+ }
414
+ }
415
+ this._lastUpdateTs = Date.now();
416
+ }
417
+ }
418
+ /**
419
+ * Create device instance from details
420
+ */
421
+ createDevice(details) {
422
+ const deviceType = details.deviceType;
423
+ const deviceClass = vesyncFanImpl_1.fanModules[deviceType];
424
+ if (deviceClass) {
425
+ return new deviceClass(details, this);
426
+ }
427
+ return null;
428
+ }
429
+ }
430
+ exports.VeSync = VeSync;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Base class for VeSync devices
3
+ */
4
+ import { VeSync } from './vesync';
5
+ export declare abstract class VeSyncBaseDevice {
6
+ protected manager: VeSync;
7
+ protected config: Record<string, any>;
8
+ cid: string;
9
+ deviceName: string;
10
+ deviceStatus: string;
11
+ deviceType: string;
12
+ deviceRegion: string;
13
+ uuid: string;
14
+ configModule: string;
15
+ macId: string;
16
+ deviceCategory: string;
17
+ connectionStatus: string;
18
+ constructor(details: Record<string, any>, manager: VeSync);
19
+ /**
20
+ * Return formatted device info to stdout
21
+ */
22
+ display(): void;
23
+ /**
24
+ * Return JSON details for device
25
+ */
26
+ displayJSON(): string;
27
+ /**
28
+ * Check API response for errors
29
+ */
30
+ protected checkResponse(response: [any, number], method: string): boolean;
31
+ /**
32
+ * Log error with context
33
+ */
34
+ protected logError(method: string, error: any): void;
35
+ /**
36
+ * Get device details
37
+ */
38
+ abstract getDetails(): Promise<void>;
39
+ /**
40
+ * Update device details
41
+ */
42
+ update(): Promise<void>;
43
+ }
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ /**
3
+ * Base class for VeSync devices
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.VeSyncBaseDevice = void 0;
7
+ class VeSyncBaseDevice {
8
+ constructor(details, manager) {
9
+ this.config = {};
10
+ this.manager = manager;
11
+ this.cid = details.cid || '';
12
+ this.deviceName = details.deviceName || '';
13
+ this.deviceStatus = details.deviceStatus || 'off';
14
+ this.deviceType = details.deviceType || '';
15
+ this.deviceRegion = details.deviceRegion || '';
16
+ this.uuid = details.uuid || '';
17
+ this.configModule = details.configModule || '';
18
+ this.macId = details.macId || '';
19
+ this.deviceCategory = details.deviceCategory || '';
20
+ this.connectionStatus = details.connectionStatus || 'offline';
21
+ }
22
+ /**
23
+ * Return formatted device info to stdout
24
+ */
25
+ display() {
26
+ console.log(`Device Name: ${this.deviceName}`);
27
+ console.log(`Status: ${this.deviceStatus}`);
28
+ console.log(`Device Type: ${this.deviceType}`);
29
+ console.log(`Connection: ${this.connectionStatus}`);
30
+ console.log(`Version: ${this.config.current_firmware_version || 'Unknown'}`);
31
+ }
32
+ /**
33
+ * Return JSON details for device
34
+ */
35
+ displayJSON() {
36
+ return JSON.stringify({
37
+ 'Device Name': this.deviceName,
38
+ 'Status': this.deviceStatus,
39
+ 'Device Type': this.deviceType,
40
+ 'Connection': this.connectionStatus,
41
+ 'Version': this.config.current_firmware_version || 'Unknown'
42
+ }, null, 4);
43
+ }
44
+ /**
45
+ * Check API response for errors
46
+ */
47
+ checkResponse(response, method) {
48
+ const [data, status] = response;
49
+ // Check HTTP status
50
+ if (status !== 200) {
51
+ this.logError(method, `Invalid HTTP status: ${status}`);
52
+ return false;
53
+ }
54
+ // Check API response
55
+ if (!data) {
56
+ this.logError(method, 'No response data');
57
+ return false;
58
+ }
59
+ // Check error code - code 0 indicates success
60
+ if (data.code === 0) {
61
+ return true;
62
+ }
63
+ const msg = data.msg || 'Unknown error';
64
+ this.logError(method, `Error code ${data.code}: ${msg}`);
65
+ return false;
66
+ }
67
+ /**
68
+ * Log error with context
69
+ */
70
+ logError(method, error) {
71
+ const errorMsg = error?.message || error;
72
+ console.error(`[${this.deviceName}] ${method}: ${errorMsg}`);
73
+ // Log additional error details if available
74
+ if (error?.response?.data) {
75
+ const responseData = error.response.data;
76
+ const msg = responseData.msg || responseData.message || JSON.stringify(responseData);
77
+ console.error(`Response: ${msg}`);
78
+ }
79
+ }
80
+ /**
81
+ * Update device details
82
+ */
83
+ async update() {
84
+ await this.getDetails();
85
+ }
86
+ }
87
+ exports.VeSyncBaseDevice = VeSyncBaseDevice;