tsvesync 1.0.67 → 1.0.69

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.
@@ -213,6 +213,44 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
213
213
  // return false;
214
214
  // }
215
215
  logger_1.logger.info(`Changing fan speed to ${speed} for device: ${this.deviceName}`);
216
+ // Special handling for LV series
217
+ if (this.deviceType.startsWith('LV-')) {
218
+ // Check if device is in manual mode
219
+ if (this.details.mode !== 'manual') {
220
+ logger_1.logger.debug(`${this.deviceName} not in manual mode, cannot change speed`);
221
+ return false;
222
+ }
223
+ // Validate speed for LV series (1-3)
224
+ if (speed < 1 || speed > 3) {
225
+ logger_1.logger.error(`Invalid fan speed: ${speed}. Must be between 1 and 3 for device: ${this.deviceName}`);
226
+ return false;
227
+ }
228
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/updateSpeed', 'put', {
229
+ acceptLanguage: 'en',
230
+ accountID: this.manager.accountId,
231
+ level: speed,
232
+ timeZone: this.manager.timeZone,
233
+ token: this.manager.token,
234
+ uuid: this.uuid
235
+ }, {
236
+ 'accept-language': 'en',
237
+ 'accountId': this.manager.accountId,
238
+ 'appVersion': '2.8.6',
239
+ 'content-type': 'application/json',
240
+ 'tk': this.manager.token,
241
+ 'tz': this.manager.timeZone
242
+ });
243
+ const success = this.checkResponse([response, status], 'changeFanSpeed');
244
+ if (success) {
245
+ this.details.speed = speed;
246
+ return true;
247
+ }
248
+ else {
249
+ logger_1.logger.error(`Failed to change fan speed to ${speed} for device: ${this.deviceName}`);
250
+ return false;
251
+ }
252
+ }
253
+ // Standard implementation for other devices
216
254
  const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
217
255
  ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
218
256
  cid: this.cid,
@@ -244,6 +282,39 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
244
282
  throw new Error(error);
245
283
  }
246
284
  logger_1.logger.debug(`Setting mode to ${mode} for device: ${this.deviceName}`);
285
+ // Special handling for LV series
286
+ if (this.deviceType.startsWith('LV-')) {
287
+ const payload = {
288
+ acceptLanguage: 'en',
289
+ accountID: this.manager.accountId,
290
+ mode: mode,
291
+ timeZone: this.manager.timeZone,
292
+ token: this.manager.token,
293
+ uuid: this.uuid
294
+ };
295
+ // For manual mode, we need to set the level
296
+ if (mode === 'manual') {
297
+ payload.level = this.details.speed || 1;
298
+ }
299
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/updateMode', 'put', payload, {
300
+ 'accept-language': 'en',
301
+ 'accountId': this.manager.accountId,
302
+ 'appVersion': '2.8.6',
303
+ 'content-type': 'application/json',
304
+ 'tk': this.manager.token,
305
+ 'tz': this.manager.timeZone
306
+ });
307
+ const success = this.checkResponse([response, status], 'setMode');
308
+ if (success) {
309
+ this.details.mode = mode;
310
+ return true;
311
+ }
312
+ else {
313
+ logger_1.logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
314
+ return false;
315
+ }
316
+ }
317
+ // Standard implementation for other devices
247
318
  const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
248
319
  ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
249
320
  cid: this.cid,
@@ -272,6 +343,34 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
272
343
  throw new Error(error);
273
344
  }
