tsvesync 1.0.15 → 1.0.17

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/README.md CHANGED
@@ -166,7 +166,7 @@ for (const device of manager.devices) {
166
166
  const fan = manager.devices.find(d => d.deviceType === 'Core300S');
167
167
  if (fan) {
168
168
  await fan.setMode('auto'); // Available modes: auto, sleep, manual
169
- await fan.setSpeed(2); // Speed range depends on model
169
+ await fan.changeFanSpeed(2); // Speed range depends on model
170
170
  }
171
171
 
172
172
  // Control an outlet
@@ -52,7 +52,7 @@ class VeSyncOutlet extends vesyncBaseDevice_1.VeSyncBaseDevice {
52
52
  };
53
53
  let url;
54
54
  if (this.deviceType === 'wifi-switch-1.3') {
55
- url = `/v1/device/${this.deviceType}-${this.cid}/detail`;
55
+ url = `/v1/device/wifi-switch-1.3-${this.cid}/detail`;
56
56
  }
57
57
  else if (this.deviceType.startsWith('ESO15')) {
58
58
  url = '/outdoorsocket15a/v1/device/devicedetail';
@@ -67,13 +67,45 @@ class VeSyncOutlet extends vesyncBaseDevice_1.VeSyncBaseDevice {
67
67
  url = '/v1/device/devicedetail';
68
68
  }
69
69
  const [response] = await helpers_1.Helpers.callApi(url, this.deviceType === 'wifi-switch-1.3' ? 'get' : 'post', this.deviceType === 'wifi-switch-1.3' ? null : body, helpers_1.Helpers.reqHeaders(this.manager));
70
- if ((response === null || response === void 0 ? void 0 : response.code) === 0) {
71
- this.details = response.result;
72
- this.deviceStatus = response.result.deviceStatus;
70
+ if (!response) {
71
+ logger_1.logger.debug(`[${this.deviceName}] No response received from API`);
72
+ return;
73
+ }
74
+ // Handle error responses
75
+ if (response.error) {
76
+ logger_1.logger.debug(`[${this.deviceName}] Failed to get outlet details: ${JSON.stringify(response)}`);
77
+ return;
78
+ }
79
+ // Handle successful responses
80
+ if (response.code === 0) {
81
+ this.details = response;
82
+ // Handle outdoor plugs with subdevices
83
+ if (response.subDevices) {
84
+ const subDevice = response.subDevices.find((dev) => dev.subDeviceName === this.deviceName);
85
+ if (subDevice) {
86
+ this.deviceStatus = subDevice.subDeviceStatus;
87
+ logger_1.logger.debug(`[${this.deviceName}] Successfully retrieved subdevice status: ${this.deviceStatus}`);
88
+ return;
89
+ }
90
+ }
91
+ // Handle regular devices
92
+ if (response.deviceStatus !== undefined) {
93
+ this.deviceStatus = response.deviceStatus;
94
+ }
95
+ else if (response.status !== undefined) {
96
+ this.deviceStatus = response.status;
97
+ }
98
+ else if (response.power !== undefined) {
99
+ this.deviceStatus = response.power === 'on' ? 'on' : 'off';
100
+ }
101
+ else {
102
+ logger_1.logger.debug(`[${this.deviceName}] Device status not found in response: ${JSON.stringify(response)}`);
103
+ return;
104
+ }
73
105
  logger_1.logger.debug(`[${this.deviceName}] Successfully retrieved outlet details`);
74
106
  }
75
107
  else {
76
- logger_1.logger.error(`[${this.deviceName}] Failed to get outlet details: ${JSON.stringify(response)}`);
108
+ logger_1.logger.debug(`[${this.deviceName}] Failed to get outlet details: ${JSON.stringify(response)}`);
77
109
  }
78
110
  }
79
111
  /**
@@ -85,14 +117,58 @@ class VeSyncOutlet extends vesyncBaseDevice_1.VeSyncBaseDevice {
85
117
  return;
86
118
  }
87
119
  logger_1.logger.debug(`[${this.deviceName}] Updating energy data`);
88
- const url = `/v1/${this.deviceType}/${this.deviceType}-${this.cid}/energy/detail`;
89
- const [response] = await helpers_1.Helpers.callApi(url, 'get', null, helpers_1.Helpers.reqHeaders(this.manager));
90
- if ((response === null || response === void 0 ? void 0 : response.code) === 0) {
120
+ // Different endpoints for different device types
121
+ let url;
122
+ if (this.deviceType === 'wifi-switch-1.3') {
123
+ url = `/v1/device/${this.deviceType}-${this.cid}/energy/detail`;
124
+ }
125
+ else if (this.deviceType.startsWith('ESO15')) {
126
+ url = '/outdoorsocket15a/v1/device/energy';
127
+ }
128
+ else if (this.deviceType.startsWith('ESW15')) {
129
+ url = '/15a/v1/device/energy';
130
+ }
131
+ else if (this.deviceType.startsWith('ESW03') || this.deviceType.startsWith('ESW01')) {
132
+ url = '/10a/v1/device/energy';
133
+ }
134
+ else {
135
+ url = '/v1/device/energy';
136
+ }
137
+ const body = this.deviceType === 'wifi-switch-1.3' ? null : {
138
+ ...helpers_1.Helpers.reqBody(this.manager, 'energy'),
139
+ uuid: this.uuid
140
+ };
141
+ const [response] = await helpers_1.Helpers.callApi(url, this.deviceType === 'wifi-switch-1.3' ? 'get' : 'post', body, helpers_1.Helpers.reqHeaders(this.manager));
142
+ // Handle different response formats
143
+ if ((response === null || response === void 0 ? void 0 : response.code) === 0 && response.result) {
91
144
  this.energy = response.result;
92
145
  logger_1.logger.debug(`[${this.deviceName}] Successfully updated energy data`);
93
146
  }
147
+ else if ((response === null || response === void 0 ? void 0 : response.code) === 0) {
148
+ // Some devices return data directly in response
149
+ this.energy = {
150
+ power: response.power || '0',
151
+ voltage: response.voltage || '0',
152
+ energy: response.energy || '0',
153
+ energyToday: response.energy || '0',
154
+ energyWeek: response.energy || '0',
155
+ energyMonth: response.energy || '0',
156
+ energyYear: response.energy || '0'
157
+ };
158
+ logger_1.logger.debug(`[${this.deviceName}] Successfully updated energy data`);
159
+ }
94
160
  else {
95
- logger_1.logger.error(`[${this.deviceName}] Failed to update energy data: ${JSON.stringify(response)}`);
161
+ // For error responses, set defaults but don't log as error
162
+ this.energy = {
163
+ power: '0',
164
+ voltage: '0',
165
+ energy: '0',
166
+ energyToday: '0',
167
+ energyWeek: '0',
168
+ energyMonth: '0',
169
+ energyYear: '0'
170
+ };
171
+ logger_1.logger.debug(`[${this.deviceName}] Failed to update energy data: ${JSON.stringify(response)}`);
96
172
  }
97
173
  }
98
174
  /**
@@ -112,12 +188,12 @@ class VeSyncOutlet extends vesyncBaseDevice_1.VeSyncBaseDevice {
112
188
  }
113
189
  await this.updateEnergy();
114
190
  return {
115
- power: this.energy.power || 'Not available',
116
- voltage: this.energy.voltage || 'Not available',
117
- energy_today: this.energy.energyToday || 'Not available',
118
- energy_week: this.energy.energyWeek || 'Not available',
119
- energy_month: this.energy.energyMonth || 'Not available',
120
- energy_year: this.energy.energyYear || 'Not available'
191
+ power: this.energy.power || '0',
192
+ voltage: this.energy.voltage || '0',
193
+ energy_today: this.energy.energyToday || '0',
194
+ energy_week: this.energy.energyWeek || '0',
195
+ energy_month: this.energy.energyMonth || '0',
196
+ energy_year: this.energy.energyYear || '0'
121
197
  };
122
198
  }
123
199
  /**
@@ -159,11 +235,12 @@ class VeSyncOutlet extends vesyncBaseDevice_1.VeSyncBaseDevice {
159
235
  };
160
236
  const [response] = await helpers_1.Helpers.callApi(isLegacyDevice ? `/${this.getApiPrefix()}/energy/week` : `/${this.getApiPrefix()}/energyweek`, isLegacyDevice ? 'get' : 'post', body, helpers_1.Helpers.reqHeaders(this.manager));
161
237
  if ((response === null || response === void 0 ? void 0 : response.code) === 0) {
162
- this.energy.week = response.result;
238
+ this.energy.week = response.result || response.energyWeek || '0';
163
239
  logger_1.logger.debug(`[${this.deviceName}] Successfully retrieved weekly energy data`);
164
240
  }
165
241
  else {
166
- logger_1.logger.error(`[${this.deviceName}] Failed to get weekly energy data: ${JSON.stringify(response)}`);
242
+ this.energy.week = '0';
243
+ logger_1.logger.debug(`[${this.deviceName}] Failed to get weekly energy data: ${JSON.stringify(response)}`);
167
244
  }
168
245
  }
169
246
  /**
@@ -182,11 +259,12 @@ class VeSyncOutlet extends vesyncBaseDevice_1.VeSyncBaseDevice {
182
259
  };
183
260
  const [response] = await helpers_1.Helpers.callApi(isLegacyDevice ? `/${this.getApiPrefix()}/energy/month` : `/${this.getApiPrefix()}/energymonth`, isLegacyDevice ? 'get' : 'post', body, helpers_1.Helpers.reqHeaders(this.manager));
184
261
  if ((response === null || response === void 0 ? void 0 : response.code) === 0) {
185
- this.energy.month = response.result;
262
+ this.energy.month = response.result || response.energyMonth || '0';
186
263
  logger_1.logger.debug(`[${this.deviceName}] Successfully retrieved monthly energy data`);
187
264
  }
188
265
  else {
189
- logger_1.logger.error(`[${this.deviceName}] Failed to get monthly energy data: ${JSON.stringify(response)}`);
266
+ this.energy.month = '0';
267
+ logger_1.logger.debug(`[${this.deviceName}] Failed to get monthly energy data: ${JSON.stringify(response)}`);
190
268
  }
191
269
  }
192
270
  /**
@@ -205,11 +283,12 @@ class VeSyncOutlet extends vesyncBaseDevice_1.VeSyncBaseDevice {
205
283
  };
206
284
  const [response] = await helpers_1.Helpers.callApi(isLegacyDevice ? `/${this.getApiPrefix()}/energy/year` : `/${this.getApiPrefix()}/energyyear`, isLegacyDevice ? 'get' : 'post', body, helpers_1.Helpers.reqHeaders(this.manager));
207
285
  if ((response === null || response === void 0 ? void 0 : response.code) === 0) {
208
- this.energy.year = response.result;
286
+ this.energy.year = response.result || response.energyYear || '0';
209
287
  logger_1.logger.debug(`[${this.deviceName}] Successfully retrieved yearly energy data`);
210
288
  }
211
289
  else {
212
- logger_1.logger.error(`[${this.deviceName}] Failed to get yearly energy data: ${JSON.stringify(response)}`);
290
+ this.energy.year = '0';
291
+ logger_1.logger.debug(`[${this.deviceName}] Failed to get yearly energy data: ${JSON.stringify(response)}`);
213
292
  }
214
293
  }
215
294
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsvesync",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
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",
@@ -66,7 +66,7 @@ export abstract class VeSyncOutlet extends VeSyncBaseDevice {
66
66
 
67
67
  let url: string;
68
68
  if (this.deviceType === 'wifi-switch-1.3') {
69
- url = `/v1/device/${this.deviceType}-${this.cid}/detail`;
69
+ url = `/v1/device/wifi-switch-1.3-${this.cid}/detail`;
70
70
  } else if (this.deviceType.startsWith('ESO15')) {
71
71
  url = '/outdoorsocket15a/v1/device/devicedetail';
72
72
  } else if (this.deviceType.startsWith('ESW15')) {
@@ -84,12 +84,47 @@ export abstract class VeSyncOutlet extends VeSyncBaseDevice {
84
84
  Helpers.reqHeaders(this.manager)
85
85
  );
86
86
 
87
- if (response?.code === 0) {
88
- this.details = response.result;
89
- this.deviceStatus = response.result.deviceStatus;
87
+ if (!response) {
88
+ logger.debug(`[${this.deviceName}] No response received from API`);
89
+ return;
90
+ }
91
+
92
+ // Handle error responses
93
+ if (response.error) {
94
+ logger.debug(`[${this.deviceName}] Failed to get outlet details: ${JSON.stringify(response)}`);
95
+ return;
96
+ }
97
+
98
+ // Handle successful responses
99
+ if (response.code === 0) {
100
+ this.details = response;
101
+
102
+ // Handle outdoor plugs with subdevices
103
+ if (response.subDevices) {
104
+ const subDevice = response.subDevices.find(
105
+ (dev: any) => dev.subDeviceName === this.deviceName
106
+ );
107
+ if (subDevice) {
108
+ this.deviceStatus = subDevice.subDeviceStatus;
109
+ logger.debug(`[${this.deviceName}] Successfully retrieved subdevice status: ${this.deviceStatus}`);
110
+ return;
111
+ }
112
+ }
113
+
114
+ // Handle regular devices
115
+ if (response.deviceStatus !== undefined) {
116
+ this.deviceStatus = response.deviceStatus;
117
+ } else if (response.status !== undefined) {
118
+ this.deviceStatus = response.status;
119
+ } else if (response.power !== undefined) {
120
+ this.deviceStatus = response.power === 'on' ? 'on' : 'off';
121
+ } else {
122
+ logger.debug(`[${this.deviceName}] Device status not found in response: ${JSON.stringify(response)}`);
123
+ return;
124
+ }
90
125
  logger.debug(`[${this.deviceName}] Successfully retrieved outlet details`);
91
126
  } else {
92
- logger.error(`[${this.deviceName}] Failed to get outlet details: ${JSON.stringify(response)}`);
127
+ logger.debug(`[${this.deviceName}] Failed to get outlet details: ${JSON.stringify(response)}`);
93
128
  }
94
129
  }
95
130
 
@@ -103,19 +138,61 @@ export abstract class VeSyncOutlet extends VeSyncBaseDevice {
103
138
  }
104
139
 
105
140
  logger.debug(`[${this.deviceName}] Updating energy data`);
106
- const url = `/v1/${this.deviceType}/${this.deviceType}-${this.cid}/energy/detail`;
141
+
142
+ // Different endpoints for different device types
143
+ let url: string;
144
+ if (this.deviceType === 'wifi-switch-1.3') {
145
+ url = `/v1/device/${this.deviceType}-${this.cid}/energy/detail`;
146
+ } else if (this.deviceType.startsWith('ESO15')) {
147
+ url = '/outdoorsocket15a/v1/device/energy';
148
+ } else if (this.deviceType.startsWith('ESW15')) {
149
+ url = '/15a/v1/device/energy';
150
+ } else if (this.deviceType.startsWith('ESW03') || this.deviceType.startsWith('ESW01')) {
151
+ url = '/10a/v1/device/energy';
152
+ } else {
153
+ url = '/v1/device/energy';
154
+ }
155
+
156
+ const body = this.deviceType === 'wifi-switch-1.3' ? null : {
157
+ ...Helpers.reqBody(this.manager, 'energy'),
158
+ uuid: this.uuid
159
+ };
160
+
107
161
  const [response] = await Helpers.callApi(
108
162
  url,
109
- 'get',
110
- null,
163
+ this.deviceType === 'wifi-switch-1.3' ? 'get' : 'post',
164
+ body,
111
165
  Helpers.reqHeaders(this.manager)
112
166
  );
113
167
 
114
- if (response?.code === 0) {
168
+ // Handle different response formats
169
+ if (response?.code === 0 && response.result) {
115
170
  this.energy = response.result;
116
171
  logger.debug(`[${this.deviceName}] Successfully updated energy data`);
172
+ } else if (response?.code === 0) {
173
+ // Some devices return data directly in response
174
+ this.energy = {
175
+ power: response.power || '0',
176
+ voltage: response.voltage || '0',
177
+ energy: response.energy || '0',
178
+ energyToday: response.energy || '0',
179
+ energyWeek: response.energy || '0',
180
+ energyMonth: response.energy || '0',
181
+ energyYear: response.energy || '0'
182
+ };
183
+ logger.debug(`[${this.deviceName}] Successfully updated energy data`);
117
184
  } else {
118
- logger.error(`[${this.deviceName}] Failed to update energy data: ${JSON.stringify(response)}`);
185
+ // For error responses, set defaults but don't log as error
186
+ this.energy = {
187
+ power: '0',
188
+ voltage: '0',
189
+ energy: '0',
190
+ energyToday: '0',
191
+ energyWeek: '0',
192
+ energyMonth: '0',
193
+ energyYear: '0'
194
+ };
195
+ logger.debug(`[${this.deviceName}] Failed to update energy data: ${JSON.stringify(response)}`);
119
196
  }
120
197
  }
121
198
 
@@ -137,12 +214,12 @@ export abstract class VeSyncOutlet extends VeSyncBaseDevice {
137
214
 
138
215
  await this.updateEnergy();
139
216
  return {
140
- power: this.energy.power || 'Not available',
141
- voltage: this.energy.voltage || 'Not available',
142
- energy_today: this.energy.energyToday || 'Not available',
143
- energy_week: this.energy.energyWeek || 'Not available',
144
- energy_month: this.energy.energyMonth || 'Not available',
145
- energy_year: this.energy.energyYear || 'Not available'
217
+ power: this.energy.power || '0',
218
+ voltage: this.energy.voltage || '0',
219
+ energy_today: this.energy.energyToday || '0',
220
+ energy_week: this.energy.energyWeek || '0',
221
+ energy_month: this.energy.energyMonth || '0',
222
+ energy_year: this.energy.energyYear || '0'
146
223
  };
147
224
  }
148
225
 
@@ -193,10 +270,11 @@ export abstract class VeSyncOutlet extends VeSyncBaseDevice {
193
270
  );
194
271
 
195
272
  if (response?.code === 0) {
196
- this.energy.week = response.result;
273
+ this.energy.week = response.result || response.energyWeek || '0';
197
274
  logger.debug(`[${this.deviceName}] Successfully retrieved weekly energy data`);
198
275
  } else {
199
- logger.error(`[${this.deviceName}] Failed to get weekly energy data: ${JSON.stringify(response)}`);
276
+ this.energy.week = '0';
277
+ logger.debug(`[${this.deviceName}] Failed to get weekly energy data: ${JSON.stringify(response)}`);
200
278
  }
201
279
  }
202
280
 
@@ -224,10 +302,11 @@ export abstract class VeSyncOutlet extends VeSyncBaseDevice {
224
302
  );
225
303
 
226
304
  if (response?.code === 0) {
227
- this.energy.month = response.result;
305
+ this.energy.month = response.result || response.energyMonth || '0';
228
306
  logger.debug(`[${this.deviceName}] Successfully retrieved monthly energy data`);
229
307
  } else {
230
- logger.error(`[${this.deviceName}] Failed to get monthly energy data: ${JSON.stringify(response)}`);
308
+ this.energy.month = '0';
309
+ logger.debug(`[${this.deviceName}] Failed to get monthly energy data: ${JSON.stringify(response)}`);
231
310
  }
232
311
  }
233
312
 
@@ -255,10 +334,11 @@ export abstract class VeSyncOutlet extends VeSyncBaseDevice {
255
334
  );
256
335
 
257
336
  if (response?.code === 0) {
258
- this.energy.year = response.result;
337
+ this.energy.year = response.result || response.energyYear || '0';
259
338
  logger.debug(`[${this.deviceName}] Successfully retrieved yearly energy data`);
260
339
  } else {
261
- logger.error(`[${this.deviceName}] Failed to get yearly energy data: ${JSON.stringify(response)}`);
340
+ this.energy.year = '0';
341
+ logger.debug(`[${this.deviceName}] Failed to get yearly energy data: ${JSON.stringify(response)}`);
262
342
  }
263
343
  }
264
344