@switchbot/homebridge-switchbot 5.0.0-beta.79 → 5.0.0-beta.80

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.
@@ -281,47 +281,142 @@
281
281
  render(list)
282
282
  }
283
283
 
284
+ async function deleteDevice(deviceId, deviceName) {
285
+ if (!confirm(`Are you sure you want to remove "${deviceName || deviceId}"?`)) {
286
+ return
287
+ }
288
+
289
+ try {
290
+ const resp = await homebridge.request('/delete-device', { deviceId })
291
+
292
+ if (!resp || resp.success === false) {
293
+ throw new Error(resp?.data?.message || 'Failed to delete device')
294
+ }
295
+
296
+ // Refresh device list
297
+ const list = await fetchDevices()
298
+ render(list)
299
+ } catch (e) {
300
+ console.error('Delete error:', e)
301
+ alert('Error: ' + (e?.message || 'Failed to delete device'))
302
+ }
303
+ }
304
+
305
+ async function editDevice(device) {
306
+ const newName = prompt('Device Name:', device.name || device.id)
307
+ if (newName === null) return // User cancelled
308
+
309
+ try {
310
+ const resp = await homebridge.request('/update-device', {
311
+ deviceId: device.id,
312
+ configDeviceName: newName || undefined,
313
+ })
314
+
315
+ if (!resp || resp.success === false) {
316
+ throw new Error(resp?.data?.message || 'Failed to update device')
317
+ }
318
+
319
+ // Refresh device list
320
+ const list = await fetchDevices()
321
+ render(list)
322
+ } catch (e) {
323
+ console.error('Update error:', e)
324
+ alert('Error: ' + (e?.message || 'Failed to update device'))
325
+ }
326
+ }
327
+
284
328
  function render(list) {
285
329
  const ul = document.getElementById('devices')
286
330
  const status = document.getElementById('status')
287
331
  if (!list.length) {
288
332
  status.textContent = 'No devices found in config.'
333
+ ul.innerHTML = ''
289
334
  return
290
335
  }
291
336
  status.textContent = `Found ${list.length} device(s)`
292
337
  ul.innerHTML = ''
293
338
  for (const d of list) {
294
339
  const li = document.createElement('li')
295
- const name = document.createElement('span')
340
+ li.style.display = 'flex'
341
+ li.style.gap = '8px'
342
+ li.style.alignItems = 'center'
343
+ li.style.justifyContent = 'space-between'
344
+ li.style.padding = '8px'
345
+ li.style.background = '#333'
346
+ li.style.borderRadius = '4px'
347
+ li.style.marginBottom = '8px'
348
+
349
+ const info = document.createElement('div')
350
+ info.style.flex = '1'
351
+
352
+ const name = document.createElement('div')
353
+ name.style.fontWeight = '500'
296
354
  name.textContent = d.name || d.id
355
+
297
356
  const code = document.createElement('code')
298
357
  code.textContent = d.id
299
- const meta = document.createElement('span')
358
+ code.style.fontSize = '12px'
359
+ code.style.opacity = '0.75'
360
+ code.style.marginLeft = '8px'
361
+
362
+ const meta = document.createElement('div')
300
363
  meta.style.opacity = '0.75'
301
- meta.style.marginLeft = '8px'
364
+ meta.style.marginTop = '4px'
365
+ meta.style.fontSize = '12px'
302
366
  const typeText = d.type ? `type: ${d.type}` : ''
303
367
  const connText = d.connectionPreference ? `conn: ${d.connectionPreference}` : ''
304
368
  const roomText = d.room ? `room: ${d.room}` : ''
305
369
  meta.textContent = [typeText, connText, roomText].filter(Boolean).join(' | ')
306
- const btn = document.createElement('button')
307
- btn.textContent = 'Copy ID'
308
- btn.addEventListener('click', async () => {
370
+
371
+ info.appendChild(name)
372
+ info.appendChild(code)
373
+ info.appendChild(meta)
374
+
375
+ const buttons = document.createElement('div')
376
+ buttons.style.display = 'flex'
377
+ buttons.style.gap = '8px'
378
+
379
+ const editBtn = document.createElement('button')
380
+ editBtn.textContent = '✏️ Edit'
381
+ editBtn.style.padding = '6px 12px'
382
+ editBtn.style.fontSize = '12px'
383
+ editBtn.onclick = async () => {
384
+ await editDevice(d)
385
+ }
386
+
387
+ const copyBtn = document.createElement('button')
388
+ copyBtn.textContent = 'Copy ID'
389
+ copyBtn.style.padding = '6px 12px'
390
+ copyBtn.style.fontSize = '12px'
391
+ copyBtn.addEventListener('click', async () => {
309
392
  try {
310
393
  await navigator.clipboard.writeText(d.id)
311
- btn.textContent = 'Copied'
312
- btn.classList.add('success')
394
+ copyBtn.textContent = 'Copied'
395
+ copyBtn.classList.add('success')
313
396
  setTimeout(() => {
314
- btn.textContent = 'Copy ID'
315
- btn.classList.remove('success')
397
+ copyBtn.textContent = 'Copy ID'
398
+ copyBtn.classList.remove('success')
316
399
  }, 1200)
317
400
  } catch (e) {
318
401
  alert('Failed to copy')
319
402
  }
320
403
  })
321
- li.appendChild(name)
322
- li.appendChild(code)
323
- li.appendChild(meta)
324
- li.appendChild(btn)
404
+
405
+ const deleteBtn = document.createElement('button')
406
+ deleteBtn.textContent = '🗑️ Delete'
407
+ deleteBtn.style.padding = '6px 12px'
408
+ deleteBtn.style.fontSize = '12px'
409
+ deleteBtn.style.background = '#ef4444'
410
+ deleteBtn.onclick = async () => {
411
+ await deleteDevice(d.id, d.name || d.id)
412
+ }
413
+
414
+ buttons.appendChild(editBtn)
415
+ buttons.appendChild(copyBtn)
416
+ buttons.appendChild(deleteBtn)
417
+
418
+ li.appendChild(info)
419
+ li.appendChild(buttons)
325
420
  ul.appendChild(li)
326
421
  }
327
422
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/homebridge-ui/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAgB,MAAM,6BAA6B,CAAA;AAGpF,QAAA,MAAM,MAAM,0BAAiC,CAAA;AAoP7C,eAAe,MAAM,CAAA"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/homebridge-ui/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAgB,MAAM,6BAA6B,CAAA;AAGpF,QAAA,MAAM,MAAM,0BAAiC,CAAA;AA4U7C,eAAe,MAAM,CAAA"}
@@ -167,6 +167,76 @@ server.onRequest('/add-device', async (body) => {
167
167
  throw new RequestError('Failed to add device', e);
168
168
  }
169
169
  });
170
+ server.onRequest('/update-device', async (body) => {
171
+ try {
172
+ const { deviceId, configDeviceName, connectionPreference, room } = body;
173
+ if (!deviceId) {
174
+ throw new Error('Device ID is required');
175
+ }
176
+ const { config, platform, cfgPath } = await getSwitchBotPlatformConfig();
177
+ console.log('[SwitchBot UI] POST /update-device - Updating:', deviceId);
178
+ // Find and update device
179
+ if (!Array.isArray(platform.devices)) {
180
+ throw new TypeError('No devices found in config');
181
+ }
182
+ const device = platform.devices.find((d) => (d.deviceId ?? d.id) === deviceId);
183
+ if (!device) {
184
+ throw new Error('Device not found in config');
185
+ }
186
+ // Update properties
187
+ if (configDeviceName !== undefined) {
188
+ device.configDeviceName = configDeviceName;
189
+ }
190
+ if (connectionPreference !== undefined) {
191
+ device.connectionPreference = connectionPreference;
192
+ }
193
+ if (room !== undefined) {
194
+ device.room = room || undefined;
195
+ }
196
+ // Save config
197
+ await fs.writeFile(cfgPath, JSON.stringify(config, null, 2), 'utf8');
198
+ console.log('[SwitchBot UI] Device updated successfully:', deviceId);
199
+ return {
200
+ success: true,
201
+ data: { message: `Device updated successfully` },
202
+ };
203
+ }
204
+ catch (e) {
205
+ console.error('[SwitchBot UI] Error in /update-device:', e);
206
+ throw new RequestError('Failed to update device', e);
207
+ }
208
+ });
209
+ server.onRequest('/delete-device', async (body) => {
210
+ try {
211
+ const { deviceId } = body;
212
+ if (!deviceId) {
213
+ throw new Error('Device ID is required');
214
+ }
215
+ const { config, platform, cfgPath } = await getSwitchBotPlatformConfig();
216
+ console.log('[SwitchBot UI] POST /delete-device - Deleting:', deviceId);
217
+ // Remove device from array
218
+ if (!Array.isArray(platform.devices)) {
219
+ throw new TypeError('No devices found in config');
220
+ }
221
+ const index = platform.devices.findIndex((d) => (d.deviceId ?? d.id) === deviceId);
222
+ if (index === -1) {
223
+ throw new Error('Device not found in config');
224
+ }
225
+ const deviceName = platform.devices[index].configDeviceName || deviceId;
226
+ platform.devices.splice(index, 1);
227
+ // Save config
228
+ await fs.writeFile(cfgPath, JSON.stringify(config, null, 2), 'utf8');
229
+ console.log('[SwitchBot UI] Device deleted successfully:', deviceId);
230
+ return {
231
+ success: true,
232
+ data: { message: `Device "${deviceName}" removed from config` },
233
+ };
234
+ }
235
+ catch (e) {
236
+ console.error('[SwitchBot UI] Error in /delete-device:', e);
237
+ throw new RequestError('Failed to delete device', e);
238
+ }
239
+ });
170
240
  server.onRequest('/credentials', async (body) => {
171
241
  try {
172
242
  // Handle both GET and POST requests
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/homebridge-ui/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/homebridge-ui/server.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/42cb2bab88e1db495b6b92e75a31f7cf34eb8670/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/5c6fbd2e3e95c852faa85ecc44c9600a943cddfc/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.79",
5
+ "version": "5.0.0-beta.80",
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": [
@@ -281,47 +281,142 @@
281
281
  render(list)
282
282
  }
283
283
 
284
+ async function deleteDevice(deviceId, deviceName) {
285
+ if (!confirm(`Are you sure you want to remove "${deviceName || deviceId}"?`)) {
286
+ return
287
+ }
288
+
289
+ try {
290
+ const resp = await homebridge.request('/delete-device', { deviceId })
291
+
292
+ if (!resp || resp.success === false) {
293
+ throw new Error(resp?.data?.message || 'Failed to delete device')
294
+ }
295
+
296
+ // Refresh device list
297
+ const list = await fetchDevices()
298
+ render(list)
299
+ } catch (e) {
300
+ console.error('Delete error:', e)
301
+ alert('Error: ' + (e?.message || 'Failed to delete device'))
302
+ }
303
+ }
304
+
305
+ async function editDevice(device) {
306
+ const newName = prompt('Device Name:', device.name || device.id)
307
+ if (newName === null) return // User cancelled
308
+
309
+ try {
310
+ const resp = await homebridge.request('/update-device', {
311
+ deviceId: device.id,
312
+ configDeviceName: newName || undefined,
313
+ })
314
+
315
+ if (!resp || resp.success === false) {
316
+ throw new Error(resp?.data?.message || 'Failed to update device')
317
+ }
318
+
319
+ // Refresh device list
320
+ const list = await fetchDevices()
321
+ render(list)
322
+ } catch (e) {
323
+ console.error('Update error:', e)
324
+ alert('Error: ' + (e?.message || 'Failed to update device'))
325
+ }
326
+ }
327
+
284
328
  function render(list) {
285
329
  const ul = document.getElementById('devices')
286
330
  const status = document.getElementById('status')
287
331
  if (!list.length) {
288
332
  status.textContent = 'No devices found in config.'
333
+ ul.innerHTML = ''
289
334
  return
290
335
  }
291
336
  status.textContent = `Found ${list.length} device(s)`
292
337
  ul.innerHTML = ''
293
338
  for (const d of list) {
294
339
  const li = document.createElement('li')
295
- const name = document.createElement('span')
340
+ li.style.display = 'flex'
341
+ li.style.gap = '8px'
342
+ li.style.alignItems = 'center'
343
+ li.style.justifyContent = 'space-between'
344
+ li.style.padding = '8px'
345
+ li.style.background = '#333'
346
+ li.style.borderRadius = '4px'
347
+ li.style.marginBottom = '8px'
348
+
349
+ const info = document.createElement('div')
350
+ info.style.flex = '1'
351
+
352
+ const name = document.createElement('div')
353
+ name.style.fontWeight = '500'
296
354
  name.textContent = d.name || d.id
355
+
297
356
  const code = document.createElement('code')
298
357
  code.textContent = d.id
299
- const meta = document.createElement('span')
358
+ code.style.fontSize = '12px'
359
+ code.style.opacity = '0.75'
360
+ code.style.marginLeft = '8px'
361
+
362
+ const meta = document.createElement('div')
300
363
  meta.style.opacity = '0.75'
301
- meta.style.marginLeft = '8px'
364
+ meta.style.marginTop = '4px'
365
+ meta.style.fontSize = '12px'
302
366
  const typeText = d.type ? `type: ${d.type}` : ''
303
367
  const connText = d.connectionPreference ? `conn: ${d.connectionPreference}` : ''
304
368
  const roomText = d.room ? `room: ${d.room}` : ''
305
369
  meta.textContent = [typeText, connText, roomText].filter(Boolean).join(' | ')
306
- const btn = document.createElement('button')
307
- btn.textContent = 'Copy ID'
308
- btn.addEventListener('click', async () => {
370
+
371
+ info.appendChild(name)
372
+ info.appendChild(code)
373
+ info.appendChild(meta)
374
+
375
+ const buttons = document.createElement('div')
376
+ buttons.style.display = 'flex'
377
+ buttons.style.gap = '8px'
378
+
379
+ const editBtn = document.createElement('button')
380
+ editBtn.textContent = '✏️ Edit'
381
+ editBtn.style.padding = '6px 12px'
382
+ editBtn.style.fontSize = '12px'
383
+ editBtn.onclick = async () => {
384
+ await editDevice(d)
385
+ }
386
+
387
+ const copyBtn = document.createElement('button')
388
+ copyBtn.textContent = 'Copy ID'
389
+ copyBtn.style.padding = '6px 12px'
390
+ copyBtn.style.fontSize = '12px'
391
+ copyBtn.addEventListener('click', async () => {
309
392
  try {
310
393
  await navigator.clipboard.writeText(d.id)
311
- btn.textContent = 'Copied'
312
- btn.classList.add('success')
394
+ copyBtn.textContent = 'Copied'
395
+ copyBtn.classList.add('success')
313
396
  setTimeout(() => {
314
- btn.textContent = 'Copy ID'
315
- btn.classList.remove('success')
397
+ copyBtn.textContent = 'Copy ID'
398
+ copyBtn.classList.remove('success')
316
399
  }, 1200)
317
400
  } catch (e) {
318
401
  alert('Failed to copy')
319
402
  }
320
403
  })
321
- li.appendChild(name)
322
- li.appendChild(code)
323
- li.appendChild(meta)
324
- li.appendChild(btn)
404
+
405
+ const deleteBtn = document.createElement('button')
406
+ deleteBtn.textContent = '🗑️ Delete'
407
+ deleteBtn.style.padding = '6px 12px'
408
+ deleteBtn.style.fontSize = '12px'
409
+ deleteBtn.style.background = '#ef4444'
410
+ deleteBtn.onclick = async () => {
411
+ await deleteDevice(d.id, d.name || d.id)
412
+ }
413
+
414
+ buttons.appendChild(editBtn)
415
+ buttons.appendChild(copyBtn)
416
+ buttons.appendChild(deleteBtn)
417
+
418
+ li.appendChild(info)
419
+ li.appendChild(buttons)
325
420
  ul.appendChild(li)
326
421
  }
327
422
  }
@@ -194,6 +194,94 @@ server.onRequest('/add-device', async (body: any) => {
194
194
  }
195
195
  })
196
196
 
197
+ server.onRequest('/update-device', async (body: any) => {
198
+ try {
199
+ const { deviceId, configDeviceName, connectionPreference, room } = body
200
+
201
+ if (!deviceId) {
202
+ throw new Error('Device ID is required')
203
+ }
204
+
205
+ const { config, platform, cfgPath } = await getSwitchBotPlatformConfig()
206
+
207
+ console.log('[SwitchBot UI] POST /update-device - Updating:', deviceId)
208
+
209
+ // Find and update device
210
+ if (!Array.isArray(platform.devices)) {
211
+ throw new TypeError('No devices found in config')
212
+ }
213
+
214
+ const device = platform.devices.find((d: any) => (d.deviceId ?? d.id) === deviceId)
215
+ if (!device) {
216
+ throw new Error('Device not found in config')
217
+ }
218
+
219
+ // Update properties
220
+ if (configDeviceName !== undefined) {
221
+ device.configDeviceName = configDeviceName
222
+ }
223
+ if (connectionPreference !== undefined) {
224
+ device.connectionPreference = connectionPreference
225
+ }
226
+ if (room !== undefined) {
227
+ device.room = room || undefined
228
+ }
229
+
230
+ // Save config
231
+ await fs.writeFile(cfgPath, JSON.stringify(config, null, 2), 'utf8')
232
+
233
+ console.log('[SwitchBot UI] Device updated successfully:', deviceId)
234
+
235
+ return {
236
+ success: true,
237
+ data: { message: `Device updated successfully` },
238
+ }
239
+ } catch (e) {
240
+ console.error('[SwitchBot UI] Error in /update-device:', e)
241
+ throw new RequestError('Failed to update device', e)
242
+ }
243
+ })
244
+
245
+ server.onRequest('/delete-device', async (body: any) => {
246
+ try {
247
+ const { deviceId } = body
248
+
249
+ if (!deviceId) {
250
+ throw new Error('Device ID is required')
251
+ }
252
+
253
+ const { config, platform, cfgPath } = await getSwitchBotPlatformConfig()
254
+
255
+ console.log('[SwitchBot UI] POST /delete-device - Deleting:', deviceId)
256
+
257
+ // Remove device from array
258
+ if (!Array.isArray(platform.devices)) {
259
+ throw new TypeError('No devices found in config')
260
+ }
261
+
262
+ const index = platform.devices.findIndex((d: any) => (d.deviceId ?? d.id) === deviceId)
263
+ if (index === -1) {
264
+ throw new Error('Device not found in config')
265
+ }
266
+
267
+ const deviceName = platform.devices[index].configDeviceName || deviceId
268
+ platform.devices.splice(index, 1)
269
+
270
+ // Save config
271
+ await fs.writeFile(cfgPath, JSON.stringify(config, null, 2), 'utf8')
272
+
273
+ console.log('[SwitchBot UI] Device deleted successfully:', deviceId)
274
+
275
+ return {
276
+ success: true,
277
+ data: { message: `Device "${deviceName}" removed from config` },
278
+ }
279
+ } catch (e) {
280
+ console.error('[SwitchBot UI] Error in /delete-device:', e)
281
+ throw new RequestError('Failed to delete device', e)
282
+ }
283
+ })
284
+
197
285
  server.onRequest('/credentials', async (body: any) => {
198
286
  try {
199
287
  // Handle both GET and POST requests