274
345
  logger_1.logger.debug(`Setting display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
346
+ // Special handling for LV series
347
+ if (this.deviceType.startsWith('LV-')) {
348
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/updateScreen', 'put', {
349
+ acceptLanguage: 'en',
350
+ accountID: this.manager.accountId,
351
+ status: enabled ? 'on' : 'off',
352
+ timeZone: this.manager.timeZone,
353
+ token: this.manager.token,
354
+ uuid: this.uuid
355
+ }, {
356
+ 'accept-language': 'en',
357
+ 'accountId': this.manager.accountId,
358
+ 'appVersion': '2.8.6',
359
+ 'content-type': 'application/json',
360
+ 'tk': this.manager.token,
361
+ 'tz': this.manager.timeZone
362
+ });
363
+ const success = this.checkResponse([response, status], 'setDisplay');
364
+ if (success) {
365
+ this.details.screenStatus = enabled ? 'on' : 'off';
366
+ return true;
367
+ }
368
+ else {
369
+ logger_1.logger.error(`Failed to set display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
370
+ return false;
371
+ }
372
+ }
373
+ // Standard implementation for other devices
275
374
  const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
276
375
  ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
277
376
  cid: this.cid,
@@ -303,6 +402,34 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
303
402
  throw new Error(error);
304
403
  }
305
404
  logger_1.logger.debug(`Setting child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
405
+ // Special handling for LV series
406
+ if (this.deviceType.startsWith('LV-')) {
407
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/updateChildLock', 'put', {
408
+ acceptLanguage: 'en',
409
+ accountID: this.manager.accountId,
410
+ status: enabled ? 'on' : 'off',
411
+ timeZone: this.manager.timeZone,
412
+ token: this.manager.token,
413
+ uuid: this.uuid
414
+ }, {
415
+ 'accept-language': 'en',
416
+ 'accountId': this.manager.accountId,
417
+ 'appVersion': '2.8.6',
418
+ 'content-type': 'application/json',
419
+ 'tk': this.manager.token,
420
+ 'tz': this.manager.timeZone
421
+ });
422
+ const success = this.checkResponse([response, status], 'setChildLock');
423
+ if (success) {
424
+ this.details.childLock = enabled;
425
+ return true;
426
+ }
427
+ else {
428
+ logger_1.logger.error(`Failed to set child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
429
+ return false;
430
+ }
431
+ }
432
+ // Standard implementation for other devices
306
433
  const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
307
434
  ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
308
435
  cid: this.cid,
@@ -334,6 +461,31 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
334
461
  throw new Error(error);
335
462
  }
336
463
  logger_1.logger.debug(`Setting timer to ${hours} hours for device: ${this.deviceName}`);
464
+ // Special handling for LV series
465
+ if (this.deviceType.startsWith('LV-')) {
466
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/updateTimer', 'put', {
467
+ acceptLanguage: 'en',
468
+ accountID: this.manager.accountId,
469
+ action: 'off',
470
+ duration: hours,
471
+ timeZone: this.manager.timeZone,
472
+ token: this.manager.token,
473
+ uuid: this.uuid
474
+ }, {
475
+ 'accept-language': 'en',
476
+ 'accountId': this.manager.accountId,
477
+ 'appVersion': '2.8.6',
478
+ 'content-type': 'application/json',
479
+ 'tk': this.manager.token,
480
+ 'tz': this.manager.timeZone
481
+ });
482
+ const success = this.checkResponse([response, status], 'setTimer');
483
+ if (!success) {
484
+ logger_1.logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
485
+ }
486
+ return success;
487
+ }
488
+ // Standard implementation for other devices
337
489
  const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
338
490
  ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
339
491
  cid: this.cid,
@@ -363,6 +515,29 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
363
515
  throw new Error(error);
364
516
  }
365
517
  logger_1.logger.debug(`Clearing timer for device: ${this.deviceName}`);
518
+ // Special handling for LV series
519
+ if (this.deviceType.startsWith('LV-')) {
520
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/cancelTimer', 'put', {
521
+ acceptLanguage: 'en',
522
+ accountID: this.manager.accountId,
523
+ timeZone: this.manager.timeZone,
524
+ token: this.manager.token,
525
+ uuid: this.uuid
526
+ }, {
527
+ 'accept-language': 'en',
528
+ 'accountId': this.manager.accountId,
529
+ 'appVersion': '2.8.6',
530
+ 'content-type': 'application/json',
531
+ 'tk': this.manager.token,
532
+ 'tz': this.manager.timeZone
533
+ });
534
+ const success = this.checkResponse([response, status], 'clearTimer');
535
+ if (!success) {
536
+ logger_1.logger.error(`Failed to clear timer for device: ${this.deviceName}`);
537
+ }
538
+ return success;
539
+ }
540
+ // Standard implementation for other devices
366
541
  const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
