tsvesync 1.0.11 → 1.0.13

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 (40) hide show
  1. package/dist/index.d.ts +7 -0
  2. package/dist/index.js +25 -0
  3. package/dist/lib/helpers.d.ts +52 -51
  4. package/dist/lib/helpers.js +135 -112
  5. package/dist/lib/logger.d.ts +23 -0
  6. package/dist/lib/logger.js +54 -0
  7. package/dist/lib/vesync.d.ts +57 -15
  8. package/dist/lib/vesync.js +341 -217
  9. package/dist/lib/vesyncBaseDevice.d.ts +25 -50
  10. package/dist/lib/vesyncBaseDevice.js +63 -90
  11. package/dist/lib/vesyncBulb.d.ts +88 -0
  12. package/dist/lib/vesyncBulb.js +295 -1
  13. package/dist/lib/vesyncBulbImpl.d.ts +38 -0
  14. package/dist/lib/vesyncBulbImpl.js +230 -0
  15. package/dist/lib/vesyncFan.d.ts +55 -67
  16. package/dist/lib/vesyncFan.js +366 -213
  17. package/dist/lib/vesyncFanImpl.d.ts +173 -0
  18. package/dist/lib/vesyncFanImpl.js +909 -0
  19. package/dist/lib/vesyncOutlet.d.ts +70 -0
  20. package/dist/lib/vesyncOutlet.js +213 -1
  21. package/dist/lib/vesyncOutletImpl.d.ts +70 -0
  22. package/dist/lib/vesyncOutletImpl.js +245 -0
  23. package/dist/lib/vesyncSwitch.d.ts +45 -0
  24. package/dist/lib/vesyncSwitch.js +77 -1
  25. package/dist/lib/vesyncSwitchImpl.d.ts +82 -0
  26. package/dist/lib/vesyncSwitchImpl.js +344 -0
  27. package/package.json +1 -1
  28. package/src/index.ts +14 -0
  29. package/src/lib/helpers.ts +3 -2
  30. package/src/lib/logger.ts +60 -0
  31. package/src/lib/vesync.ts +42 -43
  32. package/src/lib/vesyncBaseDevice.ts +8 -7
  33. package/src/lib/vesyncBulb.ts +138 -30
  34. package/src/lib/vesyncBulbImpl.ts +113 -44
  35. package/src/lib/vesyncFan.ts +2 -4
  36. package/src/lib/vesyncFanImpl.ts +314 -42
  37. package/src/lib/vesyncOutlet.ts +140 -13
  38. package/src/lib/vesyncOutletImpl.ts +41 -0
  39. package/src/lib/vesyncSwitch.ts +3 -454
  40. package/src/lib/vesyncSwitchImpl.ts +66 -16
package/src/lib/vesync.ts CHANGED
@@ -9,8 +9,7 @@ import { outletModules } from './vesyncOutletImpl';
9
9
  import { switchModules } from './vesyncSwitchImpl';
10
10
  import { bulbModules } from './vesyncBulbImpl';
11
11
  import { VeSyncBulb } from './vesyncBulb';
12
- import { VeSyncOutlet } from './vesyncOutlet';
13
- import { VeSyncSwitch } from './vesyncSwitch';
12
+ import { logger } from './logger';
14
13
 
15
14
  const DEFAULT_ENERGY_UPDATE_INTERVAL = 21600;
16
15
 
@@ -46,7 +45,7 @@ function objectFactory(details: Record<string, any>, manager: VeSync): [string,
46
45
  if (deviceType in modules) {
47
46
  DeviceClass = modules[deviceType];
48
47
  category = cat;
49
- console.debug(`Found exact match for ${deviceType} in ${cat} modules`);
48
+ logger.debug(`Found exact match for ${deviceType} in ${cat} modules`);
50
49
  break;
51
50
  }
52
51
  }
