@switchbot/homebridge-switchbot 5.0.0-beta.136 → 5.0.0-beta.138

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 (61) hide show
  1. package/dist/errors.d.ts +37 -4
  2. package/dist/errors.d.ts.map +1 -1
  3. package/dist/errors.js +31 -50
  4. package/dist/errors.js.map +1 -1
  5. package/dist/homebridge-ui/endpoints/devices.d.ts.map +1 -1
  6. package/dist/homebridge-ui/endpoints/devices.js.map +1 -1
  7. package/dist/platform.d.ts +2 -1
  8. package/dist/platform.d.ts.map +1 -1
  9. package/dist/platform.js +1 -1
  10. package/dist/platform.js.map +1 -1
  11. package/dist/switchbotClient.d.ts +0 -4
  12. package/dist/switchbotClient.d.ts.map +1 -1
  13. package/dist/switchbotClient.js +16 -90
  14. package/dist/switchbotClient.js.map +1 -1
  15. package/docs/variables/default.html +1 -1
  16. package/package.json +3 -3
  17. package/src/errors.ts +30 -38
  18. package/src/homebridge-ui/endpoints/devices.ts +29 -14
  19. package/src/platform.ts +1 -1
  20. package/src/switchbotClient.ts +16 -90
  21. package/test/client/switchbot-client-debounce.spec.ts +35 -0
  22. package/test/client/switchbot-client-openapi.spec.ts +19 -0
  23. package/test/client/switchbotClient.spec.ts +23 -0
  24. package/test/device/device-mapping.spec.ts +23 -0
  25. package/test/device/deviceBase.spec.ts +26 -0
  26. package/test/device/deviceFactory-edge.spec.ts +15 -0
  27. package/test/device/deviceFactory.spec.ts +33 -0
  28. package/test/device/fan-swing.spec.ts +34 -0
  29. package/test/device/irdevice.spec.ts +9 -0
  30. package/test/device/lock-users.spec.ts +35 -0
  31. package/test/device/matter-descriptors.spec.ts +22 -0
  32. package/test/device/matter-device-state.spec.ts +37 -0
  33. package/test/errors/errors.spec.ts +10 -0
  34. package/test/homebridge-ui/server.spec.ts +9 -0
  35. package/test/platform/accessory-restore.spec.ts +36 -0
  36. package/test/platform/matter-childbridge.spec.ts +34 -0
  37. package/test/platform/matter-integration.spec.ts +33 -0
  38. package/test/platform/platform-edge.spec.ts +72 -0
  39. package/test/platform/platform.integration.spec.ts +34 -0
  40. package/test/utils/utils-extra.spec.ts +10 -0
  41. package/test/utils/utils.spec.ts +53 -0
  42. package/todo/TODO.md +55 -165
  43. package/test/accessory-restore.spec.ts +0 -74
  44. package/test/device-mapping.spec.ts +0 -38
  45. package/test/deviceFactory.spec.ts +0 -19
  46. package/test/fan-swing.spec.ts +0 -30
  47. package/test/lock-users.spec.ts +0 -44
  48. package/test/matter-childbridge.spec.ts +0 -62
  49. package/test/matter-descriptors.spec.ts +0 -110
  50. package/test/matter-device-state.spec.ts +0 -117
  51. package/test/matter-integration.spec.ts +0 -183
  52. package/test/platform.integration.spec.ts +0 -57
  53. package/test/switchbot-client-debounce.spec.ts +0 -127
  54. package/test/switchbot-client-openapi.spec.ts +0 -63
  55. package/test/switchbotClient.spec.ts +0 -11
  56. package/test/utils.spec.ts +0 -37
  57. package/todo/COMPLETED.md +0 -542
  58. package/todo/README.md +0 -59
  59. package/todo/mockups/filtering-sorting.svg +0 -112
  60. package/todo/mockups/modal-switchbot-theme.svg +0 -66
  61. package/todo/mockups/signal-strength-visualization.svg +0 -94