367
542
  ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
368
543
  cid: this.cid,
@@ -42,6 +42,11 @@ export declare class VeSyncHumid200300S extends VeSyncHumidifier {
42
42
  * Get night light brightness
43
43
  */
44
44
  get nightLightBrightness(): number;
45
+ /**
46
+ * Return JSON details for humidifier
47
+ * Override to include current humidity and target humidity
48
+ */
49
+ displayJSON(): string;
45
50
  /**
46
51
  * Set night light brightness
47
52
  */
@@ -20,7 +20,7 @@ class VeSyncHumid200300S extends humidifier_1.VeSyncHumidifier {
20
20
  * Get device details
21
21
  */
22
22
  async getDetails() {
23
- var _a, _b, _c;
23
+ var _a, _b, _c, _d;
24
24
  logger_1.logger.debug(`Getting details for device: ${this.deviceName}`);
25
25
  const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
26
26
  ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
@@ -40,7 +40,7 @@ class VeSyncHumid200300S extends humidifier_1.VeSyncHumidifier {
40
40
  this.details = {
41
41
  mode: result.mode || '',
42
42
  humidity: result.humidity || 0, // Current humidity
43
- target_humidity: result.target_humidity || result.humidity || 0, // Target humidity
43
+ target_humidity: ((_b = result.configuration) === null || _b === void 0 ? void 0 : _b.auto_target_humidity) || result.target_humidity || 0, // Target humidity from configuration
44
44
  mist_level: result.mist_level || 0,
45
45
  mist_virtual_level: result.mist_virtual_level || 0,
46
46
  water_lacks: result.water_lacks || false,
@@ -48,8 +48,8 @@ class VeSyncHumid200300S extends humidifier_1.VeSyncHumidifier {
48
48
  water_tank_lifted: result.water_tank_lifted || false,
49
49
  display: result.display || false,
50
50
  automatic_stop: result.automatic_stop_reach_target || false,
51
- automatic_stop_configured: ((_b = result.configuration) === null || _b === void 0 ? void 0 : _b.automatic_stop) || false,
52
- auto_target_humidity: ((_c = result.configuration) === null || _c === void 0 ? void 0 : _c.auto_target_humidity) || 0,
51
+ automatic_stop_configured: ((_c = result.configuration) === null || _c === void 0 ? void 0 : _c.automatic_stop) || false,
52
+ auto_target_humidity: ((_d = result.configuration) === null || _d === void 0 ? void 0 : _d.auto_target_humidity) || 0,
53
53
  configuration: result.configuration || {},
54
54
  connection_status: result.connection_status || null,
55
55
  night_light_brightness: result.night_light_brightness || 0
@@ -132,6 +132,21 @@ class VeSyncHumid200300S extends humidifier_1.VeSyncHumidifier {
132
132
  get nightLightBrightness() {
133
133
  return this.details.night_light_brightness || 0;
134
134
  }
135
+ /**
136
+ * Return JSON details for humidifier
137
+ * Override to include current humidity and target humidity
138
+ */
139
+ displayJSON() {
140
+ var _a, _b, _c;
141
+ const baseInfo = JSON.parse(super.displayJSON());
142
+ // Add current humidity from details
143
+ baseInfo['Humidity'] = ((_a = this.details.humidity) === null || _a === void 0 ? void 0 : _a.toString()) || '0';
144
+ // Add target humidity from configuration
145
+ baseInfo['Target Humidity'] = ((_b = this.details.auto_target_humidity) === null || _b === void 0 ? void 0 : _b.toString()) || '0';
146
+ // Add mist virtual level
147
+ baseInfo['Mist Virtual Level'] = ((_c = this.details.mist_virtual_level) === null || _c === void 0 ? void 0 : _c.toString()) || '0';
148
+ return JSON.stringify(baseInfo, null, 4);
149
+ }
135
150
  /**
136
151
  * Set night light brightness
137
152
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsvesync",
3
- "version": "1.0.67",
3
+ "version": "1.0.69",
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",
@@ -261,6 +261,53 @@ export class VeSyncAirBypass extends VeSyncFan {
261
261
  // }
262
262
 
263
263
  logger.info(`Changing fan speed to ${speed} for device: ${this.deviceName}`);
264
+
265
+ // Special handling for LV series
266
+ if (this.deviceType.startsWith('LV-')) {
267
+ // Check if device is in manual mode
268
+ if (this.details.mode !== 'manual') {
269
+ logger.debug(`${this.deviceName} not in manual mode, cannot change speed`);
270
+ return false;
271
+ }
272
+
273
+ // Validate speed for LV series (1-3)
274
+ if (speed < 1 || speed > 3) {
275
+ logger.error(`Invalid fan speed: ${speed}. Must be between 1 and 3 for device: ${this.deviceName}`);
276
+ return false;
277
+ }
278
+
279
+ const [response, status] = await this.callApi(
280
+ '/131airPurifier/v1/device/updateSpeed',
281
+ 'put',
282
+ {
283
+ acceptLanguage: 'en',
284
+ accountID: this.manager.accountId!,
285
+ level: speed,
286
+ timeZone: this.manager.timeZone!,
287
+ token: this.manager.token!,
288
+ uuid: this.uuid
289
+ },
290
+ {
291
+ 'accept-language': 'en',
292
+ 'accountId': this.manager.accountId!,
293
+ 'appVersion': '2.8.6',
294
+ 'content-type': 'application/json',
295
+ 'tk': this.manager.token!,
296
+ 'tz': this.manager.timeZone!
297
+ }
298
+ );
299
+
300
+ const success = this.checkResponse([response, status], 'changeFanSpeed');
301
+ if (success) {
302
+ this.details.speed = speed;
303
+ return true;
304
+ } else {
305
+ logger.error(`Failed to change fan speed to ${speed} for device: ${this.deviceName}`);
306
+ return false;
307
+ }
308
+ }
309
+
310
+ // Standard implementation for other devices
264
311
  const [response, status] = await this.callApi(
265
312
  '/cloud/v2/deviceManaged/bypassV2',
266
313
  'post',
@@ -300,6 +347,48 @@ export class VeSyncAirBypass extends VeSyncFan {
300
347
  }
301
348
 
302
349
  logger.debug(`Setting mode to ${mode} for device: ${this.deviceName}`);
350
+
351
+ // Special handling for LV series
352
+ if (this.deviceType.startsWith('LV-')) {
353
+ const payload: Record<string, any> = {
354
+ acceptLanguage: 'en',
355
+ accountID: this.manager.accountId!,
356
+ mode: mode,
357
+ timeZone: this.manager.timeZone!,
358
+ token: this.manager.token!,
359
+ uuid: this.uuid
360
+ };
361
+
362
+ // For manual mode, we need to set the level
363
+ if (mode === 'manual') {
364
+ payload.level = this.details.speed || 1;
365
+ }
366
+
367
+ const [response, status] = await this.callApi(
368
+ '/131airPurifier/v1/device/updateMode',
369
+ 'put',
370
+ payload,
371
+ {
372
+ 'accept-language': 'en',
373
+ 'accountId': this.manager.accountId!,
374
+ 'appVersion': '2.8.6',
375
+ 'content-type': 'application/json',
376
+ 'tk': this.manager.token!,
377
+ 'tz': this.manager.timeZone!
378
+ }
379
+ );
380
+
381
+ const success = this.checkResponse([response, status], 'setMode');
382
+ if (success) {
383
+ this.details.mode = mode;
384
+ return true;
385
+ } else {
386
+ logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
387
+ return false;
388
+ }
389
+ }
390
+
391
+ // Standard implementation for other devices
303
392
  const [response, status] = await this.callApi(
304
393
  '/cloud/v2/deviceManaged/bypassV2',
305
394
  'post',
@@ -336,6 +425,41 @@ export class VeSyncAirBypass extends VeSyncFan {
336
425
  }
337
426
 
338
427
  logger.debug(`Setting display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
428
+
429
+ // Special handling for LV series
430
+ if (this.deviceType.startsWith('LV-')) {
431
+ const [response, status] = await this.callApi(
432
+ '/131airPurifier/v1/device/updateScreen',
433
+ 'put',
434
+ {
435
+ acceptLanguage: 'en',
436
+ accountID: this.manager.accountId!,
437
+ status: enabled ? 'on' : 'off',
438
+ timeZone: this.manager.timeZone!,
439
+ token: this.manager.token!,
440
+ uuid: this.uuid
441
+ },
442
+ {
443
+ 'accept-language': 'en',
444
+ 'accountId': this.manager.accountId!,
445
+ 'appVersion': '2.8.6',
446
+ 'content-type': 'application/json',
447
+ 'tk': this.manager.token!,
448
+ 'tz': this.manager.timeZone!
449
+ }
450
+ );
451
+
452
+ const success = this.checkResponse([response, status], 'setDisplay');
453
+ if (success) {
454
+ this.details.screenStatus = enabled ? 'on' : 'off';
455
+ return true;
456
+ } else {
457
+ logger.error(`Failed to set display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
458
+ return false;
459
+ }
460
+ }
461
+
462
+ // Standard implementation for other devices
339
463
  const [response, status] = await this.callApi(
340
464
  '/cloud/v2/deviceManaged/bypassV2',
341
465
  'post',
@@ -374,6 +498,41 @@ export class VeSyncAirBypass extends VeSyncFan {
374
498
  }
375
499
 
376
500
  logger.debug(`Setting child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
501
+
502
+ // Special handling for LV series
503
+ if (this.deviceType.startsWith('LV-')) {
504
+ const [response, status] = await this.callApi(
505
+ '/131airPurifier/v1/device/updateChildLock',
506
+ 'put',
507
+ {
508
+ acceptLanguage: 'en',
509
+ accountID: this.manager.accountId!,
510
+ status: enabled ? 'on' : 'off',
511
+ timeZone: this.manager.timeZone!,
512
+ token: this.manager.token!,
513
+ uuid: this.uuid
514
+ },
515
+ {
516
+ 'accept-language': 'en',
517
+ 'accountId': this.manager.accountId!,
518
+ 'appVersion': '2.8.6',
519
+ 'content-type': 'application/json',
520
+ 'tk': this.manager.token!,
521
+ 'tz': this.manager.timeZone!
522
+ }
523
+ );
524
+
525
+ const success = this.checkResponse([response, status], 'setChildLock');
526
+ if (success) {
527
+ this.details.childLock = enabled;
528
+ return true;
529
+ } else {
530
+ logger.error(`Failed to set child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
531
+ return false;
532
+ }
533
+ }
534
+
535
+ // Standard implementation for other devices
377
536
  const [response, status] = await this.callApi(
378
537
  '/cloud/v2/deviceManaged/bypassV2',
379
538
  'post',
@@ -412,6 +571,39 @@ export class VeSyncAirBypass extends VeSyncFan {
412
571
  }
413
572
 
414
573
  logger.debug(`Setting timer to ${hours} hours for device: ${this.deviceName}`);
574
+
575
+ // Special handling for LV series
576
+ if (this.deviceType.startsWith('LV-')) {
577
+ const [response, status] = await this.callApi(
578
+ '/131airPurifier/v1/device/updateTimer',
579
+ 'put',
580
+ {
581
+ acceptLanguage: 'en',
582
+ accountID: this.manager.accountId!,
583
+ action: 'off',
584
+ duration: hours,
585
+ timeZone: this.manager.timeZone!,
586
+ token: this.manager.token!,
587
+ uuid: this.uuid
588
+ },
589
+ {
590
+ 'accept-language': 'en',
591
+ 'accountId': this.manager.accountId!,
592
+ 'appVersion': '2.8.6',
593
+ 'content-type': 'application/json',
594
+ 'tk': this.manager.token!,
595
+ 'tz': this.manager.timeZone!
596
+ }
597
+ );
598
+
599
+ const success = this.checkResponse([response, status], 'setTimer');
600
+ if (!success) {
601
+ logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
602
+ }
603
+ return success;
604
+ }
605
+
606
+ // Standard implementation for other devices
415
607
  const [response, status] = await this.callApi(
416
608
  '/cloud/v2/deviceManaged/bypassV2',
417
609
  'post',
@@ -449,6 +641,37 @@ export class VeSyncAirBypass extends VeSyncFan {
449
641
  }
450
642
 
451
643
  logger.debug(`Clearing timer for device: ${this.deviceName}`);
644
+
645
+ // Special handling for LV series
646
+ if (this.deviceType.startsWith('LV-')) {
647
+ const [response, status] = await this.callApi(
648
+ '/131airPurifier/v1/device/cancelTimer',
649
+ 'put',
650
+ {
651
+ acceptLanguage: 'en',
652
+ accountID: this.manager.accountId!,
653
+ timeZone: this.manager.timeZone!,
654
+ token: this.manager.token!,
655
+ uuid: this.uuid
656
+ },
657
+ {
658
+ 'accept-language': 'en',
659
+ 'accountId': this.manager.accountId!,
660
+ 'appVersion': '2.8.6',
661
+ 'content-type': 'application/json',
662
+ 'tk': this.manager.token!,
663
+ 'tz': this.manager.timeZone!
664
+ }
665
+ );
666
+
667
+ const success = this.checkResponse([response, status], 'clearTimer');
668
+ if (!success) {
669
+ logger.error(`Failed to clear timer for device: ${this.deviceName}`);
670
+ }
671
+ return success;
672
+ }
673
+
674
+ // Standard implementation for other devices
452
675
  const [response, status] = await this.callApi(
453
676
  '/cloud/v2/deviceManaged/bypassV2',
454
677
  'post',
@@ -48,7 +48,7 @@ export class VeSyncHumid200300S extends VeSyncHumidifier {
48
48
  this.details = {
49
49
  mode: result.mode || '',
50
50
  humidity: result.humidity || 0, // Current humidity
51
- target_humidity: result.target_humidity || result.humidity || 0, // Target humidity
51
+ target_humidity: result.configuration?.auto_target_humidity || result.target_humidity || 0, // Target humidity from configuration
52
52
  mist_level: result.mist_level || 0,
53
53
  mist_virtual_level: result.mist_virtual_level || 0,
54
54
  water_lacks: result.water_lacks || false,
@@ -154,6 +154,25 @@ export class VeSyncHumid200300S extends VeSyncHumidifier {
154
154
  return this.details.night_light_brightness || 0;
155
155
  }
156
156
 
157
+ /**
158
+ * Return JSON details for humidifier
159
+ * Override to include current humidity and target humidity
160
+ */
161
+ displayJSON(): string {
162
+ const baseInfo = JSON.parse(super.displayJSON());
163
+
164
+ // Add current humidity from details
165
+ baseInfo['Humidity'] = this.details.humidity?.toString() || '0';
166
+
167
+ // Add target humidity from configuration
168
+ baseInfo['Target Humidity'] = this.details.auto_target_humidity?.toString() || '0';
169
+
170
+ // Add mist virtual level
171
+ baseInfo['Mist Virtual Level'] = this.details.mist_virtual_level?.toString() || '0';
172
+
173
+ return JSON.stringify(baseInfo, null, 4);
174
+ }
175
+
157
176
  /**
158
177
  * Set night light brightness
159
178
  */