@switchbot/homebridge-switchbot 5.2.1 → 5.2.2-beta.1
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/.github/copilot-instructions.md +4 -0
- package/.github/npm-version-script-esm.js +100 -0
- package/dist/SwitchBotHAPPlatform.d.ts.map +1 -1
- package/dist/SwitchBotHAPPlatform.js +8 -6
- package/dist/SwitchBotHAPPlatform.js.map +1 -1
- package/dist/cacheRepair.d.ts +19 -0
- package/dist/cacheRepair.d.ts.map +1 -0
- package/dist/cacheRepair.js +68 -0
- package/dist/cacheRepair.js.map +1 -0
- package/dist/deviceCommandMapper.d.ts +19 -5
- package/dist/deviceCommandMapper.d.ts.map +1 -1
- package/dist/deviceCommandMapper.js +132 -312
- package/dist/deviceCommandMapper.js.map +1 -1
- package/dist/devices/genericDevice.d.ts.map +1 -1
- package/dist/devices/genericDevice.js +8 -2
- package/dist/devices/genericDevice.js.map +1 -1
- package/dist/homebridge-ui/deviceCommandMapper.js +132 -312
- package/dist/homebridge-ui/deviceCommandMapper.js.map +1 -1
- package/dist/homebridge-ui/switchbotClient.js +30 -9
- package/dist/homebridge-ui/switchbotClient.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/switchbotClient.d.ts +1 -0
- package/dist/switchbotClient.d.ts.map +1 -1
- package/dist/switchbotClient.js +30 -9
- package/dist/switchbotClient.js.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +21 -1
- package/dist/utils.js.map +1 -1
- package/docs/variables/default.html +1 -1
- package/package.json +2 -2
- package/src/SwitchBotHAPPlatform.ts +10 -6
- package/src/cacheRepair.ts +79 -0
- package/src/deviceCommandMapper.ts +142 -317
- package/src/devices/genericDevice.ts +8 -2
- package/src/index.ts +3 -0
- package/src/switchbotClient.ts +30 -9
- package/src/utils.ts +21 -1
- package/test/client/node-switchbot-commands.spec.ts +85 -0
- package/test/client/switchbot-client-debounce.spec.ts +17 -0
- package/test/client/switchbot-client-discovery.spec.ts +40 -0
- package/test/device/genericDevice-blepoll.spec.ts +42 -0
- package/test/platform/hap-cache-restart.spec.ts +112 -0
- package/test/utils/utils.spec.ts +26 -0
|
@@ -1,319 +1,139 @@
|
|
|
1
1
|
// deviceCommandMapper.ts
|
|
2
|
-
// Maps HAP/Matter commands to node-switchbot device methods
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
// SwitchBot Water Detector (read-only)
|
|
121
|
-
'water detector': {},
|
|
122
|
-
// SwitchBot Garage Door Opener
|
|
123
|
-
'garage door opener': {
|
|
124
|
-
open: async (device) => device.open(),
|
|
125
|
-
close: async (device) => device.close(),
|
|
126
|
-
stop: async (device) => device.stop(),
|
|
127
|
-
},
|
|
128
|
-
// SwitchBot Relay Switch 1
|
|
129
|
-
'relay switch 1': {
|
|
130
|
-
turnOn: async (device) => device.turnOn(),
|
|
131
|
-
turnOff: async (device) => device.turnOff(),
|
|
132
|
-
},
|
|
133
|
-
// SwitchBot Relay Switch 1PM
|
|
134
|
-
'relay switch 1pm': {
|
|
135
|
-
turnOn: async (device) => device.turnOn(),
|
|
136
|
-
turnOff: async (device) => device.turnOff(),
|
|
137
|
-
},
|
|
138
|
-
// SwitchBot Smart Radiator Thermostat (read-only or not directly controllable)
|
|
139
|
-
'smart radiator thermostat': {},
|
|
140
|
-
// SwitchBot Humidifier2
|
|
141
|
-
'humidifier2': {
|
|
142
|
-
turnOn: async (device) => device.turnOn(),
|
|
143
|
-
turnOff: async (device) => device.turnOff(),
|
|
144
|
-
setMode: async (device, body) => device.setMode(body?.parameter),
|
|
145
|
-
setHumidity: async (device, body) => device.setHumidity(body?.parameter),
|
|
146
|
-
},
|
|
147
|
-
// SwitchBot MeterPlus (read-only)
|
|
148
|
-
'meterplus': {},
|
|
149
|
-
// SwitchBot Meter Pro (read-only)
|
|
150
|
-
'meter pro': {},
|
|
151
|
-
// SwitchBot MeterPro (read-only)
|
|
152
|
-
'meterpro': {},
|
|
153
|
-
// SwitchBot RGBICWW Floor Lamp
|
|
154
|
-
'rgbicww floor lamp': {
|
|
155
|
-
turnOn: async (device) => device.turnOn(),
|
|
156
|
-
turnOff: async (device) => device.turnOff(),
|
|
157
|
-
setBrightness: async (device, body) => device.setBrightness(body?.parameter),
|
|
158
|
-
setColor: async (device, body) => device.setColor(body?.parameter),
|
|
159
|
-
},
|
|
160
|
-
// SwitchBot RGBICWW Strip Light
|
|
161
|
-
'rgbicww strip light': {
|
|
162
|
-
turnOn: async (device) => device.turnOn(),
|
|
163
|
-
turnOff: async (device) => device.turnOff(),
|
|
164
|
-
setBrightness: async (device, body) => device.setBrightness(body?.parameter),
|
|
165
|
-
setColor: async (device, body) => device.setColor(body?.parameter),
|
|
166
|
-
},
|
|
167
|
-
// SwitchBot Circulator Fan
|
|
168
|
-
'circulator fan': {
|
|
169
|
-
turnOn: async (device) => device.turnOn(),
|
|
170
|
-
turnOff: async (device) => device.turnOff(),
|
|
171
|
-
setSpeed: async (device, body) => device.setSpeed(body?.parameter),
|
|
172
|
-
swing: async (device) => device.swing(),
|
|
173
|
-
},
|
|
174
|
-
// SwitchBot Battery Circulator Fan
|
|
175
|
-
'battery circulator fan': {
|
|
176
|
-
turnOn: async (device) => device.turnOn(),
|
|
177
|
-
turnOff: async (device) => device.turnOff(),
|
|
178
|
-
setSpeed: async (device, body) => device.setSpeed(body?.parameter),
|
|
179
|
-
swing: async (device) => device.swing(),
|
|
180
|
-
},
|
|
181
|
-
// SwitchBot Standing Circulator Fan
|
|
182
|
-
'standing circulator fan': {
|
|
183
|
-
turnOn: async (device) => device.turnOn(),
|
|
184
|
-
turnOff: async (device) => device.turnOff(),
|
|
185
|
-
setSpeed: async (device, body) => device.setSpeed(body?.parameter),
|
|
186
|
-
swing: async (device) => device.swing(),
|
|
187
|
-
},
|
|
188
|
-
// SwitchBot Bot
|
|
189
|
-
'bot': {
|
|
190
|
-
turnOn: async (device) => device.turnOn(),
|
|
191
|
-
turnOff: async (device) => device.turnOff(),
|
|
192
|
-
press: async (device) => device.press(),
|
|
193
|
-
},
|
|
194
|
-
// SwitchBot Curtain
|
|
195
|
-
'curtain': {
|
|
196
|
-
open: async (device) => device.open(),
|
|
197
|
-
close: async (device) => device.close(),
|
|
198
|
-
pause: async (device) => device.pause(),
|
|
199
|
-
setPosition: async (device, body) => device.setPosition(body?.parameter),
|
|
200
|
-
},
|
|
201
|
-
// SwitchBot Blind Tilt
|
|
202
|
-
'blind tilt': {
|
|
203
|
-
open: async (device) => device.open(),
|
|
204
|
-
close: async (device) => device.close(),
|
|
205
|
-
pause: async (device) => device.pause(),
|
|
206
|
-
setPosition: async (device, body) => device.setPosition(body?.parameter),
|
|
207
|
-
},
|
|
208
|
-
// SwitchBot Roller Shade
|
|
209
|
-
'roller shade': {
|
|
210
|
-
open: async (device) => device.open(),
|
|
211
|
-
close: async (device) => device.close(),
|
|
212
|
-
pause: async (device) => device.pause(),
|
|
213
|
-
setPosition: async (device, body) => device.setPosition(body?.parameter),
|
|
214
|
-
},
|
|
215
|
-
// SwitchBot Plug
|
|
216
|
-
'plug': {
|
|
217
|
-
turnOn: async (device) => device.turnOn(),
|
|
218
|
-
turnOff: async (device) => device.turnOff(),
|
|
219
|
-
},
|
|
220
|
-
// SwitchBot Strip Light 3
|
|
221
|
-
'strip light 3': {
|
|
222
|
-
turnOn: async (device) => device.turnOn(),
|
|
223
|
-
turnOff: async (device) => device.turnOff(),
|
|
224
|
-
setBrightness: async (device, body) => device.setBrightness(body?.parameter),
|
|
225
|
-
setColor: async (device, body) => device.setColor(body?.parameter),
|
|
226
|
-
},
|
|
227
|
-
// SwitchBot Floor Lamp
|
|
228
|
-
'floor lamp': {
|
|
229
|
-
turnOn: async (device) => device.turnOn(),
|
|
230
|
-
turnOff: async (device) => device.turnOff(),
|
|
231
|
-
setBrightness: async (device, body) => device.setBrightness(body?.parameter),
|
|
232
|
-
setColor: async (device, body) => device.setColor(body?.parameter),
|
|
233
|
-
},
|
|
234
|
-
// SwitchBot RGBIC Neon Rope Light
|
|
235
|
-
'rgbic neon rope light': {
|
|
236
|
-
turnOn: async (device) => device.turnOn(),
|
|
237
|
-
turnOff: async (device) => device.turnOff(),
|
|
238
|
-
setBrightness: async (device, body) => device.setBrightness(body?.parameter),
|
|
239
|
-
setColor: async (device, body) => device.setColor(body?.parameter),
|
|
240
|
-
},
|
|
241
|
-
// SwitchBot RGBIC Neon Wire Rope Light
|
|
242
|
-
'rgbic neon wire rope light': {
|
|
243
|
-
turnOn: async (device) => device.turnOn(),
|
|
244
|
-
turnOff: async (device) => device.turnOff(),
|
|
245
|
-
setBrightness: async (device, body) => device.setBrightness(body?.parameter),
|
|
246
|
-
setColor: async (device, body) => device.setColor(body?.parameter),
|
|
247
|
-
},
|
|
248
|
-
// SwitchBot Plug Mini
|
|
249
|
-
'plug mini': {
|
|
250
|
-
turnOn: async (device) => device.turnOn(),
|
|
251
|
-
turnOff: async (device) => device.turnOff(),
|
|
252
|
-
},
|
|
253
|
-
// SwitchBot Color Bulb
|
|
254
|
-
'color bulb': {
|
|
255
|
-
turnOn: async (device) => device.turnOn(),
|
|
256
|
-
turnOff: async (device) => device.turnOff(),
|
|
257
|
-
setBrightness: async (device, body) => device.setBrightness(body?.parameter),
|
|
258
|
-
setColor: async (device, body) => device.setColor(body?.parameter),
|
|
259
|
-
},
|
|
260
|
-
// SwitchBot Light Strip
|
|
261
|
-
'light strip': {
|
|
262
|
-
turnOn: async (device) => device.turnOn(),
|
|
263
|
-
turnOff: async (device) => device.turnOff(),
|
|
264
|
-
setBrightness: async (device, body) => device.setBrightness(body?.parameter),
|
|
265
|
-
setColor: async (device, body) => device.setColor(body?.parameter),
|
|
266
|
-
},
|
|
267
|
-
// SwitchBot Fan
|
|
268
|
-
'fan': {
|
|
269
|
-
turnOn: async (device) => device.turnOn(),
|
|
270
|
-
turnOff: async (device) => device.turnOff(),
|
|
271
|
-
setSpeed: async (device, body) => device.setSpeed(body?.parameter),
|
|
272
|
-
swing: async (device) => device.swing(),
|
|
273
|
-
},
|
|
274
|
-
// SwitchBot Lock
|
|
275
|
-
'lock': {
|
|
276
|
-
lock: async (device) => device.lock(),
|
|
277
|
-
unlock: async (device) => device.unlock(),
|
|
278
|
-
},
|
|
279
|
-
// SwitchBot Curtain 3
|
|
280
|
-
'curtain3': {
|
|
281
|
-
open: async (device) => device.open(),
|
|
282
|
-
close: async (device) => device.close(),
|
|
283
|
-
pause: async (device) => device.pause(),
|
|
284
|
-
setPosition: async (device, body) => device.setPosition(body?.parameter),
|
|
285
|
-
},
|
|
286
|
-
// SwitchBot Meter
|
|
287
|
-
'meter': {}, // Read-only
|
|
288
|
-
// SwitchBot Motion Sensor
|
|
289
|
-
'motion sensor': {}, // Read-only
|
|
290
|
-
// SwitchBot Contact Sensor
|
|
291
|
-
'contact sensor': {}, // Read-only
|
|
292
|
-
// SwitchBot Humidifier
|
|
293
|
-
'humidifier': {
|
|
294
|
-
turnOn: async (device) => device.turnOn(),
|
|
295
|
-
turnOff: async (device) => device.turnOff(),
|
|
296
|
-
setMode: async (device, body) => device.setMode(body?.parameter),
|
|
297
|
-
setHumidity: async (device, body) => device.setHumidity(body?.parameter),
|
|
298
|
-
},
|
|
299
|
-
// SwitchBot Vacuum
|
|
300
|
-
'vacuum': {
|
|
301
|
-
start: async (device) => device.start(),
|
|
302
|
-
stop: async (device) => device.stop(),
|
|
303
|
-
pause: async (device) => device.pause(),
|
|
304
|
-
dock: async (device) => device.dock(),
|
|
305
|
-
resume: async (device) => device.resume(),
|
|
306
|
-
locate: async (device) => device.locate(),
|
|
2
|
+
// Maps HAP/Matter commands to node-switchbot device methods.
|
|
3
|
+
//
|
|
4
|
+
// Accessories send generic commands (turnOn, setBrightness, setPosition, ...). Each command maps to
|
|
5
|
+
// the node-switchbot method that performs it, and is used when the device has that method. This
|
|
6
|
+
// works for every node-switchbot device class without listing device type strings, which differ
|
|
7
|
+
// between the OpenAPI ("Plug Mini (US)") and BLE ("Meter Plus") and were often missing here.
|
|
8
|
+
function numberParameter(body) {
|
|
9
|
+
const value = Number(body?.parameter);
|
|
10
|
+
if (!Number.isFinite(value)) {
|
|
11
|
+
throw new TypeError(`Expected a number, got ${JSON.stringify(body?.parameter)}`);
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* HomeKit and Matter send color temperature in mireds (about 140-500); node-switchbot expects
|
|
17
|
+
* kelvin (2700-6500). Values above 1000 are taken as kelvin already.
|
|
18
|
+
*/
|
|
19
|
+
export function toKelvin(value) {
|
|
20
|
+
const kelvin = value > 1000 ? value : 1_000_000 / value;
|
|
21
|
+
return Math.round(Math.min(6500, Math.max(2700, kelvin)));
|
|
22
|
+
}
|
|
23
|
+
/** Hue 0-360, saturation 0-100, at full value, to RGB 0-255 */
|
|
24
|
+
export function hsToRgb(hue, saturation) {
|
|
25
|
+
const h = (((hue % 360) + 360) % 360) / 60;
|
|
26
|
+
const s = Math.min(100, Math.max(0, saturation)) / 100;
|
|
27
|
+
const c = s;
|
|
28
|
+
const x = c * (1 - Math.abs((h % 2) - 1));
|
|
29
|
+
const [r, g, b] = h < 1
|
|
30
|
+
? [c, x, 0]
|
|
31
|
+
: h < 2
|
|
32
|
+
? [x, c, 0]
|
|
33
|
+
: h < 3
|
|
34
|
+
? [0, c, x]
|
|
35
|
+
: h < 4
|
|
36
|
+
? [0, x, c]
|
|
37
|
+
: h < 5 ? [x, 0, c] : [c, 0, x];
|
|
38
|
+
const m = 1 - c;
|
|
39
|
+
return [r, g, b].map(v => Math.round((v + m) * 255));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Parse a color parameter: `"hue,saturation"` (from HomeKit), `"r:g:b"` (OpenAPI style) or
|
|
43
|
+
* `"#rrggbb"`.
|
|
44
|
+
*/
|
|
45
|
+
export function toRgb(parameter) {
|
|
46
|
+
const text = String(parameter ?? '').trim();
|
|
47
|
+
const hex = /^#?([0-9a-f]{6})$/i.exec(text);
|
|
48
|
+
if (hex) {
|
|
49
|
+
const n = Number.parseInt(hex[1], 16);
|
|
50
|
+
return [(n >> 16) & 0xFF, (n >> 8) & 0xFF, n & 0xFF];
|
|
51
|
+
}
|
|
52
|
+
if (text.includes(':')) {
|
|
53
|
+
const parts = text.split(':').map(Number);
|
|
54
|
+
if (parts.length === 3 && parts.every(Number.isFinite)) {
|
|
55
|
+
return parts.map(v => Math.round(Math.min(255, Math.max(0, v))));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (text.includes(',')) {
|
|
59
|
+
const [hue, saturation] = text.split(',').map(Number);
|
|
60
|
+
if (Number.isFinite(hue) && Number.isFinite(saturation)) {
|
|
61
|
+
return hsToRgb(hue, saturation);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
throw new TypeError(`Unrecognised color ${JSON.stringify(parameter)}`);
|
|
65
|
+
}
|
|
66
|
+
const call = (method) => ({ methods: [method], handler: (device) => device[method]() });
|
|
67
|
+
const commandSpecs = {
|
|
68
|
+
turnOn: call('turnOn'),
|
|
69
|
+
turnOff: call('turnOff'),
|
|
70
|
+
toggle: call('toggle'),
|
|
71
|
+
press: call('press'),
|
|
72
|
+
open: call('open'),
|
|
73
|
+
close: call('close'),
|
|
74
|
+
pause: call('pause'),
|
|
75
|
+
lock: call('lock'),
|
|
76
|
+
unlock: call('unlock'),
|
|
77
|
+
setBrightness: {
|
|
78
|
+
methods: ['setBrightness'],
|
|
79
|
+
handler: (device, body) => device.setBrightness(numberParameter(body)),
|
|
80
|
+
},
|
|
81
|
+
setColorTemperature: {
|
|
82
|
+
methods: ['setColorTemperature', 'setColorTemp'],
|
|
83
|
+
handler: (device, body, method) => {
|
|
84
|
+
const kelvin = toKelvin(numberParameter(body));
|
|
85
|
+
return method === 'setColorTemp' ? device.setColorTemp(2700, 6500, kelvin) : device.setColorTemperature(kelvin);
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
setColor: {
|
|
89
|
+
methods: ['setColor'],
|
|
90
|
+
handler: (device, body) => device.setColor(...toRgb(body?.parameter)),
|
|
91
|
+
},
|
|
92
|
+
setPosition: {
|
|
93
|
+
methods: ['setPosition'],
|
|
94
|
+
handler: (device, body) => device.setPosition(numberParameter(body)),
|
|
95
|
+
},
|
|
96
|
+
setFanSpeed: {
|
|
97
|
+
methods: ['setFanSpeed', 'setSpeed'],
|
|
98
|
+
handler: (device, body, method) => device[method](numberParameter(body)),
|
|
99
|
+
},
|
|
100
|
+
setMode: {
|
|
101
|
+
methods: ['setMode'],
|
|
102
|
+
handler: (device, body) => device.setMode(body?.parameter),
|
|
103
|
+
},
|
|
104
|
+
setHumidity: {
|
|
105
|
+
methods: ['setTargetHumidity', 'setHumidity', 'setLevel'],
|
|
106
|
+
handler: (device, body, method) => device[method](numberParameter(body)),
|
|
107
|
+
},
|
|
108
|
+
// Vacuums: node-switchbot uses cleanUp/returnToDock with the BLE protocol version
|
|
109
|
+
start: {
|
|
110
|
+
methods: ['cleanUp', 'start'],
|
|
111
|
+
handler: (device, body, method) => method === 'cleanUp' ? device.cleanUp(Number(body?.protocolVersion) || 1) : device.start(),
|
|
112
|
+
},
|
|
113
|
+
dock: {
|
|
114
|
+
methods: ['returnToDock', 'dock'],
|
|
115
|
+
handler: (device, body, method) => method === 'returnToDock' ? device.returnToDock(Number(body?.protocolVersion) || 1) : device.dock(),
|
|
116
|
+
},
|
|
117
|
+
stop: {
|
|
118
|
+
methods: ['returnToDock', 'stop', 'pause'],
|
|
119
|
+
handler: (device, body, method) => method === 'returnToDock' ? device.returnToDock(Number(body?.protocolVersion) || 1) : device[method](),
|
|
307
120
|
},
|
|
308
|
-
// Add more device types and commands as needed
|
|
309
121
|
};
|
|
310
|
-
|
|
311
|
-
export
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
122
|
+
/** Commands this module can map, for documentation and tests */
|
|
123
|
+
export const supportedCommands = Object.keys(commandSpecs);
|
|
124
|
+
/**
|
|
125
|
+
* Get the handler for a command on a node-switchbot device, or undefined when the device has no
|
|
126
|
+
* method for it. `deviceType` is kept for callers and logging; dispatch uses the device itself.
|
|
127
|
+
*/
|
|
128
|
+
export function getDeviceCommandHandler(deviceType, command, device) {
|
|
129
|
+
const spec = Object.hasOwn(commandSpecs, command) ? commandSpecs[command] : undefined;
|
|
130
|
+
if (!spec) {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
const method = device ? spec.methods.find(name => typeof device[name] === 'function') : spec.methods[0];
|
|
134
|
+
if (!method) {
|
|
315
135
|
return undefined;
|
|
316
136
|
}
|
|
317
|
-
return
|
|
137
|
+
return async (target, body) => spec.handler(target, body, method);
|
|
318
138
|
}
|
|
319
139
|
//# sourceMappingURL=deviceCommandMapper.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deviceCommandMapper.js","sourceRoot":"","sources":["../../src/deviceCommandMapper.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"deviceCommandMapper.js","sourceRoot":"","sources":["../../src/deviceCommandMapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { getDeviceCommandHandler } from './deviceCommandMapper.js';
|
|
2
2
|
import { CharacteristicMissingError, SwitchbotAuthenticationError, SwitchbotOperationError } from './errors.js';
|
|
3
|
+
// Commands that set the same state and may replace each other while debounced
|
|
4
|
+
const WRITE_GROUP = { turnOn: 'power', turnOff: 'power', toggle: 'power' };
|
|
3
5
|
/**
|
|
4
6
|
* Thin wrapper around node-switchbot v4.0.0+
|
|
5
7
|
* Leverages upstream resilience features (retry, circuit breaker, connection intelligence)
|
|
@@ -11,6 +13,7 @@ export class SwitchBotClient {
|
|
|
11
13
|
writeDebounceMs = 100;
|
|
12
14
|
discoveryCacheTtlMs = 30_000;
|
|
13
15
|
lastDiscoveryAt = 0;
|
|
16
|
+
discoveryInFlight;
|
|
14
17
|
logger;
|
|
15
18
|
pendingWrites = new Map();
|
|
16
19
|
constructor(cfg) {
|
|
@@ -112,8 +115,12 @@ export class SwitchBotClient {
|
|
|
112
115
|
if (!this.writeDebounceMs || this.writeDebounceMs <= 0) {
|
|
113
116
|
return this._doSetDeviceState(id, body);
|
|
114
117
|
}
|
|
118
|
+
// Coalesce repeated writes of the same operation only. Power commands share one key, so a
|
|
119
|
+
// quick on/off/on sends the last one; other commands (brightness, color, position...) keep
|
|
120
|
+
// their own key so a turnOn sent together with setBrightness is not dropped.
|
|
121
|
+
const key = `${id}\u0000${WRITE_GROUP[body?.command] ?? body?.command ?? ''}`;
|
|
115
122
|
return new Promise((resolve, reject) => {
|
|
116
|
-
const existing = this.pendingWrites.get(
|
|
123
|
+
const existing = this.pendingWrites.get(key);
|
|
117
124
|
if (existing) {
|
|
118
125
|
existing.body = body;
|
|
119
126
|
existing.resolvers.push({ resolve, reject });
|
|
@@ -121,11 +128,11 @@ export class SwitchBotClient {
|
|
|
121
128
|
}
|
|
122
129
|
const resolvers = [{ resolve, reject }];
|
|
123
130
|
const timer = setTimeout(async () => {
|
|
124
|
-
const entry = this.pendingWrites.get(
|
|
131
|
+
const entry = this.pendingWrites.get(key);
|
|
125
132
|
if (!entry) {
|
|
126
133
|
return;
|
|
127
134
|
}
|
|
128
|
-
this.pendingWrites.delete(
|
|
135
|
+
this.pendingWrites.delete(key);
|
|
129
136
|
try {
|
|
130
137
|
const out = await this._doSetDeviceState(id, entry.body);
|
|
131
138
|
for (const r of entry.resolvers)
|
|
@@ -145,7 +152,7 @@ export class SwitchBotClient {
|
|
|
145
152
|
r.reject(e);
|
|
146
153
|
}
|
|
147
154
|
}, this.writeDebounceMs);
|
|
148
|
-
this.pendingWrites.set(
|
|
155
|
+
this.pendingWrites.set(key, { timer, body, resolvers });
|
|
149
156
|
});
|
|
150
157
|
}
|
|
151
158
|
async _doSetDeviceState(id, body) {
|
|
@@ -162,7 +169,7 @@ export class SwitchBotClient {
|
|
|
162
169
|
if (!command) {
|
|
163
170
|
throw new SwitchbotOperationError('No command specified in body', 'no_command');
|
|
164
171
|
}
|
|
165
|
-
const handler = getDeviceCommandHandler(deviceType, command);
|
|
172
|
+
const handler = getDeviceCommandHandler(deviceType, command, device);
|
|
166
173
|
if (!handler) {
|
|
167
174
|
throw new SwitchbotOperationError(`Unsupported command '${command}' for device type '${deviceType}'`, 'unsupported_command');
|
|
168
175
|
}
|
|
@@ -236,12 +243,26 @@ export class SwitchBotClient {
|
|
|
236
243
|
}
|
|
237
244
|
const fromManager = this.getManagedDevices();
|
|
238
245
|
const cacheValid = this.discoveryCacheTtlMs > 0 && (Date.now() - this.lastDiscoveryAt) < this.discoveryCacheTtlMs;
|
|
239
|
-
|
|
246
|
+
// A forced refresh (a device was not found) still respects the cache period once a discovery
|
|
247
|
+
// has run: an offline device would otherwise trigger a BLE scan and an OpenAPI call per lookup.
|
|
248
|
+
if (cacheValid && (!force || fromManager.length > 0)) {
|
|
240
249
|
return fromManager;
|
|
241
250
|
}
|
|
242
|
-
|
|
243
|
-
this.
|
|
244
|
-
|
|
251
|
+
// Share one discovery between concurrent callers; each BLE scan also resets the last one's results.
|
|
252
|
+
if (!this.discoveryInFlight) {
|
|
253
|
+
const client = this.client;
|
|
254
|
+
this.discoveryInFlight = (async () => {
|
|
255
|
+
try {
|
|
256
|
+
const discovered = await client.discover();
|
|
257
|
+
this.lastDiscoveryAt = Date.now();
|
|
258
|
+
return discovered;
|
|
259
|
+
}
|
|
260
|
+
finally {
|
|
261
|
+
this.discoveryInFlight = undefined;
|
|
262
|
+
}
|
|
263
|
+
})();
|
|
264
|
+
}
|
|
265
|
+
return this.discoveryInFlight;
|
|
245
266
|
}
|
|
246
267
|
}
|
|
247
268
|
//# sourceMappingURL=switchbotClient.js.map
|