@@ -7,9 +7,6 @@ import { CharacteristicMissingError, SwitchbotAuthenticationError, SwitchbotOper
7
7
  export class SwitchBotClient {
8
8
  cfg;
9
9
  client = null;
10
- baseUrl = 'https://api.switch-bot.com/v1.0';
11
- requestTimeout = 5000;
12
- maxRetries = 2;
13
10
  writeDebounceMs = 100;
14
11
  logger;
15
12
  pendingWrites = new Map();
@@ -19,12 +16,6 @@ export class SwitchBotClient {
19
16
  if (!this.logger) {
20
17
  throw new Error('SwitchBotClient requires a logger (Homebridge logger) in config');
21
18
  }
22
- if (typeof cfg?.requestTimeout === 'number') {
23
- this.requestTimeout = cfg.requestTimeout;
24
- }
25
- if (typeof cfg?.maxRetries === 'number') {
26
- this.maxRetries = cfg.maxRetries;
27
- }
28
19
  if (typeof cfg?.writeDebounceMs === 'number') {
29
20
  this.writeDebounceMs = cfg.writeDebounceMs;
30
21
  }
@@ -52,46 +43,8 @@ export class SwitchBotClient {
52
43
  this.client = null;
53
44
  }
54
45
  }
55
- async fetchWithTimeoutAndRetry(url, opts = {}, timeoutMs, retries) {
56
- const to = typeof timeoutMs === 'number' ? timeoutMs : this.requestTimeout;
57
- const max = typeof retries === 'number' ? retries : this.maxRetries;
58
- let attempt = 0;
59
- while (true) {
60
- attempt += 1;
61
- const controller = new AbortController();
62
- const timer = setTimeout(() => controller.abort(), to);
63
- try {
64
- const fetchOpts = { ...opts };
65
- try {
66
- Object.defineProperty(fetchOpts, 'signal', { value: controller.signal, enumerable: false, configurable: true });
67
- }
68
- catch (_e) {
69
- // ignore
70
- }
71
- const resp = await fetch(url, fetchOpts);
72
- clearTimeout(timer);
73
- if (resp.ok) {
74
- return resp;
75
- }
76
- // server error / rate limit: retry
77
- if (resp.status >= 500 || resp.status === 429) {
78
- throw new Error(`retriable response: ${resp.status}`);
79
- }
80
- return resp;
81
- }
82
- catch (err) {
83
- clearTimeout(timer);
84
- if (attempt > max) {
85
- throw err;
86
- }
87
- // exponential backoff
88
- const backoff = Math.min(100 * 2 ** (attempt - 1), 2000);
89
- await new Promise(r => setTimeout(r, backoff));
90
- }
91
- }
92
- }
46
+ // Removed fetchWithTimeoutAndRetry (HTTP fallback)
93
47
  async getDevice(id) {
94
- // Try client API first (with node-switchbot's smart fallback and retry)
95
48
  if (this.client?.getDevice) {
96
49
  try {
97
50
  return await this.client.getDevice(id);
@@ -103,43 +56,31 @@ export class SwitchBotClient {
103
56
  }
104
57
  else if (e instanceof SwitchbotOperationError) {
105
58
  this.logger?.warn?.(`Operation error for getDevice(${id}):`, e.message, e.code);
59
+ throw e;
106
60
  }
107
61
  else if (e instanceof CharacteristicMissingError) {
108
62
  this.logger?.warn?.(`Characteristic missing for getDevice(${id}):`, e.characteristic);
63
+ throw e;
109
64
  }
110
65
  else {
111
- this.logger?.warn?.(`Client getDevice failed for ${id}, trying OpenAPI fallback:`, e);
66
+ this.logger?.warn?.(`Client getDevice failed for ${id}:`, e);
67
+ throw e;
112
68
  }
113
69
  }
114
70
  }
115
- // Fallback: call OpenAPI via HTTP
116
- if (this.cfg.openApiToken) {
117
- const url = `${this.baseUrl}/devices/${id}`;
118
- const opts = { headers: { Authorization: this.cfg.openApiToken } };
119
- const resp = await this.fetchWithTimeoutAndRetry(url, opts);
120
- return resp.json();
121
- }
122
71
  throw new SwitchbotOperationError('No SwitchBot client available', 'no_client');
123
72
  }
124
73
  async getDevices() {
125
- // Try client API first
126
74
  if (this.client?.getDevices) {
127
75
  try {
128
76
  return await this.client.getDevices();
129
77
  }
130
78
  catch (e) {
131
- this.logger?.warn?.('Client getDevices failed, trying OpenAPI fallback:', e);
79
+ this.logger?.warn?.('Client getDevices failed:', e);
80
+ throw e;
132
81
  }
133
82
  }
134
- // Fallback: call OpenAPI
135
- if (this.cfg.openApiToken) {
136
- const url = `${this.baseUrl}/devices`;
137
- const opts = { headers: { Authorization: this.cfg.openApiToken } };
138
- const resp = await this.fetchWithTimeoutAndRetry(url, opts);
139
- const data = await resp.json();
140
- return (data?.body || data);
141
- }
142
- return [];
83
+ throw new SwitchbotOperationError('No SwitchBot client available', 'no_client');
143
84
  }
144
85
  async setDeviceState(id, body) {
145
86
  // Plugin-level debounce: coalesce rapid writes per device
@@ -183,7 +124,6 @@ export class SwitchBotClient {
183
124
  });
184
125
  }
185
126
  async _doSetDeviceState(id, body) {
186
- // Prefer client API (which has node-switchbot's native resilience)
187
127
  if (this.client?.setDeviceState) {
188
128
  try {
189
129
  this.logger?.debug?.(`[${id}] Using client.setDeviceState()`);
@@ -198,16 +138,18 @@ export class SwitchBotClient {
198
138
  }
199
139
  else if (e instanceof SwitchbotOperationError) {
200
140
  this.logger?.warn?.(`Operation error for setDeviceState(${id}):`, e.message, e.code);
141
+ throw e;
201
142
  }
202
143
  else if (e instanceof CharacteristicMissingError) {
203
144
  this.logger?.warn?.(`Characteristic missing for setDeviceState(${id}):`, e.characteristic);
145
+ throw e;
204
146
  }
205
147
  else {
206
- this.logger?.warn?.(`Client setDeviceState failed for ${id}, trying fallback:`, e);
148
+ this.logger?.warn?.(`Client setDeviceState failed for ${id}:`, e);
149
+ throw e;
207
150
  }
208
151
  }
209
152
  }
210
- // Try generic sendCommand if available
211
153
  if (this.client?.sendCommand) {
212
154
  try {
213
155
  this.logger?.debug?.(`[${id}] Using client.sendCommand()`);
@@ -222,34 +164,18 @@ export class SwitchBotClient {
222
164
  }
223
165
  else if (e instanceof SwitchbotOperationError) {
224
166
  this.logger?.warn?.(`Operation error for sendCommand(${id}):`, e.message, e.code);
167
+ throw e;
225
168
  }
226
169
  else if (e instanceof CharacteristicMissingError) {
227
170
  this.logger?.warn?.(`Characteristic missing for sendCommand(${id}):`, e.characteristic);
171
+ throw e;
228
172
  }
229
173
  else {
230
- this.logger?.warn?.(`Client sendCommand failed for ${id}, trying OpenAPI:`, e);
174
+ this.logger?.warn?.(`Client sendCommand failed for ${id}:`, e);
175
+ throw e;
231
176
  }
232
177
  }
233
178
  }
234
- // OpenAPI fallback
235
- if (this.cfg.openApiToken) {
236
- const url = `${this.baseUrl}/devices/${id}/commands`;
237
- const opts = {
238
- method: 'POST',
239
- headers: {
240
- 'Authorization': this.cfg.openApiToken,
241
- 'Content-Type': 'application/json',
242
- },
243
- body: JSON.stringify(body),
244
- };
245
- this.logger?.debug?.(`[${id}] Using OpenAPI fallback POST ${url}`);
246
- this.logger?.debug?.(`[${id}] Request body:`, body);
247
- const resp = await this.fetchWithTimeoutAndRetry(url, opts);
248
- const result = await resp.json();
249
- this.logger?.debug?.(`[${id}] OpenAPI response:`, result);
250
- this.logger?.debug?.(`[${id}] Response status:`, resp.status, resp.statusText);
251
- return result;
252
- }
253
179
  throw new SwitchbotOperationError('No SwitchBot client available for setDeviceState', 'no_client');
254
180
  }
255
181
  async destroy() {
@@ -1 +1 @@
1
- {"version":3,"file":"switchbotClient.js","sourceRoot":"","sources":["../src/switchbotClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"switchbotClient.js","sourceRoot":"","sources":["../src/switchbotClient.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- <!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>default | @switchbot/homebridge-switchbot</title><meta name="description" content="Documentation for @switchbot/homebridge-switchbot"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">@switchbot/homebridge-switchbot</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">default</a></li></ul><h1>Variable default</h1></div><div class="tsd-signature"><span class="tsd-kind-variable">default</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">api</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">API</span><span class="tsd-signature-symbol">)</span> <span class="tsd-signature-symbol">=&gt;</span> <span class="tsd-signature-type">void</span></div><div class="tsd-type-declaration"><h4>Type Declaration</h4><ul class="tsd-parameters"><li class="tsd-parameter-signature"><ul class="tsd-signatures"><li class="tsd-signature" id="__type"><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">api</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">API</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">void</span></li><li class="tsd-description"><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">api</span>: <span class="tsd-signature-type">API</span></span></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4></li></ul></li></ul></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/OpenWonderLabs/homebridge-switchbot/blob/0ddf11dddc97190c138263b17af75efb904b7874/src/index.ts#L12">index.ts:12</a></li></ul></aside></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">@switchbot/homebridge-switchbot</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer></footer><div class="overlay"></div></body></html>
1
+ <!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>default | @switchbot/homebridge-switchbot</title><meta name="description" content="Documentation for @switchbot/homebridge-switchbot"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">@switchbot/homebridge-switchbot</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">default</a></li></ul><h1>Variable default</h1></div><div class="tsd-signature"><span class="tsd-kind-variable">default</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">api</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">API</span><span class="tsd-signature-symbol">)</span> <span class="tsd-signature-symbol">=&gt;</span> <span class="tsd-signature-type">void</span></div><div class="tsd-type-declaration"><h4>Type Declaration</h4><ul class="tsd-parameters"><li class="tsd-parameter-signature"><ul class="tsd-signatures"><li class="tsd-signature" id="__type"><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">api</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">API</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">void</span></li><li class="tsd-description"><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">api</span>: <span class="tsd-signature-type">API</span></span></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4></li></ul></li></ul></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/OpenWonderLabs/homebridge-switchbot/blob/7442de05fcd318c476920d1a0c249ee86c3bd592/src/index.ts#L12">index.ts:12</a></li></ul></aside></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">@switchbot/homebridge-switchbot</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer></footer><div class="overlay"></div></body></html>
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@switchbot/homebridge-switchbot",
3
3
  "displayName": "SwitchBot",
4
4
  "type": "module",
5
- "version": "5.0.0-beta.136",
5
+ "version": "5.0.0-beta.138",
6
6
  "description": "The SwitchBot plugin allows you to access your SwitchBot device(s) from HomeKit.",
7
7
  "author": "SwitchBot <support@wondertechlabs.com> (https://github.com/SwitchBot)",
8
8
  "contributors": [
@@ -92,13 +92,13 @@
92
92
  "dependencies": {
93
93
  "@homebridge/plugin-ui-utils": "^2.2.1",
94
94
  "class-validator": "^0.15.1",
95
- "node-switchbot": "^4.0.0-beta.14"
95
+ "node-switchbot": "^4.0.0-beta.16"
96
96
  },
97
97
  "devDependencies": {
98
98
  "@antfu/eslint-config": "^7.7.0",
99
99
  "@types/debug": "^4.1.12",
100
100
  "@types/fs-extra": "^11.0.4",
101
- "@types/node": "^25.3.5",
101
+ "@types/node": "^25.4.0",
102
102
  "@types/semver": "^7.7.1",
103
103
  "@types/source-map-support": "^0.5.10",
104
104
  "@vitest/coverage-v8": "^4.0.18",
package/src/errors.ts CHANGED
@@ -1,43 +1,35 @@
1
- // Error re-exports for node-switchbot v4 error compatibility
1
+ // Error classes for node-switchbot v4 compatibility
2
+ // Always use local fallback classes for compatibility; upstream error classes are not guaranteed to exist
2
3
 
3
- let SwitchbotOperationError: any = undefined;
4
- let SwitchbotAuthenticationError: any = undefined;
5
- let CharacteristicMissingError: any = undefined;
6
-
7
- try {
8
- // Dynamically import from node-switchbot if available
9
- // (node-switchbot v4+ exports these error classes)
10
- // eslint-disable-next-line @typescript-eslint/no-var-requires
11
- const mod = require('node-switchbot');
12
- SwitchbotOperationError = mod.SwitchbotOperationError;
13
- SwitchbotAuthenticationError = mod.SwitchbotAuthenticationError;
14
- CharacteristicMissingError = mod.CharacteristicMissingError;
15
- } catch {}
16
-
17
- // Fallbacks (for OpenAPI or legacy code)
18
- if (!SwitchbotOperationError) {
19
- SwitchbotOperationError = class extends Error {
20
- code?: string; cause?: Error;
21
- constructor(message: string, code?: string, cause?: Error) {
22
- super(message); this.name = 'SwitchbotOperationError'; this.code = code; this.cause = cause;
23
- }
24
- };
4
+ const SwitchbotOperationError = class extends Error {
5
+ code?: string
6
+ cause?: Error
7
+ constructor(message: string, code?: string, cause?: Error) {
8
+ super(message)
9
+ this.name = 'SwitchbotOperationError'
10
+ this.code = code
11
+ this.cause = cause
12
+ }
25
13
  }
26
- if (!SwitchbotAuthenticationError) {
27
- SwitchbotAuthenticationError = class extends Error {
28
- code?: string; cause?: Error;
29
- constructor(message: string, code?: string, cause?: Error) {
30
- super(message); this.name = 'SwitchbotAuthenticationError'; this.code = code; this.cause = cause;
31
- }
32
- };
14
+
15
+ const SwitchbotAuthenticationError = class extends Error {
16
+ code?: string
17
+ cause?: Error
18
+ constructor(message: string, code?: string, cause?: Error) {
19
+ super(message)
20
+ this.name = 'SwitchbotAuthenticationError'
21
+ this.code = code
22
+ this.cause = cause
23
+ }
33
24
  }
34
- if (!CharacteristicMissingError) {
35
- CharacteristicMissingError = class extends Error {
36
- characteristic: string;
37
- constructor(message: string, characteristic: string) {
38
- super(message); this.name = 'CharacteristicMissingError'; this.characteristic = characteristic;
39
- }
40
- };
25
+
26
+ const CharacteristicMissingError = class extends Error {
27
+ characteristic: string
28
+ constructor(message: string, characteristic: string) {
29
+ super(message)
30
+ this.name = 'CharacteristicMissingError'
31
+ this.characteristic = characteristic
32
+ }
41
33
  }
42
34
 
43
- export { SwitchbotOperationError, SwitchbotAuthenticationError, CharacteristicMissingError };
35
+ export { CharacteristicMissingError, SwitchbotAuthenticationError, SwitchbotOperationError }
@@ -44,8 +44,8 @@ export function registerDeviceEndpoints(server: HomebridgePluginUiServer) {
44
44
  const method = stateConnection.includes('ble')
45
45
  ? 'BLE'
46
46
  : stateConnection.includes('api')
47
- ? 'OpenAPI'
48
- : 'Auto'
47
+ ? 'OpenAPI'
48
+ : 'Auto'
49
49
 
50
50
  return {
51
51
  success: true,
@@ -131,11 +131,21 @@ export function registerDeviceEndpoints(server: HomebridgePluginUiServer) {
131
131
  configDeviceName: name,
132
132
  configDeviceType: type,
133
133
  }
134
- if (address) { newDevice.address = address }
135
- if (model) { newDevice.model = model }
136
- if (rssi !== undefined && rssi !== null && rssi !== 0) { newDevice.rssi = rssi }
137
- if (encryptionKey) { newDevice.encryptionKey = encryptionKey }
138
- if (keyId) { newDevice.keyId = keyId }
134
+ if (address) {
135
+ newDevice.address = address
136
+ }
137
+ if (model) {
138
+ newDevice.model = model
139
+ }
140
+ if (rssi !== undefined && rssi !== null && rssi !== 0) {
141
+ newDevice.rssi = rssi
142
+ }
143
+ if (encryptionKey) {
144
+ newDevice.encryptionKey = encryptionKey
145
+ }
146
+ if (keyId) {
147
+ newDevice.keyId = keyId
148
+ }
139
149
  ref.push(newDevice)
140
150
  addCount++
141
151
  }
@@ -189,10 +199,10 @@ export function registerDeviceEndpoints(server: HomebridgePluginUiServer) {
189
199
  const { cfg, platform, cfgPath } = await getSwitchBotPlatformConfig(server)
190
200
  uiLog.debug(`POST /add-devices - Received ${devices.length} device(s) to add`)
191
201
  uiLog.debug(`POST /add-devices - Config path: ${cfgPath}`)
192
-
202
+
193
203
  const deviceArrays = getDeviceArrays(platform)
194
204
  const allDevices = getAllDevices(platform)
195
-
205
+
196
206
  uiLog.debug(`POST /add-devices - Device arrays count: ${deviceArrays.length}, existing devices: ${allDevices.length}`)
197
207
  uiLog.debug(`POST /add-devices - Platform.devices exists: ${!!platform.devices}, length: ${platform.devices?.length || 0}`)
198
208
 
@@ -227,10 +237,16 @@ export function registerDeviceEndpoints(server: HomebridgePluginUiServer) {
227
237
  configDeviceType: type,
228
238
  }
229
239
  // Store RSSI, address, and model if available
230
- if (rssi !== undefined && rssi !== null && rssi !== 0) { newDevice.rssi = rssi }
231
- if (address) { newDevice.address = address }
232
- if (model) { newDevice.model = model }
233
-
240
+ if (rssi !== undefined && rssi !== null && rssi !== 0) {
241
+ newDevice.rssi = rssi
242
+ }
243
+ if (address) {
244
+ newDevice.address = address
245
+ }
246
+ if (model) {
247
+ newDevice.model = model
248
+ }
249
+
234
250
  ref.push(newDevice)
235
251
  addedToArray = true
236
252
  uiLog.debug(`POST /add-devices - Added device to array: ${deviceId} (${name}, ${type}, RSSI: ${rssi})`)
@@ -460,5 +476,4 @@ export function registerDeviceEndpoints(server: HomebridgePluginUiServer) {
460
476
  throw new RequestError(`Failed to delete all devices: ${e instanceof Error ? e.message : String(e)}`, e)
461
477
  }
462
478
  })
463
-
464
479
  }
package/src/platform.ts CHANGED
@@ -1607,4 +1607,4 @@ export class SwitchBotMatterPlatform {
1607
1607
  }
1608
1608
  }
1609
1609
 
1610
- export default SwitchBotHAPPlatform
1610
+ export default SwitchBotHAPPlatform || SwitchBotMatterPlatform
@@ -18,9 +18,6 @@ export interface ISwitchBotClient {
18
18
  export class SwitchBotClient implements ISwitchBotClient {
19
19
  private cfg: SwitchBotPluginConfig
20
20
  private client: any | null = null
21
- private baseUrl = 'https://api.switch-bot.com/v1.0'
22
- private requestTimeout = 5000
23
- private maxRetries = 2
24
21
  private writeDebounceMs = 100
25
22
  private logger: import('homebridge').Logger
26
23
  private pendingWrites: Map<string, { timer: any, body: any, resolvers: Array<{ resolve: (v: any) => void, reject: (e: any) => void }> }> = new Map()
@@ -31,12 +28,6 @@ export class SwitchBotClient implements ISwitchBotClient {
31
28
  if (!this.logger) {
32
29
  throw new Error('SwitchBotClient requires a logger (Homebridge logger) in config')
33
30
  }
34
- if (typeof (cfg as any)?.requestTimeout === 'number') {
35
- this.requestTimeout = (cfg as any).requestTimeout
36
- }
37
- if (typeof (cfg as any)?.maxRetries === 'number') {
38
- this.maxRetries = (cfg as any).maxRetries
39
- }
40
31
  if (typeof (cfg as any)?.writeDebounceMs === 'number') {
41
32
  this.writeDebounceMs = (cfg as any).writeDebounceMs
42
33
  }
@@ -65,46 +56,9 @@ export class SwitchBotClient implements ISwitchBotClient {
65
56
  }
66
57
  }
67
58
 
68
- private async fetchWithTimeoutAndRetry(url: string, opts: any = {}, timeoutMs?: number, retries?: number) {
69
- const to = typeof timeoutMs === 'number' ? timeoutMs : this.requestTimeout
70
- const max = typeof retries === 'number' ? retries : this.maxRetries
71
-
72
- let attempt = 0
73
- while (true) {
74
- attempt += 1
75
- const controller = new AbortController()
76
- const timer = setTimeout(() => controller.abort(), to)
77
- try {
78
- const fetchOpts = { ...opts }
79
- try {
80
- Object.defineProperty(fetchOpts, 'signal', { value: controller.signal, enumerable: false, configurable: true })
81
- } catch (_e) {
82
- // ignore
83
- }
84
- const resp = await fetch(url, fetchOpts)
85
- clearTimeout(timer)
86
- if (resp.ok) {
87
- return resp
88
- }
89
- // server error / rate limit: retry
90
- if (resp.status >= 500 || resp.status === 429) {
91
- throw new Error(`retriable response: ${resp.status}`)
92
- }
93
- return resp
94
- } catch (err: any) {
95
- clearTimeout(timer)
96
- if (attempt > max) {
97
- throw err
98
- }
99
- // exponential backoff
100
- const backoff = Math.min(100 * 2 ** (attempt - 1), 2000)
101
- await new Promise(r => setTimeout(r, backoff))
102
- }
103
- }
104
- }
59
+ // Removed fetchWithTimeoutAndRetry (HTTP fallback)
105
60
 
106
61
  async getDevice(id: string): Promise<any> {
107
- // Try client API first (with node-switchbot's smart fallback and retry)
108
62
  if (this.client?.getDevice) {
109
63
  try {
110
64
  return await this.client.getDevice(id)
@@ -114,41 +68,29 @@ export class SwitchBotClient implements ISwitchBotClient {
114
68
  throw e
115
69
  } else if (e instanceof SwitchbotOperationError) {
116
70
  this.logger?.warn?.(`Operation error for getDevice(${id}):`, e.message, e.code)
71
+ throw e
117
72
  } else if (e instanceof CharacteristicMissingError) {
118
73
  this.logger?.warn?.(`Characteristic missing for getDevice(${id}):`, e.characteristic)
74
+ throw e
119
75
  } else {
120
- this.logger?.warn?.(`Client getDevice failed for ${id}, trying OpenAPI fallback:`, e)
76
+ this.logger?.warn?.(`Client getDevice failed for ${id}:`, e)
77
+ throw e
121
78
  }
122
79
  }
123
80
  }
124
- // Fallback: call OpenAPI via HTTP
125
- if (this.cfg.openApiToken) {
126
- const url = `${this.baseUrl}/devices/${id}`
127
- const opts = { headers: { Authorization: this.cfg.openApiToken } }
128
- const resp = await this.fetchWithTimeoutAndRetry(url, opts)
129
- return resp.json()
130
- }
131
81
  throw new SwitchbotOperationError('No SwitchBot client available', 'no_client')
132
82
  }
133
83
 
134
84
  async getDevices(): Promise<any[]> {
135
- // Try client API first
136
85
  if (this.client?.getDevices) {
137
86
  try {
138
87
  return await this.client.getDevices()
139
88
  } catch (e) {
140
- this.logger?.warn?.('Client getDevices failed, trying OpenAPI fallback:', e)
89
+ this.logger?.warn?.('Client getDevices failed:', e)
90
+ throw e
141
91
  }
142
92
  }
143
- // Fallback: call OpenAPI
144
- if (this.cfg.openApiToken) {
145
- const url = `${this.baseUrl}/devices`
146
- const opts = { headers: { Authorization: this.cfg.openApiToken } }
147
- const resp = await this.fetchWithTimeoutAndRetry(url, opts)
148
- const data = await resp.json()
149
- return (data?.body || data) as any[]
150
- }
151
- return []
93
+ throw new SwitchbotOperationError('No SwitchBot client available', 'no_client')
152
94
  }
153
95
 
154
96
  async setDeviceState(id: string, body: any): Promise<any> {
@@ -192,7 +134,6 @@ export class SwitchBotClient implements ISwitchBotClient {
192
134
  }
193
135
 
194
136
  private async _doSetDeviceState(id: string, body: any): Promise<any> {
195
- // Prefer client API (which has node-switchbot's native resilience)
196
137
  if (this.client?.setDeviceState) {
197
138
  try {
198
139
  this.logger?.debug?.(`[${id}] Using client.setDeviceState()`)
@@ -205,15 +146,17 @@ export class SwitchBotClient implements ISwitchBotClient {
205
146
  throw e
206
147
  } else if (e instanceof SwitchbotOperationError) {
207
148
  this.logger?.warn?.(`Operation error for setDeviceState(${id}):`, e.message, e.code)
149
+ throw e
208
150
  } else if (e instanceof CharacteristicMissingError) {
209
151
  this.logger?.warn?.(`Characteristic missing for setDeviceState(${id}):`, e.characteristic)
152
+ throw e
210
153
  } else {
211
- this.logger?.warn?.(`Client setDeviceState failed for ${id}, trying fallback:`, e)
154
+ this.logger?.warn?.(`Client setDeviceState failed for ${id}:`, e)
155
+ throw e
212
156
  }
213
157
  }
214
158
  }
215
159
 
216
- // Try generic sendCommand if available
217
160
  if (this.client?.sendCommand) {
218
161
  try {
219
162
  this.logger?.debug?.(`[${id}] Using client.sendCommand()`)
@@ -226,34 +169,17 @@ export class SwitchBotClient implements ISwitchBotClient {
226
169
  throw e
227
170
  } else if (e instanceof SwitchbotOperationError) {
228
171
  this.logger?.warn?.(`Operation error for sendCommand(${id}):`, e.message, e.code)
172
+ throw e
229
173
  } else if (e instanceof CharacteristicMissingError) {
230
174
  this.logger?.warn?.(`Characteristic missing for sendCommand(${id}):`, e.characteristic)
175
+ throw e
231
176
  } else {
232
- this.logger?.warn?.(`Client sendCommand failed for ${id}, trying OpenAPI:`, e)
177
+ this.logger?.warn?.(`Client sendCommand failed for ${id}:`, e)
178
+ throw e
233
179
  }
234
180
  }
235
181
  }
236
182
 
237
- // OpenAPI fallback
238
- if (this.cfg.openApiToken) {
239
- const url = `${this.baseUrl}/devices/${id}/commands`
240
- const opts = {
241
- method: 'POST',
242
- headers: {
243
- 'Authorization': this.cfg.openApiToken,
244
- 'Content-Type': 'application/json',
245
- },
246
- body: JSON.stringify(body),
247
- }
248
- this.logger?.debug?.(`[${id}] Using OpenAPI fallback POST ${url}`)
249
- this.logger?.debug?.(`[${id}] Request body:`, body)
250
- const resp = await this.fetchWithTimeoutAndRetry(url, opts)
251
- const result = await resp.json()
252
- this.logger?.debug?.(`[${id}] OpenAPI response:`, result)
253
- this.logger?.debug?.(`[${id}] Response status:`, resp.status, resp.statusText)
254
- return result
255
- }
256
-
257
183
  throw new SwitchbotOperationError('No SwitchBot client available for setDeviceState', 'no_client')
258
184
  }
259
185