tsvesync 1.0.33 → 1.0.35

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.
@@ -0,0 +1,278 @@
1
+ automatic_stop_off:
2
+ headers:
3
+ Content-Type: application/json; charset=UTF-8
4
+ User-Agent: okhttp/3.12.1
5
+ json_object:
6
+ acceptLanguage: en
7
+ accountID: sample_id
8
+ appVersion: 2.8.6
9
+ cid: LUH-M101S-WEUR-CID
10
+ configModule: ConfigModule
11
+ debugMode: false
12
+ deviceRegion: EU
13
+ method: bypassV2
14
+ payload:
15
+ data:
16
+ autoStopSwitch: 0
17
+ method: setAutoStopSwitch
18
+ source: APP
19
+ phoneBrand: SM N9005
20
+ phoneOS: Android
21
+ timeZone: America/New_York
22
+ token: sample_tk
23
+ traceId: TRACE_ID
24
+ method: post
25
+ url: /cloud/v2/deviceManaged/bypassV2
26
+ automatic_stop_on:
27
+ headers:
28
+ Content-Type: application/json; charset=UTF-8
29
+ User-Agent: okhttp/3.12.1
30
+ json_object:
31
+ acceptLanguage: en
32
+ accountID: sample_id
33
+ appVersion: 2.8.6
34
+ cid: LUH-M101S-WEUR-CID
35
+ configModule: ConfigModule
36
+ debugMode: false
37
+ deviceRegion: EU
38
+ method: bypassV2
39
+ payload:
40
+ data:
41
+ autoStopSwitch: 1
42
+ method: setAutoStopSwitch
43
+ source: APP
44
+ phoneBrand: SM N9005
45
+ phoneOS: Android
46
+ timeZone: America/New_York
47
+ token: sample_tk
48
+ traceId: TRACE_ID
49
+ method: post
50
+ url: /cloud/v2/deviceManaged/bypassV2
51
+ set_auto_mode:
52
+ headers:
53
+ Content-Type: application/json; charset=UTF-8
54
+ User-Agent: okhttp/3.12.1
55
+ json_object:
56
+ acceptLanguage: en
57
+ accountID: sample_id
58
+ appVersion: 2.8.6
59
+ cid: LUH-M101S-WEUR-CID
60
+ configModule: ConfigModule
61
+ debugMode: false
62
+ deviceRegion: EU
63
+ method: bypassV2
64
+ payload:
65
+ data:
66
+ workMode: auto
67
+ method: setHumidityMode
68
+ source: APP
69
+ phoneBrand: SM N9005
70
+ phoneOS: Android
71
+ timeZone: America/New_York
72
+ token: sample_tk
73
+ traceId: TRACE_ID
74
+ method: post
75
+ url: /cloud/v2/deviceManaged/bypassV2
76
+ set_humidity:
77
+ headers:
78
+ Content-Type: application/json; charset=UTF-8
79
+ User-Agent: okhttp/3.12.1
80
+ json_object:
81
+ acceptLanguage: en
82
+ accountID: sample_id
83
+ appVersion: 2.8.6
84
+ cid: LUH-M101S-WEUR-CID
85
+ configModule: ConfigModule
86
+ debugMode: false
87
+ deviceRegion: EU
88
+ method: bypassV2
89
+ payload:
90
+ data:
91
+ targetHumidity: 50
92
+ method: setTargetHumidity
93
+ source: APP
94
+ phoneBrand: SM N9005
95
+ phoneOS: Android
96
+ timeZone: America/New_York
97
+ token: sample_tk
98
+ traceId: TRACE_ID
99
+ method: post
100
+ url: /cloud/v2/deviceManaged/bypassV2
101
+ set_manual_mode:
102
+ headers:
103
+ Content-Type: application/json; charset=UTF-8
104
+ User-Agent: okhttp/3.12.1
105
+ json_object:
106
+ acceptLanguage: en
107
+ accountID: sample_id
108
+ appVersion: 2.8.6
109
+ cid: LUH-M101S-WEUR-CID
110
+ configModule: ConfigModule
111
+ debugMode: false
112
+ deviceRegion: EU
113
+ method: bypassV2
114
+ payload:
115
+ data:
116
+ workMode: manual
117
+ method: setHumidityMode
118
+ source: APP
119
+ phoneBrand: SM N9005
120
+ phoneOS: Android
121
+ timeZone: America/New_York
122
+ token: sample_tk
123
+ traceId: TRACE_ID
124
+ method: post
125
+ url: /cloud/v2/deviceManaged/bypassV2
126
+ set_mist_level:
127
+ headers:
128
+ Content-Type: application/json; charset=UTF-8
129
+ User-Agent: okhttp/3.12.1
130
+ json_object:
131
+ acceptLanguage: en
132
+ accountID: sample_id
133
+ appVersion: 2.8.6
134
+ cid: LUH-M101S-WEUR-CID
135
+ configModule: ConfigModule
136
+ debugMode: false
137
+ deviceRegion: EU
138
+ method: bypassV2
139
+ payload:
140
+ data:
141
+ levelIdx: 0
142
+ levelType: mist
143
+ virtualLevel: 2
144
+ method: setVirtualLevel
145
+ source: APP
146
+ phoneBrand: SM N9005
147
+ phoneOS: Android
148
+ timeZone: America/New_York
149
+ token: sample_tk
150
+ traceId: TRACE_ID
151
+ method: post
152
+ url: /cloud/v2/deviceManaged/bypassV2
153
+ turn_off:
154
+ headers:
155
+ Content-Type: application/json; charset=UTF-8
156
+ User-Agent: okhttp/3.12.1
157
+ json_object:
158
+ acceptLanguage: en
159
+ accountID: sample_id
160
+ appVersion: 2.8.6
161
+ cid: LUH-M101S-WEUR-CID
162
+ configModule: ConfigModule
163
+ debugMode: false
164
+ deviceRegion: EU
165
+ method: bypassV2
166
+ payload:
167
+ data:
168
+ powerSwitch: 0
169
+ switchIdx: 0
170
+ method: setSwitch
171
+ source: APP
172
+ phoneBrand: SM N9005
173
+ phoneOS: Android
174
+ timeZone: America/New_York
175
+ token: sample_tk
176
+ traceId: TRACE_ID
177
+ method: post
178
+ url: /cloud/v2/deviceManaged/bypassV2
179
+ turn_off_display:
180
+ headers:
181
+ Content-Type: application/json; charset=UTF-8
182
+ User-Agent: okhttp/3.12.1
183
+ json_object:
184
+ acceptLanguage: en
185
+ accountID: sample_id
186
+ appVersion: 2.8.6
187
+ cid: LUH-M101S-WEUR-CID
188
+ configModule: ConfigModule
189
+ debugMode: false
190
+ deviceRegion: EU
191
+ method: bypassV2
192
+ payload:
193
+ data:
194
+ screenSwitch: 0
195
+ method: setDisplay
196
+ source: APP
197
+ phoneBrand: SM N9005
198
+ phoneOS: Android
199
+ timeZone: America/New_York
200
+ token: sample_tk
201
+ traceId: TRACE_ID
202
+ method: post
203
+ url: /cloud/v2/deviceManaged/bypassV2
204
+ turn_on:
205
+ headers:
206
+ Content-Type: application/json; charset=UTF-8
207
+ User-Agent: okhttp/3.12.1
208
+ json_object:
209
+ acceptLanguage: en
210
+ accountID: sample_id
211
+ appVersion: 2.8.6
212
+ cid: LUH-M101S-WEUR-CID
213
+ configModule: ConfigModule
214
+ debugMode: false
215
+ deviceRegion: EU
216
+ method: bypassV2
217
+ payload:
218
+ data:
219
+ powerSwitch: 1
220
+ switchIdx: 0
221
+ method: setSwitch
222
+ source: APP
223
+ phoneBrand: SM N9005
224
+ phoneOS: Android
225
+ timeZone: America/New_York
226
+ token: sample_tk
227
+ traceId: TRACE_ID
228
+ method: post
229
+ url: /cloud/v2/deviceManaged/bypassV2
230
+ turn_on_display:
231
+ headers:
232
+ Content-Type: application/json; charset=UTF-8
233
+ User-Agent: okhttp/3.12.1
234
+ json_object:
235
+ acceptLanguage: en
236
+ accountID: sample_id
237
+ appVersion: 2.8.6
238
+ cid: LUH-M101S-WEUR-CID
239
+ configModule: ConfigModule
240
+ debugMode: false
241
+ deviceRegion: EU
242
+ method: bypassV2
243
+ payload:
244
+ data:
245
+ screenSwitch: 1
246
+ method: setDisplay
247
+ source: APP
248
+ phoneBrand: SM N9005
249
+ phoneOS: Android
250
+ timeZone: America/New_York
251
+ token: sample_tk
252
+ traceId: TRACE_ID
253
+ method: post
254
+ url: /cloud/v2/deviceManaged/bypassV2
255
+ update:
256
+ headers:
257
+ Content-Type: application/json; charset=UTF-8
258
+ User-Agent: okhttp/3.12.1
259
+ json_object:
260
+ acceptLanguage: en
261
+ accountID: sample_id
262
+ appVersion: 2.8.6
263
+ cid: LUH-M101S-WEUR-CID
264
+ configModule: ConfigModule
265
+ debugMode: false
266
+ deviceRegion: EU
267
+ method: bypassV2
268
+ payload:
269
+ data: {}
270
+ method: getHumidifierStatus
271
+ source: APP
272
+ phoneBrand: SM N9005
273
+ phoneOS: Android
274
+ timeZone: America/New_York
275
+ token: sample_tk
276
+ traceId: TRACE_ID
277
+ method: post
278
+ url: /cloud/v2/deviceManaged/bypassV2
@@ -81,7 +81,7 @@ export declare class VeSync {
81
81
  /**
82
82
  * Login to VeSync server
83
83
  */
84
- login(): Promise<boolean>;
84
+ login(retryAttempts?: number, initialDelayMs?: number): Promise<boolean>;
85
85
  /**
86
86
  * Test if update interval has been exceeded
87
87
  */
@@ -385,30 +385,41 @@ class VeSync {
385
385
  /**
386
386
  * Login to VeSync server
387
387
  */
388
- async login() {
388
+ async login(retryAttempts = 3, initialDelayMs = 1000) {
389
389
  var _a;
390
390
  const body = helpers_1.Helpers.reqBody(this, 'login');
391
391
  logger_1.logger.debug('Login request:', {
392
392
  url: `${process.env.VESYNC_API_URL}/cloud/v1/user/login`,
393
393
  body
394
394
  });
395
- try {
396
- const [response, status] = await helpers_1.Helpers.callApi('/cloud/v1/user/login', 'post', body, {}, this);
397
- logger_1.logger.debug('Login response:', { status, response });
398
- if ((_a = response === null || response === void 0 ? void 0 : response.result) === null || _a === void 0 ? void 0 : _a.token) {
399
- this.token = response.result.token;
400
- this.accountId = response.result.accountID;
401
- this.countryCode = response.result.countryCode;
402
- this.enabled = true;
403
- return true;
395
+ for (let attempt = 0; attempt < retryAttempts; attempt++) {
396
+ try {
397
+ const [response, status] = await helpers_1.Helpers.callApi('/cloud/v1/user/login', 'post', body, {}, this);
398
+ logger_1.logger.debug('Login response:', { status, response });
399
+ if ((_a = response === null || response === void 0 ? void 0 : response.result) === null || _a === void 0 ? void 0 : _a.token) {
400
+ this.token = response.result.token;
401
+ this.accountId = response.result.accountID;
402
+ this.countryCode = response.result.countryCode;
403
+ this.enabled = true;
404
+ return true;
405
+ }
406
+ // If we reach here, login failed but didn't throw an error
407
+ const delay = initialDelayMs * Math.pow(2, attempt);
408
+ logger_1.logger.debug(`Login attempt ${attempt + 1} failed, retrying in ${delay}ms...`);
409
+ await new Promise(resolve => setTimeout(resolve, delay));
410
+ }
411
+ catch (error) {
412
+ if (attempt === retryAttempts - 1) {
413
+ logger_1.logger.error('Login error after all retry attempts:', error);
414
+ return false;
415
+ }
416
+ const delay = initialDelayMs * Math.pow(2, attempt);
417
+ logger_1.logger.debug(`Login attempt ${attempt + 1} failed with error, retrying in ${delay}ms...`, error);
418
+ await new Promise(resolve => setTimeout(resolve, delay));
404
419
  }
405
- logger_1.logger.error('Unable to login with supplied credentials');
406
- return false;
407
- }
408
- catch (error) {
409
- logger_1.logger.error('Login error:', error);
410
- return false;
411
420
  }
421
+ logger_1.logger.error('Unable to login with supplied credentials after all retry attempts');
422
+ return false;
412
423
  }
413
424
  /**
414
425
  * Test if update interval has been exceeded
@@ -234,6 +234,10 @@ exports.fanConfig = {
234
234
  module: 'VeSyncWarmHumidifier',
235
235
  features: ['display', 'humidity', 'mist', 'warm', 'timer', 'auto_mode']
236
236
  },
237
+ 'LUH-M101S-WEUR': {
238
+ module: 'VeSyncWarmHumidifier',
239
+ features: ['display', 'humidity', 'mist', 'warm', 'timer', 'auto_mode']
240
+ },
237
241
  // LEH Series
238
242
  'LEH-S601S-WUS': {
239
243
  module: 'VeSyncWarmHumidifier',
@@ -917,6 +917,7 @@ exports.fanModules = {
917
917
  'LUH-O601S-WUS': VeSyncWarmHumidifier,
918
918
  'LUH-O601S-KUS': VeSyncWarmHumidifier,
919
919
  'LUH-M101S-WUS': VeSyncWarmHumidifier,
920
+ 'LUH-M101S-WEUR': VeSyncWarmHumidifier,
920
921
  // LEH Series
921
922
  'LEH-S601S-WUS': VeSyncWarmHumidifier,
922
923
  'LEH-S601S-WUSR': VeSyncWarmHumidifier,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsvesync",
3
- "version": "1.0.33",
3
+ "version": "1.0.35",
4
4
  "description": "A TypeScript library for interacting with VeSync smart home devices",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/lib/vesync.ts CHANGED
@@ -469,38 +469,52 @@ export class VeSync {
469
469
  /**
470
470
  * Login to VeSync server
471
471
  */
472
- async login(): Promise<boolean> {
472
+ async login(retryAttempts: number = 3, initialDelayMs: number = 1000): Promise<boolean> {
473
473
  const body = Helpers.reqBody(this, 'login');
474
474
  logger.debug('Login request:', {
475
475
  url: `${process.env.VESYNC_API_URL}/cloud/v1/user/login`,
476
476
  body
477
477
  });
478
478
 
479
- try {
480
- const [response, status] = await Helpers.callApi(
481
- '/cloud/v1/user/login',
482
- 'post',
483
- body,
484
- {},
485
- this
486
- );
487
-
488
- logger.debug('Login response:', { status, response });
479
+ for (let attempt = 0; attempt < retryAttempts; attempt++) {
480
+ try {
481
+ const [response, status] = await Helpers.callApi(
482
+ '/cloud/v1/user/login',
483
+ 'post',
484
+ body,
485
+ {},
486
+ this
487
+ );
488
+
489
+ logger.debug('Login response:', { status, response });
490
+
491
+ if (response?.result?.token) {
492
+ this.token = response.result.token;
493
+ this.accountId = response.result.accountID;
494
+ this.countryCode = response.result.countryCode;
495
+ this.enabled = true;
496
+ return true;
497
+ }
489
498
 
490
- if (response?.result?.token) {
491
- this.token = response.result.token;
492
- this.accountId = response.result.accountID;
493
- this.countryCode = response.result.countryCode;
494
- this.enabled = true;
495
- return true;
499
+ // If we reach here, login failed but didn't throw an error
500
+ const delay = initialDelayMs * Math.pow(2, attempt);
501
+ logger.debug(`Login attempt ${attempt + 1} failed, retrying in ${delay}ms...`);
502
+ await new Promise(resolve => setTimeout(resolve, delay));
503
+
504
+ } catch (error) {
505
+ if (attempt === retryAttempts - 1) {
506
+ logger.error('Login error after all retry attempts:', error);
507
+ return false;
508
+ }
509
+
510
+ const delay = initialDelayMs * Math.pow(2, attempt);
511
+ logger.debug(`Login attempt ${attempt + 1} failed with error, retrying in ${delay}ms...`, error);
512
+ await new Promise(resolve => setTimeout(resolve, delay));
496
513
  }
497
-
498
- logger.error('Unable to login with supplied credentials');
499
- return false;
500
- } catch (error) {
501
- logger.error('Login error:', error);
502
- return false;
503
514
  }
515
+
516
+ logger.error('Unable to login with supplied credentials after all retry attempts');
517
+ return false;
504
518
  }
505
519
 
506
520
  /**
@@ -246,6 +246,10 @@ export const fanConfig: FanConfig = {
246
246
  module: 'VeSyncWarmHumidifier',
247
247
  features: ['display', 'humidity', 'mist', 'warm', 'timer', 'auto_mode']
248
248
  },
249
+ 'LUH-M101S-WEUR': {
250
+ module: 'VeSyncWarmHumidifier',
251
+ features: ['display', 'humidity', 'mist', 'warm', 'timer', 'auto_mode']
252
+ },
249
253
 
250
254
  // LEH Series
251
255
  'LEH-S601S-WUS': {
@@ -1129,6 +1129,7 @@ export const fanModules: Record<string, new (details: Record<string, any>, manag
1129
1129
  'LUH-O601S-WUS': VeSyncWarmHumidifier,
1130
1130
  'LUH-O601S-KUS': VeSyncWarmHumidifier,
1131
1131
  'LUH-M101S-WUS': VeSyncWarmHumidifier,
1132
+ 'LUH-M101S-WEUR': VeSyncWarmHumidifier,
1132
1133
 
1133
1134
  // LEH Series
1134
1135
  'LEH-S601S-WUS': VeSyncWarmHumidifier,