@switchbot/homebridge-switchbot 5.0.0-beta.60 → 5.0.0-beta.61

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.
@@ -1,111 +1,7 @@
1
- import fs from 'node:fs';
2
1
  import { HomebridgePluginUiServer } from '@homebridge/plugin-ui-utils';
3
2
  class PluginUiServer extends HomebridgePluginUiServer {
4
3
  constructor() {
5
4
  super();
6
- /*
7
- A native method getCachedAccessories() was introduced in config-ui-x v4.37.0
8
- The following is for users who have a lower version of config-ui-x
9
- */
10
- const getCachedAccessoriesHandler = () => {
11
- try {
12
- // Some Homebridge versions store cached accessories with the scoped
13
- // plugin name ("@switchbot/homebridge-switchbot"); others may use
14
- // the unscoped id ("homebridge-switchbot"). Check both.
15
- const pluginNames = ['@switchbot/homebridge-switchbot', 'homebridge-switchbot'];
16
- const devicesToReturn = [];
17
- // The path and file of the cached accessories
18
- const accFile = `${this.homebridgeStoragePath}/accessories/cachedAccessories`;
19
- // Check the file exists
20
- if (fs.existsSync(accFile)) {
21
- // read the cached accessories file
22
- const cachedAccessories = JSON.parse(fs.readFileSync(accFile, 'utf8'));
23
- cachedAccessories.forEach((entry) => {
24
- // entry shape varies by UI version
25
- const pluginName = entry.plugin || entry?.accessory?.plugin || entry?.accessory?.pluginName;
26
- const acc = entry.accessory ?? entry;
27
- if (pluginNames.includes(pluginName)) {
28
- devicesToReturn.push(acc);
29
- }
30
- });
31
- }
32
- // Return the array
33
- console.warn(`[Homebridge UI] getCachedAccessories returning ${devicesToReturn.length} device(s)`);
34
- return devicesToReturn;
35
- }
36
- catch (e) {
37
- // Just return an empty accessory list in case of any errors
38
- console.error(`[Homebridge UI] getCachedAccessories error: ${e?.message ?? e}`);
39
- return [];
40
- }
41
- };
42
- this.onRequest('getCachedAccessories', getCachedAccessoriesHandler);
43
- // Also register with a leading slash for compatibility with some UIs
44
- this.onRequest('/getCachedAccessories', getCachedAccessoriesHandler);
45
- // Provide Matter cached accessories if Homebridge stores them separately.
46
- const getCachedMatterAccessoriesHandler = () => {
47
- try {
48
- const pluginNames = ['@switchbot/homebridge-switchbot', 'homebridge-switchbot'];
49
- const devicesToReturn = [];
50
- const accFile = `${this.homebridgeStoragePath}/accessories/cachedAccessories`;
51
- const matterFile = `${this.homebridgeStoragePath}/accessories/cachedMatterAccessories`;
52
- // Log all files in the accessories directory for debugging
53
- try {
54
- const accessoriesDir = `${this.homebridgeStoragePath}/accessories`;
55
- if (fs.existsSync(accessoriesDir)) {
56
- const files = fs.readdirSync(accessoriesDir);
57
- console.warn(`[Homebridge UI] Files in accessories directory: ${files.join(', ')}`);
58
- }
59
- }
60
- catch (e) {
61
- console.error(`[Homebridge UI] Error listing accessories directory: ${e?.message ?? e}`);
62
- }
63
- console.warn(`[Homebridge UI] Checking for cached files:`);
64
- console.warn(`[Homebridge UI] - cachedAccessories: ${fs.existsSync(accFile)}`);
65
- console.warn(`[Homebridge UI] - cachedMatterAccessories: ${fs.existsSync(matterFile)}`);
66
- console.warn(`[Homebridge UI] Matter cached accessories file exists: ${fs.existsSync(matterFile)}`);
67
- if (fs.existsSync(matterFile)) {
68
- const matterAccessories = JSON.parse(fs.readFileSync(matterFile, 'utf8'));
69
- console.warn(`[Homebridge UI] Matter Cached Accessories:`, matterAccessories);
70
- }
71
- const readAndCollect = (filePath) => {
72
- if (!fs.existsSync(filePath)) {
73
- return;
74
- }
75
- try {
76
- const parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
77
- console.warn(`[Homebridge UI] - ${filePath}: found ${parsed.length} total entries`);
78
- let matchCount = 0;
79
- parsed.forEach((entry) => {
80
- // Entry shape varies between Homebridge versions; try common locations
81
- const pluginName = entry.plugin || entry?.accessory?.plugin || entry?.accessory?.pluginName;
82
- const acc = entry.accessory ?? entry;
83
- if (pluginNames.includes(pluginName)) {
84
- devicesToReturn.push(acc);
85
- matchCount++;
86
- }
87
- });
88
- console.warn(`[Homebridge UI] - ${filePath}: matched ${matchCount} SwitchBot entries`);
89
- }
90
- catch (e) {
91
- // ignore parse errors for a single file
92
- console.error(`[Homebridge UI] - ${filePath}: parse error - ${e?.message ?? e}`);
93
- }
94
- };
95
- // Read both canonical files (some Homebridge versions use one or the other)
96
- readAndCollect(accFile);
97
- readAndCollect(matterFile);
98
- console.warn(`[Homebridge UI] getCachedMatterAccessories returning ${devicesToReturn.length} device(s)`);
99
- return devicesToReturn;
100
- }
101
- catch (e) {
102
- console.error(`[Homebridge UI] getCachedMatterAccessories error: ${e?.message ?? e}`);
103
- return [];
104
- }
105
- };
106
- this.onRequest('getCachedMatterAccessories', getCachedMatterAccessoriesHandler);
107
- // Also register with a leading slash for compatibility with some UIs
108
- this.onRequest('/getCachedMatterAccessories', getCachedMatterAccessoriesHandler);
109
5
  this.ready();
110
6
  }
111
7
  }
