tsvesync 1.0.92 → 1.0.94

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.
@@ -53,10 +53,35 @@ class VeSyncAir131 extends vesyncFan_1.VeSyncFan {
53
53
  // Check if data is in response.result or directly in response
54
54
  const data = response.result || response;
55
55
  this.deviceStatus = data.deviceStatus === 'on' ? 'on' : 'off';
56
+ // Parse filter life with proper object/value handling
57
+ let filterLife = 0;
58
+ if (data.filterLife !== undefined) {
59
+ if (typeof data.filterLife === 'object' && data.filterLife !== null) {
60
+ // API returns object like {percent: 85}
61
+ filterLife = data.filterLife;
62
+ logger_1.logger.debug(`${this.deviceName}: Parsed filter life from filterLife object: ${JSON.stringify(data.filterLife)}`);
63
+ }
64
+ else if (typeof data.filterLife === 'number') {
65
+ // API returns direct number
66
+ filterLife = data.filterLife;
67
+ logger_1.logger.debug(`${this.deviceName}: Parsed filter life from filterLife number: ${data.filterLife}%`);
68
+ }
69
+ }
70
+ else if (data.filter_life !== undefined) {
71
+ // Fallback to filter_life field
72
+ filterLife = data.filter_life;
73
+ logger_1.logger.debug(`${this.deviceName}: Parsed filter life from filter_life fallback: ${data.filter_life}%`);
74
+ }
75
+ else {
76
+ logger_1.logger.debug(`${this.deviceName}: No filter life data found in API response`);
77
+ if (logger_1.logger.getLevel && logger_1.logger.getLevel() !== undefined && logger_1.logger.getLevel() <= 0) {
78
+ logger_1.logger.debug(`${this.deviceName}: API response structure:`, JSON.stringify(data, null, 2));
79
+ }
80
+ }
56
81
  this.details = {
57
82
  mode: data.mode || 'manual', // Default to manual if not specified
58
83
  speed: data.level || 0,
59
- filter_life: data.filterLife || data.filter_life || 0,
84
+ filter_life: filterLife,
60
85
  screen_status: data.screenStatus || 'off',
61
86
  child_lock: data.childLock || false,
62
87
  air_quality: data.airQuality || 'unknown',
@@ -127,7 +127,7 @@ class VeSyncAirBaseV2 extends airBypass_1.VeSyncAirBypass {
127
127
  * Build purifier dictionary
128
128
  */
129
129
  buildPurifierDict(devDict) {
130
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
130
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
131
131
  this.connectionStatus = 'online';
132
132
  const powerSwitch = Boolean((_a = devDict.powerSwitch) !== null && _a !== void 0 ? _a : 0);
133
133
  this.enabled = powerSwitch;
@@ -135,19 +135,35 @@ class VeSyncAirBaseV2 extends airBypass_1.VeSyncAirBypass {
135
135
  this.mode = (_b = devDict.workMode) !== null && _b !== void 0 ? _b : 'manual';
136
136
  this.speed = (_c = devDict.fanSpeedLevel) !== null && _c !== void 0 ? _c : 0;
137
137
  this.setSpeedLevel = (_d = devDict.manualSpeedLevel) !== null && _d !== void 0 ? _d : 1;
138
+ // Parse filter life with proper fallback handling and logging
139
+ let filterLife = 0;
140
+ if (devDict.filterLifePercent !== undefined) {
141
+ filterLife = devDict.filterLifePercent;
142
+ logger_1.logger.debug(`${this.deviceName}: Parsed filter life from filterLifePercent: ${filterLife}%`);
143
+ }
144
+ else if (devDict.filter_life !== undefined) {
145
+ filterLife = devDict.filter_life;
146
+ logger_1.logger.debug(`${this.deviceName}: Parsed filter life from filter_life fallback: ${filterLife}%`);
147
+ }
148
+ else {
149
+ logger_1.logger.debug(`${this.deviceName}: No filter life data found in API response`);
150
+ if (logger_1.logger.getLevel && logger_1.logger.getLevel() !== undefined && logger_1.logger.getLevel() <= 0) {
151
+ logger_1.logger.debug(`${this.deviceName}: Device dict structure:`, JSON.stringify(devDict, null, 2));
152
+ }
153
+ }
138
154
  this.details = {
139
155
  ...this.details,
140
- filter_life: (_e = devDict.filterLifePercent) !== null && _e !== void 0 ? _e : 0,
141
- child_lock: Boolean((_f = devDict.childLockSwitch) !== null && _f !== void 0 ? _f : 0),
142
- display: Boolean((_g = devDict.screenState) !== null && _g !== void 0 ? _g : 0),
143
- light_detection_switch: Boolean((_h = devDict.lightDetectionSwitch) !== null && _h !== void 0 ? _h : 0),
144
- environment_light_state: Boolean((_j = devDict.environmentLightState) !== null && _j !== void 0 ? _j : 0),
145
- screen_switch: Boolean((_k = devDict.screenSwitch) !== null && _k !== void 0 ? _k : 0),
146
- screenStatus: Boolean((_l = devDict.screenSwitch) !== null && _l !== void 0 ? _l : 0) ? 'on' : 'off'
156
+ filter_life: filterLife,
157
+ child_lock: Boolean((_e = devDict.childLockSwitch) !== null && _e !== void 0 ? _e : 0),
158
+ display: Boolean((_f = devDict.screenState) !== null && _f !== void 0 ? _f : 0),
159
+ light_detection_switch: Boolean((_g = devDict.lightDetectionSwitch) !== null && _g !== void 0 ? _g : 0),
160
+ environment_light_state: Boolean((_h = devDict.environmentLightState) !== null && _h !== void 0 ? _h : 0),
161
+ screen_switch: Boolean((_j = devDict.screenSwitch) !== null && _j !== void 0 ? _j : 0),
162
+ screenStatus: Boolean((_k = devDict.screenSwitch) !== null && _k !== void 0 ? _k : 0) ? 'on' : 'off'
147
163
  };
148
164
  if (this.hasFeature('air_quality')) {
149
- this.details.air_quality_value = (_m = devDict.PM25) !== null && _m !== void 0 ? _m : 0;
150
- this.details.air_quality = (_o = devDict.AQLevel) !== null && _o !== void 0 ? _o : 0;
165
+ this.details.air_quality_value = (_l = devDict.PM25) !== null && _l !== void 0 ? _l : 0;
166
+ this.details.air_quality = (_m = devDict.AQLevel) !== null && _m !== void 0 ? _m : 0;
151
167
  }
152
168
  if ('PM1' in devDict)
153
169
  this.details.pm1 = devDict.PM1;
@@ -159,11 +175,11 @@ class VeSyncAirBaseV2 extends airBypass_1.VeSyncAirBypass {
159
175
  this.details.fan_rotate_angle = devDict.fanRotateAngle;
160
176
  if ('filterOpenState' in devDict)
161
177
  this.details.filter_open_state = Boolean(devDict.filterOpenState);
162
- if (((_p = devDict.timerRemain) !== null && _p !== void 0 ? _p : 0) > 0) {
178
+ if (((_o = devDict.timerRemain) !== null && _o !== void 0 ? _o : 0) > 0) {
163
179
  this.timer = { duration: devDict.timerRemain, action: 'off' };
164
180
  }
165
181
  if (typeof devDict.autoPreference === 'object' && devDict.autoPreference) {
166
- this.details.auto_preference_type = (_r = (_q = devDict.autoPreference) === null || _q === void 0 ? void 0 : _q.autoPreferenceType) !== null && _r !== void 0 ? _r : 'default';
182
+ this.details.auto_preference_type = (_q = (_p = devDict.autoPreference) === null || _p === void 0 ? void 0 : _p.autoPreferenceType) !== null && _q !== void 0 ? _q : 'default';
167
183
  }
168
184
  else {
169
185
  this.details.auto_preference_type = null;
@@ -53,10 +53,26 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
53
53
  const result = (_a = response === null || response === void 0 ? void 0 : response.result) === null || _a === void 0 ? void 0 : _a.result;
54
54
  if (result) {
55
55
  this.deviceStatus = result.enabled ? 'on' : 'off';
56
+ // Parse filter life with fallback handling
57
+ let filterLife = 0;
58
+ if (result.filterLifePercent !== undefined) {
59
+ filterLife = result.filterLifePercent;
60
+ logger_1.logger.debug(`${this.deviceName}: Parsed filter life from filterLifePercent: ${filterLife}%`);
61
+ }
62
+ else if (result.filter_life !== undefined) {
63
+ filterLife = result.filter_life;
64
+ logger_1.logger.debug(`${this.deviceName}: Parsed filter life from filter_life: ${filterLife}%`);
65
+ }
66
+ else {
67
+ logger_1.logger.debug(`${this.deviceName}: No filter life data found in API response`);
68
+ if (logger_1.logger.getLevel && logger_1.logger.getLevel() !== undefined && logger_1.logger.getLevel() <= 0) {
69
+ logger_1.logger.debug(`${this.deviceName}: API response structure:`, JSON.stringify(result, null, 2));
70
+ }
71
+ }
56
72
  this.details = {
57
73
  mode: result.mode || '',
58
74
  speed: result.level || 0,
59
- filter_life: result.filter_life || 0,
75
+ filter_life: filterLife,
60
76
  screen_status: result.display ? 'on' : 'off',
61
77
  child_lock: result.child_lock || false,
62
78
  air_quality: result.air_quality || 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsvesync",
3
- "version": "1.0.92",
3
+ "version": "1.0.94",
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",
@@ -64,10 +64,34 @@ export class VeSyncAir131 extends VeSyncFan {
64
64
  const data = response.result || response;
65
65
 
66
66
  this.deviceStatus = data.deviceStatus === 'on' ? 'on' : 'off';
67
+
68
+ // Parse filter life with proper object/value handling
69
+ let filterLife: number | { percent: number } = 0;
70
+ if (data.filterLife !== undefined) {
71
+ if (typeof data.filterLife === 'object' && data.filterLife !== null) {
72
+ // API returns object like {percent: 85}
73
+ filterLife = data.filterLife;
74
+ logger.debug(`${this.deviceName}: Parsed filter life from filterLife object: ${JSON.stringify(data.filterLife)}`);
75
+ } else if (typeof data.filterLife === 'number') {
76
+ // API returns direct number
77
+ filterLife = data.filterLife;
78
+ logger.debug(`${this.deviceName}: Parsed filter life from filterLife number: ${data.filterLife}%`);
79
+ }
80
+ } else if (data.filter_life !== undefined) {
81
+ // Fallback to filter_life field
82
+ filterLife = data.filter_life;
83
+ logger.debug(`${this.deviceName}: Parsed filter life from filter_life fallback: ${data.filter_life}%`);
84
+ } else {
85
+ logger.debug(`${this.deviceName}: No filter life data found in API response`);
86
+ if (logger.getLevel && logger.getLevel() !== undefined && logger.getLevel()! <= 0) {
87
+ logger.debug(`${this.deviceName}: API response structure:`, JSON.stringify(data, null, 2));
88
+ }
89
+ }
90
+
67
91
  this.details = {
68
92
  mode: data.mode || 'manual', // Default to manual if not specified
69
93
  speed: data.level || 0,
70
- filter_life: data.filterLife || data.filter_life || 0,
94
+ filter_life: filterLife,
71
95
  screen_status: data.screenStatus || 'off',
72
96
  child_lock: data.childLock || false,
73
97
  air_quality: data.airQuality || 'unknown',
@@ -163,9 +163,24 @@ export class VeSyncAirBaseV2 extends VeSyncAirBypass {
163
163
  this.speed = devDict.fanSpeedLevel ?? 0;
164
164
  this.setSpeedLevel = devDict.manualSpeedLevel ?? 1;
165
165
 
166
+ // Parse filter life with proper fallback handling and logging
167
+ let filterLife = 0;
168
+ if (devDict.filterLifePercent !== undefined) {
169
+ filterLife = devDict.filterLifePercent;
170
+ logger.debug(`${this.deviceName}: Parsed filter life from filterLifePercent: ${filterLife}%`);
171
+ } else if (devDict.filter_life !== undefined) {
172
+ filterLife = devDict.filter_life;
173
+ logger.debug(`${this.deviceName}: Parsed filter life from filter_life fallback: ${filterLife}%`);
174
+ } else {
175
+ logger.debug(`${this.deviceName}: No filter life data found in API response`);
176
+ if (logger.getLevel && logger.getLevel() !== undefined && logger.getLevel()! <= 0) {
177
+ logger.debug(`${this.deviceName}: Device dict structure:`, JSON.stringify(devDict, null, 2));
178
+ }
179
+ }
180
+
166
181
  this.details = {
167
182
  ...this.details,
168
- filter_life: devDict.filterLifePercent ?? 0,
183
+ filter_life: filterLife,
169
184
  child_lock: Boolean(devDict.childLockSwitch ?? 0),
170
185
  display: Boolean(devDict.screenState ?? 0),
171
186
  light_detection_switch: Boolean(devDict.lightDetectionSwitch ?? 0),
@@ -61,10 +61,26 @@ export class VeSyncAirBypass extends VeSyncFan {
61
61
  const result = response?.result?.result;
62
62
  if (result) {
63
63
  this.deviceStatus = result.enabled ? 'on' : 'off';
64
+
65
+ // Parse filter life with fallback handling
66
+ let filterLife = 0;
67
+ if (result.filterLifePercent !== undefined) {
68
+ filterLife = result.filterLifePercent;
69
+ logger.debug(`${this.deviceName}: Parsed filter life from filterLifePercent: ${filterLife}%`);
70
+ } else if (result.filter_life !== undefined) {
71
+ filterLife = result.filter_life;
72
+ logger.debug(`${this.deviceName}: Parsed filter life from filter_life: ${filterLife}%`);
73
+ } else {
74
+ logger.debug(`${this.deviceName}: No filter life data found in API response`);
75
+ if (logger.getLevel && logger.getLevel() !== undefined && logger.getLevel()! <= 0) {
76
+ logger.debug(`${this.deviceName}: API response structure:`, JSON.stringify(result, null, 2));
77
+ }
78
+ }
79
+
64
80
  this.details = {
65
81
  mode: result.mode || '',
66
82
  speed: result.level || 0,
67
- filter_life: result.filter_life || 0,
83
+ filter_life: filterLife,
68
84
  screen_status: result.display ? 'on' : 'off',
69
85
  child_lock: result.child_lock || false,
70
86
  air_quality: result.air_quality || 0,