@@ -83,7 +82,7 @@ function objectFactory(details: Record<string, any>, manager: VeSync): [string,
83
82
  for (const [prefix, cat] of Object.entries(prefixMap)) {
84
83
  if (deviceType.startsWith(prefix)) {
85
84
  category = cat;
86
- console.debug(`Device type ${deviceType} matched prefix ${prefix} -> category ${cat}`);
85
+ logger.debug(`Device type ${deviceType} matched prefix ${prefix} -> category ${cat}`);
87
86
 
88
87
  // Try to find a base class in this category's modules
89
88
  const modules = allModules[cat];
@@ -91,7 +90,7 @@ function objectFactory(details: Record<string, any>, manager: VeSync): [string,
91
90
  const baseType = moduleType.split('-')[0]; // e.g., ESL100 from ESL100-USA
92
91
  if (deviceType.startsWith(baseType)) {
93
92
  DeviceClass = ModuleClass;
94
- console.debug(`Found base type match: ${deviceType} -> ${baseType}`);
93
+ logger.debug(`Found base type match: ${deviceType} -> ${baseType}`);
95
94
  break;
96
95
  }
97
96
  }
@@ -107,11 +106,11 @@ function objectFactory(details: Record<string, any>, manager: VeSync): [string,
107
106
  const device = new DeviceClass(details, manager);
108
107
  return [category, device];
109
108
  } catch (error) {
110
- console.error(`Error creating device instance for ${deviceType}:`, error);
109
+ logger.error(`Error creating device instance for ${deviceType}:`, error);
111
110
  return [category, null];
112
111
  }
113
112
  } else {
114
- console.warn(`No device class found for type: ${deviceType}`);
113
+ logger.warn(`No device class found for type: ${deviceType}`);
115
114
  return [category, null];
116
115
  }
117
116
  }
@@ -187,13 +186,13 @@ export class VeSync {
187
186
  const regTest = /[^a-zA-Z/_]/;
188
187
  if (regTest.test(timeZone)) {
189
188
  this.timeZone = DEFAULT_TZ;
190
- console.debug('Invalid characters in time zone - ', timeZone);
189
+ logger.debug('Invalid characters in time zone - ', timeZone);
191
190
  } else {
192
191
  this.timeZone = timeZone;
193
192
  }
194
193
  } else {
195
194
  this.timeZone = DEFAULT_TZ;
196
- console.debug('Time zone is not a string');
195
+ logger.debug('Time zone is not a string');
197
196
  }
198
197
 
199
198
  if (debug) {
@@ -251,7 +250,7 @@ export class VeSync {
251
250
  return true;
252
251
  }
253
252
  }
254
- console.debug(`Device removed - ${device.deviceName} - ${device.deviceType}`);
253
+ logger.debug(`Device removed - ${device.deviceName} - ${device.deviceType}`);
255
254
  return false;
256
255
  }
257
256
  return true;
@@ -282,7 +281,7 @@ export class VeSync {
282
281
  this._devList[key] = deviceList.filter(device => VeSync.removeDevTest(device, devices));
283
282
  const after = this._devList[key].length;
284
283
  if (before !== after) {
285
- console.debug(`${before - after} ${key} removed`);
284
+ logger.debug(`${before - after} ${key} removed`);
286
285
  }
287
286
  }
288
287
  return true;
@@ -301,7 +300,7 @@ export class VeSync {
301
300
  dev.cid = dev.uuid;
302
301
  } else {
303
302
  devRem.push(index);
304
- console.warn(`Device with no ID - ${dev.deviceName || ''}`);
303
+ logger.warn(`Device with no ID - ${dev.deviceName || ''}`);
305
304
  }
306
305
  }
307
306
  });
@@ -326,13 +325,13 @@ export class VeSync {
326
325
  }
327
326
 
328
327
  if (!devices || devices.length === 0) {
329
- console.warn('No devices found in api return');
328
+ logger.warn('No devices found in api return');
330
329
  return false;
331
330
  }
332
331
 
333
332
  // Initialize new device list or remove old devices
334
333
  if (numDevices === 0) {
335
- console.debug('New device list initialized');
334
+ logger.debug('New device list initialized');
336
335
  } else {
337
336
  this.removeOldDevices(devices);
338
337
  }
