homebridge-tsvesync 1.0.41 → 1.0.43
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 +1 -1
- package/dist/platform.d.ts +2 -0
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +12 -4
- package/dist/platform.js.map +1 -1
- package/dist/utils/api-proxy.d.ts +4 -0
- package/dist/utils/api-proxy.d.ts.map +1 -0
- package/dist/utils/api-proxy.js +132 -0
- package/dist/utils/api-proxy.js.map +1 -0
- package/dist/utils/device-factory.js +1 -1
- package/dist/utils/device-factory.js.map +1 -1
- package/package.json +3 -2
- package/scripts/get_response.sh +4 -2
- package/src/platform.ts +13 -3
- package/src/utils/api-proxy.ts +160 -0
- package/src/utils/device-factory.ts +1 -1
package/README.md
CHANGED
|
@@ -82,7 +82,7 @@ All outlets are exposed as HomeKit outlets with the following features:
|
|
|
82
82
|
* Power/Energy monitoring
|
|
83
83
|
* Voltage monitoring
|
|
84
84
|
|
|
85
|
-
- 10A Outlets (ESW03-USA, ESW01-EU)
|
|
85
|
+
- 10A Outlets (ESW03-USA, ESW01-EU, ESW10-USA)
|
|
86
86
|
* On/Off control
|
|
87
87
|
* Power/Energy monitoring
|
|
88
88
|
* Voltage monitoring
|
package/dist/platform.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ export declare class TSVESyncPlatform implements DynamicPlatformPlugin {
|
|
|
22
22
|
private initializationResolver;
|
|
23
23
|
private isInitialized;
|
|
24
24
|
private readonly logger;
|
|
25
|
+
private readonly TOKEN_EXPIRY;
|
|
26
|
+
private lastTokenRefresh;
|
|
25
27
|
constructor(log: Logger, config: PlatformConfig, api: API);
|
|
26
28
|
/**
|
|
27
29
|
* Check if platform is ready
|
package/dist/platform.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,qBAAqB,EAAE,MAAM,EAAE,iBAAiB,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,qBAAqB,EAAE,MAAM,EAAE,iBAAiB,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAQ5H;;;;GAIG;AACH,qBAAa,gBAAiB,YAAW,qBAAqB;aAsB1C,GAAG,EAAE,MAAM;aACX,MAAM,EAAE,cAAc;aACtB,GAAG,EAAE,GAAG;IAvB1B,SAAgB,OAAO,EAAE,OAAO,OAAO,CAAwB;IAC/D,SAAgB,cAAc,EAAE,OAAO,cAAc,CAA+B;IAGpF,SAAgB,WAAW,EAAE,iBAAiB,EAAE,CAAM;IACtD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAyC;IAE3E,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,oBAAoB,CAAC,CAAiB;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,qBAAqB,CAAgB;IAC7C,OAAO,CAAC,sBAAsB,CAAc;IAC5C,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkB;IAC/C,OAAO,CAAC,gBAAgB,CAAqB;gBAG3B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,GAAG;IAqE1B;;OAEG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBrC;;OAEG;YACW,kBAAkB;IAmChC;;OAEG;IACH,kBAAkB,CAAC,SAAS,EAAE,iBAAiB;IAK/C;;OAEG;IACH,OAAO,CAAC,aAAa;IASrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;OAEG;YACW,WAAW;IAwDzB;;OAEG;YACW,kBAAkB;IAIhC;;OAEG;IACG,eAAe;IA8GrB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;CAO3B"}
|
package/dist/platform.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TSVESyncPlatform = void 0;
|
|
4
4
|
const settings_1 = require("./settings");
|
|
5
|
-
const tsvesync_1 = require("tsvesync");
|
|
6
5
|
const device_factory_1 = require("./utils/device-factory");
|
|
7
6
|
const logger_1 = require("./utils/logger");
|
|
7
|
+
const api_proxy_1 = require("./utils/api-proxy");
|
|
8
8
|
/**
|
|
9
9
|
* HomebridgePlatform
|
|
10
10
|
* This class is the main constructor for your plugin, this is where you should
|
|
@@ -23,6 +23,8 @@ class TSVESyncPlatform {
|
|
|
23
23
|
this.lastLoginAttempt = new Date(0);
|
|
24
24
|
this.loginBackoffTime = 10000; // Start with 10 seconds
|
|
25
25
|
this.isInitialized = false;
|
|
26
|
+
this.TOKEN_EXPIRY = 60 * 60 * 1000; // 1 hour in milliseconds
|
|
27
|
+
this.lastTokenRefresh = new Date(0);
|
|
26
28
|
// Create initialization promise
|
|
27
29
|
this.initializationPromise = new Promise((resolve) => {
|
|
28
30
|
this.initializationResolver = resolve;
|
|
@@ -38,7 +40,7 @@ class TSVESyncPlatform {
|
|
|
38
40
|
return;
|
|
39
41
|
}
|
|
40
42
|
// Initialize VeSync client with all configuration
|
|
41
|
-
this.client =
|
|
43
|
+
this.client = (0, api_proxy_1.createRateLimitedVeSync)(config.username, config.password, Intl.DateTimeFormat().resolvedOptions().timeZone, this.debug, true, // redact sensitive info
|
|
42
44
|
config.apiUrl, this.logger);
|
|
43
45
|
this.logger.debug('Initialized platform with config:', {
|
|
44
46
|
name: config.name,
|
|
@@ -170,6 +172,11 @@ class TSVESyncPlatform {
|
|
|
170
172
|
*/
|
|
171
173
|
async ensureLogin(forceLogin = false) {
|
|
172
174
|
var _a;
|
|
175
|
+
// Check if token needs refresh
|
|
176
|
+
const timeSinceLastRefresh = Date.now() - this.lastTokenRefresh.getTime();
|
|
177
|
+
if (!forceLogin && timeSinceLastRefresh < this.TOKEN_EXPIRY) {
|
|
178
|
+
return true; // Token is still valid
|
|
179
|
+
}
|
|
173
180
|
let isLoggedIn = false;
|
|
174
181
|
while (!isLoggedIn) { // Keep trying until successful
|
|
175
182
|
try {
|
|
@@ -181,7 +188,7 @@ class TSVESyncPlatform {
|
|
|
181
188
|
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
182
189
|
}
|
|
183
190
|
// Need to login again
|
|
184
|
-
this.logger.debug(forceLogin ? 'Forcing new login to VeSync API' : '
|
|
191
|
+
this.logger.debug(forceLogin ? 'Forcing new login to VeSync API' : 'Refreshing VeSync API token');
|
|
185
192
|
this.lastLoginAttempt = new Date();
|
|
186
193
|
const loginResult = await this.client.login();
|
|
187
194
|
if (!loginResult) {
|
|
@@ -189,8 +196,9 @@ class TSVESyncPlatform {
|
|
|
189
196
|
this.loginBackoffTime = Math.min(this.loginBackoffTime * 2, 300000);
|
|
190
197
|
continue; // Try again after backoff
|
|
191
198
|
}
|
|
192
|
-
// Reset backoff on successful login
|
|
199
|
+
// Reset backoff and update token refresh time on successful login
|
|
193
200
|
this.loginBackoffTime = 10000;
|
|
201
|
+
this.lastTokenRefresh = new Date();
|
|
194
202
|
isLoggedIn = true;
|
|
195
203
|
return true;
|
|
196
204
|
}
|
package/dist/platform.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { VeSync } from 'tsvesync';
|
|
2
|
+
import { PluginLogger } from './logger';
|
|
3
|
+
export declare const createRateLimitedVeSync: (username: string, password: string, timeZone: string, debug?: boolean, redact?: boolean, apiUrl?: string, customLogger?: PluginLogger) => VeSync;
|
|
4
|
+
//# sourceMappingURL=api-proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-proxy.d.ts","sourceRoot":"","sources":["../../src/utils/api-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAkJxC,eAAO,MAAM,uBAAuB,aACxB,MAAM,YACN,MAAM,YACN,MAAM,UACR,OAAO,WACN,OAAO,WACP,MAAM,iBACA,YAAY,KAC1B,MAIF,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRateLimitedVeSync = void 0;
|
|
4
|
+
const tsvesync_1 = require("tsvesync");
|
|
5
|
+
const logger_1 = require("./logger");
|
|
6
|
+
const RATE_LIMIT_DELAY = 500; // 500ms between API calls
|
|
7
|
+
const DEBOUNCE_DELAY = 5000; // 5 second debounce for rapid changes
|
|
8
|
+
class RateLimiter {
|
|
9
|
+
constructor(logger) {
|
|
10
|
+
this.logger = logger;
|
|
11
|
+
this.lastCallTime = 0;
|
|
12
|
+
this.lastMethodName = '';
|
|
13
|
+
this.debounceTimers = new Map();
|
|
14
|
+
}
|
|
15
|
+
async rateLimit(methodName) {
|
|
16
|
+
const now = Date.now();
|
|
17
|
+
const timeSinceLastCall = now - this.lastCallTime;
|
|
18
|
+
if (timeSinceLastCall < RATE_LIMIT_DELAY) {
|
|
19
|
+
const waitTime = RATE_LIMIT_DELAY - timeSinceLastCall;
|
|
20
|
+
this.logger.debug(`Rate limiting '${methodName}' - waiting ${waitTime}ms before next API call (previous call was '${this.lastMethodName}' ${timeSinceLastCall}ms ago)`);
|
|
21
|
+
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
22
|
+
}
|
|
23
|
+
this.lastMethodName = methodName;
|
|
24
|
+
this.lastCallTime = Date.now();
|
|
25
|
+
this.logger.debug(`Executing API call '${methodName}'`);
|
|
26
|
+
}
|
|
27
|
+
getDebounceKey(methodName, deviceId, args) {
|
|
28
|
+
const paramsKey = args.length > 0 ? `-${JSON.stringify(args)}` : '';
|
|
29
|
+
return deviceId ? `${methodName}-${deviceId}${paramsKey}` : `${methodName}${paramsKey}`;
|
|
30
|
+
}
|
|
31
|
+
debounce(methodName, deviceId, fn, args) {
|
|
32
|
+
const key = this.getDebounceKey(methodName, deviceId, args);
|
|
33
|
+
const pending = this.debounceTimers.get(key);
|
|
34
|
+
// If there's an active debounce timer and a call is in progress, skip this call
|
|
35
|
+
if (pending === null || pending === void 0 ? void 0 : pending.inProgress) {
|
|
36
|
+
this.logger.debug(`Skipping '${methodName}'${deviceId ? ` for device ${deviceId}` : ''} with args ${JSON.stringify(args)} - call already in progress`);
|
|
37
|
+
return Promise.resolve(pending.lastValue);
|
|
38
|
+
}
|
|
39
|
+
// If we're within the debounce window but no call is in progress, return the last value
|
|
40
|
+
if (pending && !pending.inProgress) {
|
|
41
|
+
this.logger.debug(`Reusing last value for '${methodName}'${deviceId ? ` for device ${deviceId}` : ''} with args ${JSON.stringify(args)}`);
|
|
42
|
+
return Promise.resolve(pending.lastValue);
|
|
43
|
+
}
|
|
44
|
+
// Execute the call
|
|
45
|
+
return (async () => {
|
|
46
|
+
try {
|
|
47
|
+
// Mark call as in progress
|
|
48
|
+
if (pending) {
|
|
49
|
+
pending.inProgress = true;
|
|
50
|
+
}
|
|
51
|
+
this.logger.debug(`Executing '${methodName}'${deviceId ? ` for device ${deviceId}` : ''} with args ${JSON.stringify(args)}`);
|
|
52
|
+
await this.rateLimit(methodName);
|
|
53
|
+
const result = await fn();
|
|
54
|
+
// Store the result and set the debounce timer
|
|
55
|
+
const timer = setTimeout(() => {
|
|
56
|
+
this.debounceTimers.delete(key);
|
|
57
|
+
}, DEBOUNCE_DELAY);
|
|
58
|
+
this.debounceTimers.set(key, {
|
|
59
|
+
timer,
|
|
60
|
+
lastValue: result,
|
|
61
|
+
inProgress: false
|
|
62
|
+
});
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
// If there was an error, clear the debounce timer
|
|
67
|
+
if (pending) {
|
|
68
|
+
clearTimeout(pending.timer);
|
|
69
|
+
this.debounceTimers.delete(key);
|
|
70
|
+
}
|
|
71
|
+
this.logger.error(`Error in '${methodName}' call:`, error);
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
})();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Create a proxy handler that adds rate limiting to API calls
|
|
78
|
+
const createRateLimitedProxy = (target, rateLimiter, deviceId) => {
|
|
79
|
+
return new Proxy(target, {
|
|
80
|
+
get(target, prop) {
|
|
81
|
+
const value = target[prop];
|
|
82
|
+
// If it's not a function or it's a getter, return as is
|
|
83
|
+
if (typeof value !== 'function' || prop === 'get') {
|
|
84
|
+
// If it's an array of devices, wrap each device in a proxy
|
|
85
|
+
if (Array.isArray(value) && ['fans', 'outlets', 'switches', 'bulbs', 'humidifiers', 'purifiers'].includes(prop.toString())) {
|
|
86
|
+
return value.map(device => createRateLimitedProxy(device, rateLimiter, device.cid));
|
|
87
|
+
}
|
|
88
|
+
// If it's a device object (has deviceType and cid), wrap it in a proxy
|
|
89
|
+
if (value && typeof value === 'object' && 'deviceType' in value && 'cid' in value) {
|
|
90
|
+
return createRateLimitedProxy(value, rateLimiter, value.cid);
|
|
91
|
+
}
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
// Return a proxied function that applies rate limiting
|
|
95
|
+
return async function (...args) {
|
|
96
|
+
const methodName = prop.toString();
|
|
97
|
+
// Methods that bypass all rate limiting and debouncing
|
|
98
|
+
const bypassMethods = [
|
|
99
|
+
// Getters and internal methods
|
|
100
|
+
'get', 'getService', 'getCharacteristic',
|
|
101
|
+
// State accessors
|
|
102
|
+
'deviceStatus', 'speed', 'brightness', 'colorTemp',
|
|
103
|
+
// Event handlers
|
|
104
|
+
'onSet', 'onGet', 'addListener', 'removeListener',
|
|
105
|
+
// Controlled interval methods
|
|
106
|
+
'update'
|
|
107
|
+
];
|
|
108
|
+
// Methods that should only be rate limited (no debouncing)
|
|
109
|
+
const noDebounceAPIMethods = [
|
|
110
|
+
'ignored'
|
|
111
|
+
];
|
|
112
|
+
if (bypassMethods.includes(methodName)) {
|
|
113
|
+
return value.apply(target, args);
|
|
114
|
+
}
|
|
115
|
+
if (noDebounceAPIMethods.includes(methodName)) {
|
|
116
|
+
await rateLimiter.rateLimit(methodName);
|
|
117
|
+
return value.apply(target, args);
|
|
118
|
+
}
|
|
119
|
+
// Everything else gets both rate limited and debounced
|
|
120
|
+
return rateLimiter.debounce(methodName, deviceId, () => value.apply(target, args), args);
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
// Export a factory function that creates rate-limited VeSync instances
|
|
126
|
+
const createRateLimitedVeSync = (username, password, timeZone, debug, redact, apiUrl, customLogger) => {
|
|
127
|
+
const client = new tsvesync_1.VeSync(username, password, timeZone, debug, redact, apiUrl, customLogger);
|
|
128
|
+
const rateLimiter = new RateLimiter(customLogger || new logger_1.PluginLogger(console, debug || false));
|
|
129
|
+
return createRateLimitedProxy(client, rateLimiter);
|
|
130
|
+
};
|
|
131
|
+
exports.createRateLimitedVeSync = createRateLimitedVeSync;
|
|
132
|
+
//# sourceMappingURL=api-proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-proxy.js","sourceRoot":"","sources":["../../src/utils/api-proxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,7 +21,7 @@ const HUMIDIFIER_MODELS = [
|
|
|
21
21
|
const FAN_MODELS = ['LTF-F422'];
|
|
22
22
|
const OUTLET_MODELS = [
|
|
23
23
|
'ESO15-TB', 'ESW15-USA', 'ESW03-USA', 'ESW01-EU',
|
|
24
|
-
'wifi-switch-1.3'
|
|
24
|
+
'ESW10-USA', 'wifi-switch-1.3'
|
|
25
25
|
];
|
|
26
26
|
const SWITCH_MODELS = ['ESWD16', 'ESWL01', 'ESWL03'];
|
|
27
27
|
class DeviceFactory {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device-factory.js","sourceRoot":"","sources":["../../src/utils/device-factory.ts"],"names":[],"mappings":";;;AAGA,kFAA6E;AAC7E,8EAA0E;AAC1E,gEAA4D;AAC5D,oEAAgE;AAChE,sEAAkE;AAClE,sEAAkE;AAWlE,yBAAyB;AACzB,MAAM,mBAAmB,GAAG;IAC1B,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;IAC9C,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW;IACnD,YAAY;CACb,CAAC;AAEF,MAAM,iBAAiB,GAAG;IACxB,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ;IAClD,WAAW,EAAE,eAAe,EAAE,eAAe;IAC7C,gBAAgB;CACjB,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,UAAU,CAAC,CAAC;AAEhC,MAAM,aAAa,GAAG;IACpB,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU;IAChD,iBAAiB;
|
|
1
|
+
{"version":3,"file":"device-factory.js","sourceRoot":"","sources":["../../src/utils/device-factory.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-tsvesync",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.43",
|
|
4
4
|
"description": "Homebridge plugin for VeSync devices including Levoit air purifiers, humidifiers, and Etekcity smart outlets",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
"XYD0001",
|
|
73
73
|
"ESO15-TB",
|
|
74
74
|
"ESW15-USA",
|
|
75
|
+
"ESW10-USA",
|
|
75
76
|
"ESW03-USA",
|
|
76
77
|
"ESW01-EU",
|
|
77
78
|
"LTF-F422S",
|
|
@@ -97,7 +98,7 @@
|
|
|
97
98
|
"axios": "^1.6.5",
|
|
98
99
|
"dotenv": "^16.3.1",
|
|
99
100
|
"js-yaml": "^4.1.0",
|
|
100
|
-
"tsvesync": "1.0.
|
|
101
|
+
"tsvesync": "1.0.37"
|
|
101
102
|
},
|
|
102
103
|
"devDependencies": {
|
|
103
104
|
"@types/jest": "^29.5.11",
|
package/scripts/get_response.sh
CHANGED
|
@@ -253,8 +253,8 @@ echo "$DEVICES_RESPONSE" | jq -c '.result.list[]' | while read -r device; do
|
|
|
253
253
|
echo "$period energy for $DEVICE_NAME:"
|
|
254
254
|
echo "$ENERGY_RESPONSE" | jq '.'
|
|
255
255
|
done
|
|
256
|
-
elif [[ "$DEVICE_TYPE" == "ESW01-EU" ]]; then
|
|
257
|
-
echo "Getting
|
|
256
|
+
elif [[ "$DEVICE_TYPE" == "ESW01-EU" || "$DEVICE_TYPE" == "ESW03-USA" || "$DEVICE_TYPE" == "ESW10-USA" ]]; then
|
|
257
|
+
echo "Getting 10A outlet details..."
|
|
258
258
|
DETAILS_RESPONSE=$(curl -s -X POST "$BASE_URL/10a/v1/device/devicedetail" \
|
|
259
259
|
-H "Content-Type: application/json" \
|
|
260
260
|
-H "accept-language: en" \
|
|
@@ -556,6 +556,8 @@ echo "$DEVICES_RESPONSE" | jq -c '.result.list[]' | while read -r device; do
|
|
|
556
556
|
|
|
557
557
|
echo "Status for $DEVICE_NAME:"
|
|
558
558
|
echo "$STATUS_RESPONSE" | jq '.'
|
|
559
|
+
elif [[ "$DEVICE_TYPE" == "ESW03-USA" ]]; then
|
|
560
|
+
echo "Getting energy details for 10A outlet..."
|
|
559
561
|
fi
|
|
560
562
|
|
|
561
563
|
echo "Details for $DEVICE_NAME:"
|
package/src/platform.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { VeSync } from 'tsvesync';
|
|
|
4
4
|
import { DeviceFactory } from './utils/device-factory';
|
|
5
5
|
import { BaseAccessory } from './accessories/base.accessory';
|
|
6
6
|
import { PluginLogger } from './utils/logger';
|
|
7
|
+
import { createRateLimitedVeSync } from './utils/api-proxy';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* HomebridgePlatform
|
|
@@ -28,6 +29,8 @@ export class TSVESyncPlatform implements DynamicPlatformPlugin {
|
|
|
28
29
|
private initializationResolver!: () => void;
|
|
29
30
|
private isInitialized = false;
|
|
30
31
|
private readonly logger!: PluginLogger;
|
|
32
|
+
private readonly TOKEN_EXPIRY = 60 * 60 * 1000; // 1 hour in milliseconds
|
|
33
|
+
private lastTokenRefresh: Date = new Date(0);
|
|
31
34
|
|
|
32
35
|
constructor(
|
|
33
36
|
public readonly log: Logger,
|
|
@@ -53,7 +56,7 @@ export class TSVESyncPlatform implements DynamicPlatformPlugin {
|
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
// Initialize VeSync client with all configuration
|
|
56
|
-
this.client =
|
|
59
|
+
this.client = createRateLimitedVeSync(
|
|
57
60
|
config.username,
|
|
58
61
|
config.password,
|
|
59
62
|
Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
@@ -205,6 +208,12 @@ export class TSVESyncPlatform implements DynamicPlatformPlugin {
|
|
|
205
208
|
* Ensure client is logged in, but avoid unnecessary logins
|
|
206
209
|
*/
|
|
207
210
|
private async ensureLogin(forceLogin = false): Promise<boolean> {
|
|
211
|
+
// Check if token needs refresh
|
|
212
|
+
const timeSinceLastRefresh = Date.now() - this.lastTokenRefresh.getTime();
|
|
213
|
+
if (!forceLogin && timeSinceLastRefresh < this.TOKEN_EXPIRY) {
|
|
214
|
+
return true; // Token is still valid
|
|
215
|
+
}
|
|
216
|
+
|
|
208
217
|
let isLoggedIn = false;
|
|
209
218
|
while (!isLoggedIn) { // Keep trying until successful
|
|
210
219
|
try {
|
|
@@ -217,7 +226,7 @@ export class TSVESyncPlatform implements DynamicPlatformPlugin {
|
|
|
217
226
|
}
|
|
218
227
|
|
|
219
228
|
// Need to login again
|
|
220
|
-
this.logger.debug(forceLogin ? 'Forcing new login to VeSync API' : '
|
|
229
|
+
this.logger.debug(forceLogin ? 'Forcing new login to VeSync API' : 'Refreshing VeSync API token');
|
|
221
230
|
|
|
222
231
|
this.lastLoginAttempt = new Date();
|
|
223
232
|
const loginResult = await this.client.login();
|
|
@@ -228,8 +237,9 @@ export class TSVESyncPlatform implements DynamicPlatformPlugin {
|
|
|
228
237
|
continue; // Try again after backoff
|
|
229
238
|
}
|
|
230
239
|
|
|
231
|
-
// Reset backoff on successful login
|
|
240
|
+
// Reset backoff and update token refresh time on successful login
|
|
232
241
|
this.loginBackoffTime = 10000;
|
|
242
|
+
this.lastTokenRefresh = new Date();
|
|
233
243
|
isLoggedIn = true;
|
|
234
244
|
return true;
|
|
235
245
|
} catch (error) {
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { VeSync } from 'tsvesync';
|
|
2
|
+
import { PluginLogger } from './logger';
|
|
3
|
+
|
|
4
|
+
const RATE_LIMIT_DELAY = 500; // 500ms between API calls
|
|
5
|
+
const DEBOUNCE_DELAY = 5000; // 5 second debounce for rapid changes
|
|
6
|
+
|
|
7
|
+
class RateLimiter {
|
|
8
|
+
private lastCallTime = 0;
|
|
9
|
+
private lastMethodName = '';
|
|
10
|
+
private debounceTimers: Map<string, {
|
|
11
|
+
timer: NodeJS.Timeout;
|
|
12
|
+
lastValue: any;
|
|
13
|
+
inProgress: boolean;
|
|
14
|
+
}> = new Map();
|
|
15
|
+
|
|
16
|
+
constructor(private readonly logger: PluginLogger) {}
|
|
17
|
+
|
|
18
|
+
async rateLimit(methodName: string): Promise<void> {
|
|
19
|
+
const now = Date.now();
|
|
20
|
+
const timeSinceLastCall = now - this.lastCallTime;
|
|
21
|
+
|
|
22
|
+
if (timeSinceLastCall < RATE_LIMIT_DELAY) {
|
|
23
|
+
const waitTime = RATE_LIMIT_DELAY - timeSinceLastCall;
|
|
24
|
+
this.logger.debug(`Rate limiting '${methodName}' - waiting ${waitTime}ms before next API call (previous call was '${this.lastMethodName}' ${timeSinceLastCall}ms ago)`);
|
|
25
|
+
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
this.lastMethodName = methodName;
|
|
29
|
+
this.lastCallTime = Date.now();
|
|
30
|
+
this.logger.debug(`Executing API call '${methodName}'`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private getDebounceKey(methodName: string, deviceId: string | undefined, args: any[]): string {
|
|
34
|
+
const paramsKey = args.length > 0 ? `-${JSON.stringify(args)}` : '';
|
|
35
|
+
return deviceId ? `${methodName}-${deviceId}${paramsKey}` : `${methodName}${paramsKey}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
debounce<T>(methodName: string, deviceId: string | undefined, fn: () => Promise<T>, args: any[]): Promise<T> {
|
|
39
|
+
const key = this.getDebounceKey(methodName, deviceId, args);
|
|
40
|
+
const pending = this.debounceTimers.get(key);
|
|
41
|
+
|
|
42
|
+
// If there's an active debounce timer and a call is in progress, skip this call
|
|
43
|
+
if (pending?.inProgress) {
|
|
44
|
+
this.logger.debug(`Skipping '${methodName}'${deviceId ? ` for device ${deviceId}` : ''} with args ${JSON.stringify(args)} - call already in progress`);
|
|
45
|
+
return Promise.resolve(pending.lastValue);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// If we're within the debounce window but no call is in progress, return the last value
|
|
49
|
+
if (pending && !pending.inProgress) {
|
|
50
|
+
this.logger.debug(`Reusing last value for '${methodName}'${deviceId ? ` for device ${deviceId}` : ''} with args ${JSON.stringify(args)}`);
|
|
51
|
+
return Promise.resolve(pending.lastValue);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Execute the call
|
|
55
|
+
return (async () => {
|
|
56
|
+
try {
|
|
57
|
+
// Mark call as in progress
|
|
58
|
+
if (pending) {
|
|
59
|
+
pending.inProgress = true;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
this.logger.debug(`Executing '${methodName}'${deviceId ? ` for device ${deviceId}` : ''} with args ${JSON.stringify(args)}`);
|
|
63
|
+
await this.rateLimit(methodName);
|
|
64
|
+
const result = await fn();
|
|
65
|
+
|
|
66
|
+
// Store the result and set the debounce timer
|
|
67
|
+
const timer = setTimeout(() => {
|
|
68
|
+
this.debounceTimers.delete(key);
|
|
69
|
+
}, DEBOUNCE_DELAY);
|
|
70
|
+
|
|
71
|
+
this.debounceTimers.set(key, {
|
|
72
|
+
timer,
|
|
73
|
+
lastValue: result,
|
|
74
|
+
inProgress: false
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return result;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
// If there was an error, clear the debounce timer
|
|
80
|
+
if (pending) {
|
|
81
|
+
clearTimeout(pending.timer);
|
|
82
|
+
this.debounceTimers.delete(key);
|
|
83
|
+
}
|
|
84
|
+
this.logger.error(`Error in '${methodName}' call:`, error);
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
})();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Create a proxy handler that adds rate limiting to API calls
|
|
92
|
+
const createRateLimitedProxy = (target: any, rateLimiter: RateLimiter, deviceId?: string): any => {
|
|
93
|
+
return new Proxy(target, {
|
|
94
|
+
get(target, prop) {
|
|
95
|
+
const value = target[prop];
|
|
96
|
+
|
|
97
|
+
// If it's not a function or it's a getter, return as is
|
|
98
|
+
if (typeof value !== 'function' || prop === 'get') {
|
|
99
|
+
// If it's an array of devices, wrap each device in a proxy
|
|
100
|
+
if (Array.isArray(value) && ['fans', 'outlets', 'switches', 'bulbs', 'humidifiers', 'purifiers'].includes(prop.toString())) {
|
|
101
|
+
return value.map(device => createRateLimitedProxy(device, rateLimiter, device.cid));
|
|
102
|
+
}
|
|
103
|
+
// If it's a device object (has deviceType and cid), wrap it in a proxy
|
|
104
|
+
if (value && typeof value === 'object' && 'deviceType' in value && 'cid' in value) {
|
|
105
|
+
return createRateLimitedProxy(value, rateLimiter, value.cid);
|
|
106
|
+
}
|
|
107
|
+
return value;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Return a proxied function that applies rate limiting
|
|
111
|
+
return async function(...args: any[]) {
|
|
112
|
+
const methodName = prop.toString();
|
|
113
|
+
|
|
114
|
+
// Methods that bypass all rate limiting and debouncing
|
|
115
|
+
const bypassMethods = [
|
|
116
|
+
// Getters and internal methods
|
|
117
|
+
'get', 'getService', 'getCharacteristic',
|
|
118
|
+
// State accessors
|
|
119
|
+
'deviceStatus', 'speed', 'brightness', 'colorTemp',
|
|
120
|
+
// Event handlers
|
|
121
|
+
'onSet', 'onGet', 'addListener', 'removeListener',
|
|
122
|
+
// Controlled interval methods
|
|
123
|
+
'update'
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
// Methods that should only be rate limited (no debouncing)
|
|
127
|
+
const noDebounceAPIMethods = [
|
|
128
|
+
'ignored'
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
if (bypassMethods.includes(methodName)) {
|
|
132
|
+
return value.apply(target, args);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (noDebounceAPIMethods.includes(methodName)) {
|
|
136
|
+
await rateLimiter.rateLimit(methodName);
|
|
137
|
+
return value.apply(target, args);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Everything else gets both rate limited and debounced
|
|
141
|
+
return rateLimiter.debounce(methodName, deviceId, () => value.apply(target, args), args);
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// Export a factory function that creates rate-limited VeSync instances
|
|
148
|
+
export const createRateLimitedVeSync = (
|
|
149
|
+
username: string,
|
|
150
|
+
password: string,
|
|
151
|
+
timeZone: string,
|
|
152
|
+
debug?: boolean,
|
|
153
|
+
redact?: boolean,
|
|
154
|
+
apiUrl?: string,
|
|
155
|
+
customLogger?: PluginLogger
|
|
156
|
+
): VeSync => {
|
|
157
|
+
const client = new VeSync(username, password, timeZone, debug, redact, apiUrl, customLogger);
|
|
158
|
+
const rateLimiter = new RateLimiter(customLogger || new PluginLogger(console as any, debug || false));
|
|
159
|
+
return createRateLimitedProxy(client, rateLimiter);
|
|
160
|
+
};
|