@@ -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":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAA;AAEtE,MAAM,cAAe,SAAQ,wBAAwB;IACnD;QACE,KAAK,EAAE,CAAA;QACP,IAAI,CAAC,KAAK,EAAE,CAAA;IACd,CAAC;CACF;AAED,SAAS,mBAAmB;IAC1B,OAAO,IAAI,cAAc,EAAE,CAAA;AAC7B,CAAC;AAED,mBAAmB,EAAE,CAAA"}
@@ -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/e649c055165426b99f89bb7d92071170d1947691/src/index.ts#L13">index.ts:13</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/ea1ffa7b07dc7b76c62319a4f551049b10d98ae6/src/index.ts#L13">index.ts:13</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.60",
5
+ "version": "5.0.0-beta.61",
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": [
@@ -1,118 +1,8 @@
1
- import fs from 'node:fs'
2
-
3
1
  import { HomebridgePluginUiServer } from '@homebridge/plugin-ui-utils'
4
2
 
5
3
  class PluginUiServer extends HomebridgePluginUiServer {
6
4
  constructor() {
7
5
  super()
8
- /*
9
- A native method getCachedAccessories() was introduced in config-ui-x v4.37.0
10
- The following is for users who have a lower version of config-ui-x
11
- */
12
- const getCachedAccessoriesHandler = () => {
13
- try {
14
- // Some Homebridge versions store cached accessories with the scoped
15
- // plugin name ("@switchbot/homebridge-switchbot"); others may use
16
- // the unscoped id ("homebridge-switchbot"). Check both.
17
- const pluginNames = ['@switchbot/homebridge-switchbot', 'homebridge-switchbot']
18
- const devicesToReturn = []
19
-
20
- // The path and file of the cached accessories
21
- const accFile = `${this.homebridgeStoragePath}/accessories/cachedAccessories`
22
-
23
- // Check the file exists
24
- if (fs.existsSync(accFile)) {
25
- // read the cached accessories file
26
- const cachedAccessories: any[] = JSON.parse(fs.readFileSync(accFile, 'utf8'))
27
-
28
- cachedAccessories.forEach((entry: any) => {
29
- // entry shape varies by UI version
30
- const pluginName = entry.plugin || entry?.accessory?.plugin || entry?.accessory?.pluginName
31
- const acc = entry.accessory ?? entry
32
- if (pluginNames.includes(pluginName)) {
33
- devicesToReturn.push(acc as never)
34
- }
35
- })
36
- }
37
- // Return the array
38
- console.warn(`[Homebridge UI] getCachedAccessories returning ${devicesToReturn.length} device(s)`)
39
- return devicesToReturn
40
- } catch (e: any) {
41
- // Just return an empty accessory list in case of any errors
42
- console.error(`[Homebridge UI] getCachedAccessories error: ${e?.message ?? e}`)
43
- return []
44
- }
45
- }
46
- this.onRequest('getCachedAccessories', getCachedAccessoriesHandler)
47
- // Also register with a leading slash for compatibility with some UIs
48
- this.onRequest('/getCachedAccessories', getCachedAccessoriesHandler)
49
- // Provide Matter cached accessories if Homebridge stores them separately.
50
- const getCachedMatterAccessoriesHandler = () => {
51
- try {
52
- const pluginNames = ['@switchbot/homebridge-switchbot', 'homebridge-switchbot']
53
- const devicesToReturn: any[] = []
54
-
55
- const accFile = `${this.homebridgeStoragePath}/accessories/cachedAccessories`
56
- const matterFile = `${this.homebridgeStoragePath}/accessories/cachedMatterAccessories`
57
-
58
- // Log all files in the accessories directory for debugging
59
- try {
60
- const accessoriesDir = `${this.homebridgeStoragePath}/accessories`
61
- if (fs.existsSync(accessoriesDir)) {
62
- const files = fs.readdirSync(accessoriesDir)
63
- console.warn(`[Homebridge UI] Files in accessories directory: ${files.join(', ')}`)
64
- }
65
- } catch (e: any) {
66
- console.error(`[Homebridge UI] Error listing accessories directory: ${e?.message ?? e}`)
67
- }
68
-
69
- console.warn(`[Homebridge UI] Checking for cached files:`)
70
- console.warn(`[Homebridge UI] - cachedAccessories: ${fs.existsSync(accFile)}`)
71
- console.warn(`[Homebridge UI] - cachedMatterAccessories: ${fs.existsSync(matterFile)}`)
72
- console.warn(`[Homebridge UI] Matter cached accessories file exists: ${fs.existsSync(matterFile)}`)
73
- if (fs.existsSync(matterFile)) {
74
- const matterAccessories: any[] = JSON.parse(fs.readFileSync(matterFile, 'utf8'))
75
- console.warn(`[Homebridge UI] Matter Cached Accessories:`, matterAccessories)
76
- }
77
-
78
- const readAndCollect = (filePath: string) => {
79
- if (!fs.existsSync(filePath)) {
80
- return
81
- }
82
- try {
83
- const parsed: any[] = JSON.parse(fs.readFileSync(filePath, 'utf8'))
84
- console.warn(`[Homebridge UI] - ${filePath}: found ${parsed.length} total entries`)
85
- let matchCount = 0
86
- parsed.forEach((entry: any) => {
87
- // Entry shape varies between Homebridge versions; try common locations
88
- const pluginName = entry.plugin || entry?.accessory?.plugin || entry?.accessory?.pluginName
89
- const acc = entry.accessory ?? entry
90
- if (pluginNames.includes(pluginName)) {
91
- devicesToReturn.push(acc as never)
92
- matchCount++
93
- }
94
- })
95
- console.warn(`[Homebridge UI] - ${filePath}: matched ${matchCount} SwitchBot entries`)
96
- } catch (e: any) {
97
- // ignore parse errors for a single file
98
- console.error(`[Homebridge UI] - ${filePath}: parse error - ${e?.message ?? e}`)
99
- }
100
- }
101
-
102
- // Read both canonical files (some Homebridge versions use one or the other)
103
- readAndCollect(accFile)
104
- readAndCollect(matterFile)
105
-
106
- console.warn(`[Homebridge UI] getCachedMatterAccessories returning ${devicesToReturn.length} device(s)`)
107
- return devicesToReturn
108
- } catch (e: any) {
109
- console.error(`[Homebridge UI] getCachedMatterAccessories error: ${e?.message ?? e}`)
110
- return []
111
- }
112
- }
113
- this.onRequest('getCachedMatterAccessories', getCachedMatterAccessoriesHandler)
114
- // Also register with a leading slash for compatibility with some UIs
115
- this.onRequest('/getCachedMatterAccessories', getCachedMatterAccessoriesHandler)
116
6
  this.ready()
117
7
  }
118
8
  }