@@ -347,7 +346,7 @@ export class VeSync {
347
346
  for (const dev of newDevices) {
348
347
  // Verify required device properties
349
348
  if (!requiredKeys.every(key => key in dev)) {
350
- console.debug(`Error adding device - missing required properties: ${dev.deviceName || 'Unknown'}`);
349
+ logger.debug(`Error adding device - missing required properties: ${dev.deviceName || 'Unknown'}`);
351
350
  continue;
352
351
  }
353
352
 
@@ -359,12 +358,12 @@ export class VeSync {
359
358
  // Add device to appropriate category if valid
360
359
  if (deviceObj && category in this._devList) {
361
360
  this._devList[category].push(deviceObj);
362
- console.debug(`Added ${devType} device to ${category} category`);
361
+ logger.debug(`Added ${devType} device to ${category} category`);
363
362
  } else if (category === 'unknown') {
364
- console.debug(`Unknown device type: ${devType}`);
363
+ logger.debug(`Unknown device type: ${devType}`);
365
364
  }
366
365
  } catch (err) {
367
- console.error(`Error creating device ${devType}:`, err);
366
+ logger.error(`Error creating device ${devType}:`, err);
368
367
  continue;
369
368
  }
370
369
  }
@@ -377,7 +376,7 @@ export class VeSync {
377
376
  */
378
377
  async getDevices(): Promise<boolean> {
379
378
  if (!this.enabled) {
380
- console.error('Not logged in to VeSync');
379
+ logger.error('Not logged in to VeSync');
381
380
  return false;
382
381
  }
383
382
 
@@ -400,42 +399,42 @@ export class VeSync {
400
399
  this.devices = Object.values(this._devList).flat();
401
400
 
402
401
  // Log device discovery results
403
- console.log('\n=== Device Discovery Summary ===');
404
- console.log(`Total devices processed: ${deviceList.length}`);
402
+ logger.debug('\n=== Device Discovery Summary ===');
403
+ logger.debug(`Total devices processed: ${deviceList.length}`);
405
404
 
406
405
  // Log device types found
407
406
  const deviceTypes = deviceList.map((d: Record<string, any>) => d.deviceType);
408
- console.log('\nDevice types found:', deviceTypes);
407
+ logger.debug('\nDevice types found:', deviceTypes);
409
408
 
410
409
  // Log devices by category with details
411
- console.log('\nDevices by Category:');
412
- console.log('---------------------');
410
+ logger.debug('\nDevices by Category:');
411
+ logger.debug('---------------------');
413
412
  for (const [category, devices] of Object.entries(this._devList)) {
414
413
  if (devices.length > 0) {
415
- console.log(`\n${category.toUpperCase()} (${devices.length} devices):`);
414
+ logger.debug(`\n${category.toUpperCase()} (${devices.length} devices):`);
416
415
  devices.forEach((d: VeSyncBaseDevice) => {
417
- console.log(` • ${d.deviceName}`);
418
- console.log(` Type: ${d.deviceType}`);
419
- console.log(` Status: ${d.deviceStatus}`);
420
- console.log(` ID: ${d.cid}`);
416
+ logger.debug(` • ${d.deviceName}`);
417
+ logger.debug(` Type: ${d.deviceType}`);
418
+ logger.debug(` Status: ${d.deviceStatus}`);
419
+ logger.debug(` ID: ${d.cid}`);
421
420
  });
422
421
  }
423
422
  }
424
423
 
425
424
  // Log summary statistics
426
- console.log('\nSummary Statistics:');
427
- console.log('-------------------');
428
- console.log(`Total Devices: ${this.devices?.length || 0}`);
425
+ logger.debug('\nSummary Statistics:');
426
+ logger.debug('-------------------');
427
+ logger.debug(`Total Devices: ${this.devices?.length || 0}`);
429
428
  for (const [category, devices] of Object.entries(this._devList)) {
430
- console.log(`${category}: ${devices.length} devices`);
429
+ logger.debug(`${category}: ${devices.length} devices`);
431
430
  }
432
431
 
433
- console.log('\n=== End of Device Discovery ===\n');
432
+ logger.debug('\n=== End of Device Discovery ===\n');
434
433
  } else {
435
- console.error('No devices found in response');
434
+ logger.error('No devices found in response');
436
435
  }
437
436
  } catch (error) {
438
- console.error('Unable to get device list:', error);
437
+ logger.error('Unable to get device list:', error);
439
438
  }
440
439
 
441
440
  this._inProcess = false;
@@ -447,7 +446,7 @@ export class VeSync {
447
446
  */
448
447
  async login(): Promise<boolean> {
449
448
  const body = Helpers.reqBody(this, 'login');
450
- console.log('Login request:', {
449
+ logger.debug('Login request:', {
451
450
  url: `${process.env.VESYNC_API_URL}/cloud/v1/user/login`,
452
451
  body
453
452
  });
@@ -459,7 +458,7 @@ export class VeSync {
459
458
  body
460
459
  );
461
460
 
462
- console.log('Login response:', { status, response });
461
+ logger.debug('Login response:', { status, response });
463
462
 
464
463
  if (response?.result?.token) {
465
464
  this.token = response.result.token;
@@ -469,10 +468,10 @@ export class VeSync {
469
468
  return true;
470
469
  }
471
470
 
472
- console.error('Unable to login with supplied credentials');
471
+ logger.error('Unable to login with supplied credentials');
473
472
  return false;
474
473
  } catch (error) {
475
- console.error('Login error:', error);
474
+ logger.error('Login error:', error);
476
475
  return false;
477
476
  }
478
477
  }
@@ -493,19 +492,19 @@ export class VeSync {
493
492
  async update(): Promise<void> {
494
493
  if (this.deviceTimeCheck()) {
495
494
  if (!this.enabled) {
496
- console.error('Not logged in to VeSync');
495
+ logger.error('Not logged in to VeSync');
497
496
  return;
498
497
  }
499
498
 
500
499
  await this.getDevices();
501
500
 
502
- console.debug('Start updating the device details one by one');
501
+ logger.debug('Start updating the device details one by one');
503
502
  for (const deviceList of Object.values(this._devList)) {
504
503
  for (const device of deviceList) {
505
504
  try {
506
505
  await device.getDetails();
507
506
  } catch (error) {
508
- console.error(`Error updating ${device.deviceName}:`, error);
507
+ logger.error(`Error updating ${device.deviceName}:`, error);
509
508
  }
510
509
  }
511
510
  }
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  import { VeSync } from './vesync';
6
+ import { logger } from './logger';
6
7
 
7
8
  export abstract class VeSyncBaseDevice {
8
9
  protected manager: VeSync;
@@ -37,11 +38,11 @@ export abstract class VeSyncBaseDevice {
37
38
  * Return formatted device info to stdout
38
39
  */
39
40
  display(): void {
40
- console.log(`Device Name: ${this.deviceName}`);
41
- console.log(`Status: ${this.deviceStatus}`);
42
- console.log(`Device Type: ${this.deviceType}`);
43
- console.log(`Connection: ${this.connectionStatus}`);
44
- console.log(`Version: ${this.config.current_firmware_version || 'Unknown'}`);
41
+ logger.info(`Device Name: ${this.deviceName}`);
42
+ logger.info(`Status: ${this.deviceStatus}`);
43
+ logger.info(`Device Type: ${this.deviceType}`);
44
+ logger.info(`Connection: ${this.connectionStatus}`);
45
+ logger.info(`Version: ${this.config.current_firmware_version || 'Unknown'}`);
45
46
  }
46
47
 
47
48
  /**
@@ -90,13 +91,13 @@ export abstract class VeSyncBaseDevice {
90
91
  */
91
92
  protected logError(method: string, error: any): void {
92
93
  const errorMsg = error?.message || error;
93
- console.error(`[${this.deviceName}] ${method}: ${errorMsg}`);
94
+ logger.error(`[${this.deviceName}] ${method}: ${errorMsg}`);
94
95
 
95
96
  // Log additional error details if available
96
97
  if (error?.response?.data) {
97
98
  const responseData = error.response.data;
98
99
  const msg = responseData.msg || responseData.message || JSON.stringify(responseData);
99
- console.error(`Response: ${msg}`);
100
+ logger.error(`Response: ${msg}`);
100
101
  }
101
102
  }
102
103
 
@@ -5,22 +5,35 @@
5
5
  import { VeSyncBaseDevice } from './vesyncBaseDevice';
6
6
  import { VeSync } from './vesync';
7
7
  import { Helpers } from './helpers';
8
+ import { logger } from './logger';
8
9
 
9
- // Feature dictionary for bulb types
10
- const featureDict: Record<string, { features: string[], colorModel: string }> = {
10
+ interface BulbConfig {
11
+ [key: string]: {
12
+ module: string;
13
+ features: string[];
14
+ colorModel: string;
15
+ };
16
+ }
17
+
18
+ // Bulb configuration
19
+ export const bulbConfig: BulbConfig = {
11
20
  'ESL100': {
21
+ module: 'VeSyncBulbESL100',
12
22
  features: ['dimmable'],
13
23
  colorModel: 'none'
14
24
  },
15
25
  'ESL100CW': {
26
+ module: 'VeSyncBulbESL100CW',
16
27
  features: ['dimmable', 'color_temp'],
17
28
  colorModel: 'none'
18
29
  },
19
30
  'XYD0001': {
31
+ module: 'VeSyncBulbXYD0001',
20
32
  features: ['dimmable', 'color_temp', 'rgb_shift'],
21
33
  colorModel: 'hsv'
22
34
  },
23
35
  'ESL100MC': {
36
+ module: 'VeSyncBulbESL100MC',
24
37
  features: ['dimmable', 'rgb_shift'],
25
38
  colorModel: 'rgb'
26
39
  }
@@ -47,7 +60,7 @@ export abstract class VeSyncBulb extends VeSyncBaseDevice {
47
60
  this.colorHue = 0;
48
61
  this.colorSaturation = 0;
49
62
  this.colorMode = '';
50
- this.features = featureDict[this.deviceType]?.features || [];
63
+ this.features = bulbConfig[this.deviceType]?.features || [];
51
64
  this.rgbValues = {
52
65
  red: 0,
53
66
  green: 0,
@@ -59,27 +72,43 @@ export abstract class VeSyncBulb extends VeSyncBaseDevice {
59
72
  * Get bulb details
60
73
  */
61
74
  async getDetails(): Promise<void> {
62
- const body = {
63
- ...Helpers.reqBody(this.manager, 'devicedetail'),
64
- uuid: this.cid,
65
- method: 'devicedetail'
75
+ logger.debug(`[${this.deviceName}] Getting bulb details`);
76
+
77
+ const isV2Device = this.deviceType === 'XYD0001';
78
+ const endpoint = isV2Device ? '/cloud/v2/deviceManaged/bypassV2' : '/cloud/v1/deviceManaged/bypass';
79
+ const body = isV2Device ? {
80
+ ...Helpers.reqBody(this.manager, 'bypassV2'),
81
+ cid: this.cid,
82
+ configModule: this.configModule,
83
+ payload: {
84
+ data: {},
85
+ method: 'getLightStatusV2',
86
+ source: 'APP'
87
+ }
88
+ } : {
89
+ ...Helpers.reqBody(this.manager, 'bypass'),
90
+ cid: this.cid,
91
+ configModule: this.configModule,
92
+ jsonCmd: {
93
+ getLightStatus: 'get'
94
+ }
66
95
  };
67
96
 
68
97
  const [response] = await Helpers.callApi(
69
- '/SmartBulb/v1/device/devicedetail',
98
+ endpoint,
70
99
  'post',
71
100
  body,
72
101
  Helpers.reqHeaders(this.manager)
73
102
  );
74
103
 
75
104
  if (response?.code === 0 && response?.result) {
76
- this.deviceStatus = response.result.deviceStatus || this.deviceStatus;
105
+ this.deviceStatus = response.result.enabled ? 'on' : 'off';
77
106
  this.brightness = response.result.brightness || this.brightness;
78
107
  if (this.features.includes('color_temp')) {
79
108
  this.colorTemp = response.result.colorTemp || this.colorTemp;
80
109
  }
81
110
  if (this.features.includes('rgb_shift')) {
82
- if (featureDict[this.deviceType].colorModel === 'rgb') {
111
+ if (bulbConfig[this.deviceType].colorModel === 'rgb') {
83
112
  this.rgbValues = {
84
113
  red: response.result.red || this.rgbValues.red,
85
114
  green: response.result.green || this.rgbValues.green,
@@ -91,6 +120,9 @@ export abstract class VeSyncBulb extends VeSyncBaseDevice {
91
120
  this.colorValue = response.result.value || this.colorValue;
92
121
  }
93
122
  }
123
+ logger.debug(`[${this.deviceName}] Successfully retrieved bulb details`);
124
+ } else {
125
+ logger.error(`[${this.deviceName}] Failed to get bulb details: ${JSON.stringify(response)}`);
94
126
  }
95
127
  }
96
128
 
@@ -98,30 +130,55 @@ export abstract class VeSyncBulb extends VeSyncBaseDevice {
98
130
  * Update bulb status
99
131
  */
100
132
  async update(): Promise<void> {
133
+ logger.debug(`[${this.deviceName}] Updating bulb information`);
101
134
  await this.getDetails();
135
+ logger.debug(`[${this.deviceName}] Successfully updated bulb information`);
102
136
  }
103
137
 
104
138
  /**
105
139
  * Turn bulb on
106
140
  */
107
141
  async turnOn(): Promise<boolean> {
108
- const body = {
109
- ...Helpers.reqBody(this.manager, 'devicestatus'),
110
- uuid: this.cid,
111
- status: 'on'
142
+ logger.debug(`[${this.deviceName}] Turning bulb on`);
143
+
144
+ const isV2Device = this.deviceType === 'XYD0001';
145
+ const endpoint = isV2Device ? '/cloud/v2/deviceManaged/bypassV2' : '/cloud/v1/deviceManaged/bypass';
146
+ const body = isV2Device ? {
147
+ ...Helpers.reqBody(this.manager, 'bypassV2'),
148
+ cid: this.cid,
149
+ configModule: this.configModule,
150
+ payload: {
151
+ data: {
152
+ enabled: true,
153
+ id: 0
154
+ },
155
+ method: 'setSwitch',
156
+ source: 'APP'
157
+ }
158
+ } : {
159
+ ...Helpers.reqBody(this.manager, 'bypass'),
160
+ cid: this.cid,
161
+ configModule: this.configModule,
162
+ jsonCmd: {
163
+ light: {
164
+ action: 'on'
165
+ }
166
+ }
112
167
  };
113
168
 
114
169
  const [response] = await Helpers.callApi(
115
- '/SmartBulb/v1/device/devicestatus',
116
- 'put',
170
+ endpoint,
171
+ 'post',
117
172
  body,
118
173
  Helpers.reqHeaders(this.manager)
119
174
  );
120
175
 
121
176
  if (response?.code === 0) {
122
177
  this.deviceStatus = 'on';
178
+ logger.debug(`[${this.deviceName}] Successfully turned bulb on`);
123
179
  return true;
124
180
  }
181
+ logger.error(`[${this.deviceName}] Failed to turn bulb on: ${JSON.stringify(response)}`);
125
182
  return false;
126
183
  }
127
184
 
@@ -129,23 +186,46 @@ export abstract class VeSyncBulb extends VeSyncBaseDevice {
129
186
  * Turn bulb off
130
187
  */
131
188
  async turnOff(): Promise<boolean> {
132
- const body = {
133
- ...Helpers.reqBody(this.manager, 'devicestatus'),
134
- uuid: this.cid,
135
- status: 'off'
189
+ logger.debug(`[${this.deviceName}] Turning bulb off`);
190
+
191
+ const isV2Device = this.deviceType === 'XYD0001';
192
+ const endpoint = isV2Device ? '/cloud/v2/deviceManaged/bypassV2' : '/cloud/v1/deviceManaged/bypass';
193
+ const body = isV2Device ? {
194
+ ...Helpers.reqBody(this.manager, 'bypassV2'),
195
+ cid: this.cid,
196
+ configModule: this.configModule,
197
+ payload: {
198
+ data: {
199
+ enabled: false,
200
+ id: 0
201
+ },
202
+ method: 'setSwitch',
203
+ source: 'APP'
204
+ }
205
+ } : {
206
+ ...Helpers.reqBody(this.manager, 'bypass'),
207
+ cid: this.cid,
208
+ configModule: this.configModule,
209
+ jsonCmd: {
210
+ light: {
211
+ action: 'off'
212
+ }
213
+ }
136
214
  };
137
215
 
138
216
  const [response] = await Helpers.callApi(
139
- '/SmartBulb/v1/device/devicestatus',
140
- 'put',
217
+ endpoint,
218
+ 'post',
141
219
  body,
142
220
  Helpers.reqHeaders(this.manager)
143
221
  );
144
222
 
145
223
  if (response?.code === 0) {
146
224
  this.deviceStatus = 'off';
225
+ logger.debug(`[${this.deviceName}] Successfully turned bulb off`);
147
226
  return true;
148
227
  }
228
+ logger.error(`[${this.deviceName}] Failed to turn bulb off: ${JSON.stringify(response)}`);
149
229
  return false;
150
230
  }
151
231
 
@@ -154,27 +234,55 @@ export abstract class VeSyncBulb extends VeSyncBaseDevice {
154
234
  */
155
235
  async setBrightness(brightness: number): Promise<boolean> {
156
236
  if (!this.features.includes('dimmable')) {
237
+ logger.error(`[${this.deviceName}] Dimming not supported`);
157
238
  return false;
158
239
  }
159
240
 
160
- const body = {
161
- ...Helpers.reqBody(this.manager, 'devicestatus'),
162
- uuid: this.cid,
163
- status: 'on',
164
- brightNess: brightness.toString()
241
+ logger.debug(`[${this.deviceName}] Setting brightness to ${brightness}`);
242
+
243
+ const isV2Device = this.deviceType === 'XYD0001';
244
+ const endpoint = isV2Device ? '/cloud/v2/deviceManaged/bypassV2' : '/cloud/v1/deviceManaged/bypass';
245
+ const body = isV2Device ? {
246
+ ...Helpers.reqBody(this.manager, 'bypassV2'),
247
+ cid: this.cid,
248
+ configModule: this.configModule,
249
+ payload: {
250
+ data: {
251
+ brightness: brightness,
252
+ colorMode: '',
253
+ colorTemp: '',
254
+ force: 0,
255
+ hue: '',
256
+ saturation: '',
257
+ value: ''
258
+ },
259
+ method: 'setLightStatusV2',
260
+ source: 'APP'
261
+ }
262
+ } : {
263
+ ...Helpers.reqBody(this.manager, 'bypass'),
264
+ cid: this.cid,
265
+ configModule: this.configModule,
266
+ jsonCmd: {
267
+ light: {
268
+ brightness: brightness
269
+ }
270
+ }
165
271
  };
166
272
 
167
273
  const [response] = await Helpers.callApi(
168
- '/SmartBulb/v1/device/updateBrightness',
169
- 'put',
274
+ endpoint,
275
+ 'post',
170
276
  body,
171
277
  Helpers.reqHeaders(this.manager)
172
278
  );
173
279
 
174
280
  if (response?.code === 0) {
175
281
  this.brightness = brightness;
282
+ logger.debug(`[${this.deviceName}] Successfully set brightness to ${brightness}`);
176
283
  return true;
177
284
  }
285
+ logger.error(`[${this.deviceName}] Failed to set brightness: ${JSON.stringify(response)}`);
178
286
  return false;
179
287
  }
180
288
 
@@ -239,7 +347,7 @@ export abstract class VeSyncBulb extends VeSyncBaseDevice {
239
347
  * Get RGB values
240
348
  */
241
349
  getRGBValues(): { red: number, green: number, blue: number } {
242
- if (!this.features.includes('rgb_shift') || featureDict[this.deviceType].colorModel !== 'rgb') {
350
+ if (!this.features.includes('rgb_shift') || bulbConfig[this.deviceType].colorModel !== 'rgb') {
243
351
  return { red: 0, green: 0, blue: 0 };
244
352
  }
245
353
  return this.rgbValues;