@homebridge-plugins/homebridge-matter 0.0.6 → 0.1.0

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 (95) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +67 -33
  3. package/config.schema.json +73 -77
  4. package/dist/devices/index.d.ts +13 -0
  5. package/dist/devices/index.js +22 -0
  6. package/dist/devices/index.js.map +1 -0
  7. package/dist/devices/section-12-robotic/index.d.ts +6 -0
  8. package/dist/devices/section-12-robotic/index.js +7 -0
  9. package/dist/devices/section-12-robotic/index.js.map +1 -0
  10. package/dist/devices/section-12-robotic/robotic-vacuum-cleaner.d.ts +63 -0
  11. package/dist/devices/section-12-robotic/robotic-vacuum-cleaner.js +318 -0
  12. package/dist/devices/section-12-robotic/robotic-vacuum-cleaner.js.map +1 -0
  13. package/dist/devices/section-4-lighting/color-temperature-light.d.ts +7 -0
  14. package/dist/devices/section-4-lighting/color-temperature-light.js +62 -0
  15. package/dist/devices/section-4-lighting/color-temperature-light.js.map +1 -0
  16. package/dist/devices/section-4-lighting/dimmable-light.d.ts +7 -0
  17. package/dist/devices/section-4-lighting/dimmable-light.js +48 -0
  18. package/dist/devices/section-4-lighting/dimmable-light.js.map +1 -0
  19. package/dist/devices/section-4-lighting/extended-color-light.d.ts +12 -0
  20. package/dist/devices/section-4-lighting/extended-color-light.js +142 -0
  21. package/dist/devices/section-4-lighting/extended-color-light.js.map +1 -0
  22. package/dist/devices/section-4-lighting/index.d.ts +9 -0
  23. package/dist/devices/section-4-lighting/index.js +10 -0
  24. package/dist/devices/section-4-lighting/index.js.map +1 -0
  25. package/dist/devices/section-4-lighting/on-off-light.d.ts +7 -0
  26. package/dist/devices/section-4-lighting/on-off-light.js +37 -0
  27. package/dist/devices/section-4-lighting/on-off-light.js.map +1 -0
  28. package/dist/devices/section-5-smart-plugs/dimmable-plug-in-unit.d.ts +7 -0
  29. package/dist/devices/section-5-smart-plugs/dimmable-plug-in-unit.js +48 -0
  30. package/dist/devices/section-5-smart-plugs/dimmable-plug-in-unit.js.map +1 -0
  31. package/dist/devices/section-5-smart-plugs/index.d.ts +7 -0
  32. package/dist/devices/section-5-smart-plugs/index.js +8 -0
  33. package/dist/devices/section-5-smart-plugs/index.js.map +1 -0
  34. package/dist/devices/section-5-smart-plugs/on-off-plug-in-unit.d.ts +7 -0
  35. package/dist/devices/section-5-smart-plugs/on-off-plug-in-unit.js +37 -0
  36. package/dist/devices/section-5-smart-plugs/on-off-plug-in-unit.js.map +1 -0
  37. package/dist/devices/section-6-switches/index.d.ts +6 -0
  38. package/dist/devices/section-6-switches/index.js +7 -0
  39. package/dist/devices/section-6-switches/index.js.map +1 -0
  40. package/dist/devices/section-6-switches/on-off-light-switch.d.ts +7 -0
  41. package/dist/devices/section-6-switches/on-off-light-switch.js +30 -0
  42. package/dist/devices/section-6-switches/on-off-light-switch.js.map +1 -0
  43. package/dist/devices/section-7-sensors/contact-sensor.d.ts +7 -0
  44. package/dist/devices/section-7-sensors/contact-sensor.js +27 -0
  45. package/dist/devices/section-7-sensors/contact-sensor.js.map +1 -0
  46. package/dist/devices/section-7-sensors/humidity-sensor.d.ts +7 -0
  47. package/dist/devices/section-7-sensors/humidity-sensor.js +29 -0
  48. package/dist/devices/section-7-sensors/humidity-sensor.js.map +1 -0
  49. package/dist/devices/section-7-sensors/index.d.ts +12 -0
  50. package/dist/devices/section-7-sensors/index.js +13 -0
  51. package/dist/devices/section-7-sensors/index.js.map +1 -0
  52. package/dist/devices/section-7-sensors/light-sensor.d.ts +7 -0
  53. package/dist/devices/section-7-sensors/light-sensor.js +29 -0
  54. package/dist/devices/section-7-sensors/light-sensor.js.map +1 -0
  55. package/dist/devices/section-7-sensors/occupancy-sensor.d.ts +8 -0
  56. package/dist/devices/section-7-sensors/occupancy-sensor.js +33 -0
  57. package/dist/devices/section-7-sensors/occupancy-sensor.js.map +1 -0
  58. package/dist/devices/section-7-sensors/smoke-co-alarm.d.ts +7 -0
  59. package/dist/devices/section-7-sensors/smoke-co-alarm.js +37 -0
  60. package/dist/devices/section-7-sensors/smoke-co-alarm.js.map +1 -0
  61. package/dist/devices/section-7-sensors/temperature-sensor.d.ts +7 -0
  62. package/dist/devices/section-7-sensors/temperature-sensor.js +29 -0
  63. package/dist/devices/section-7-sensors/temperature-sensor.js.map +1 -0
  64. package/dist/devices/section-7-sensors/water-leak-detector.d.ts +7 -0
  65. package/dist/devices/section-7-sensors/water-leak-detector.js +27 -0
  66. package/dist/devices/section-7-sensors/water-leak-detector.js.map +1 -0
  67. package/dist/devices/section-8-closure/door-lock.d.ts +7 -0
  68. package/dist/devices/section-8-closure/door-lock.js +48 -0
  69. package/dist/devices/section-8-closure/door-lock.js.map +1 -0
  70. package/dist/devices/section-8-closure/index.d.ts +7 -0
  71. package/dist/devices/section-8-closure/index.js +8 -0
  72. package/dist/devices/section-8-closure/index.js.map +1 -0
  73. package/dist/devices/section-8-closure/window-covering.d.ts +9 -0
  74. package/dist/devices/section-8-closure/window-covering.js +154 -0
  75. package/dist/devices/section-8-closure/window-covering.js.map +1 -0
  76. package/dist/devices/section-9-hvac/fan.d.ts +7 -0
  77. package/dist/devices/section-9-hvac/fan.js +56 -0
  78. package/dist/devices/section-9-hvac/fan.js.map +1 -0
  79. package/dist/devices/section-9-hvac/index.d.ts +7 -0
  80. package/dist/devices/section-9-hvac/index.js +8 -0
  81. package/dist/devices/section-9-hvac/index.js.map +1 -0
  82. package/dist/devices/section-9-hvac/thermostat.d.ts +7 -0
  83. package/dist/devices/section-9-hvac/thermostat.js +61 -0
  84. package/dist/devices/section-9-hvac/thermostat.js.map +1 -0
  85. package/dist/devices/types.d.ts +16 -0
  86. package/dist/devices/types.js +5 -0
  87. package/dist/devices/types.js.map +1 -0
  88. package/dist/homebridge-ui/public/index.html +269 -0
  89. package/dist/homebridge-ui/server.js +47 -0
  90. package/dist/platform.d.ts +25 -21
  91. package/dist/platform.js +133 -1023
  92. package/dist/platform.js.map +1 -1
  93. package/package.json +9 -9
  94. package/plugin-header.png +0 -0
  95. package/.claude/settings.local.json +0 -28
@@ -0,0 +1,269 @@
1
+ <style>
2
+ .dark-mode {
3
+ background-color: #242424;
4
+ color: lightgrey;
5
+
6
+ .form-control {
7
+ background-color: #333333 !important;
8
+ border: none !important;
9
+ color: #eeeeee !important;
10
+ }
11
+
12
+ thead, tbody, tr {
13
+ border-style: hidden;
14
+ }
15
+
16
+ th {
17
+ color: #eeeeee !important;
18
+ font-weight: 500 !important;
19
+ }
20
+ }
21
+ select {
22
+ background-image:
23
+ linear-gradient(45deg, transparent 50%, gray 50%),
24
+ linear-gradient(135deg, gray 50%, transparent 50%),
25
+ linear-gradient(to right, #ccc, #ccc);
26
+ background-position:
27
+ calc(100% - 20px) calc(1em + 2px),
28
+ calc(100% - 15px) calc(1em + 2px),
29
+ calc(100% - 2.5em) 0.5em;
30
+ background-size:
31
+ 5px 5px,
32
+ 5px 5px,
33
+ 1px 1.5em;
34
+ background-repeat: no-repeat;
35
+ }
36
+ </style>
37
+ <p class="text-center">
38
+ <img
39
+ src="https://github.com/homebridge-plugins/homebridge-matter/blob/latest/plugin-header.png?raw=true"
40
+ alt="homebridge-matter logo"
41
+ style="width: 60%;"
42
+ />
43
+ </p>
44
+ <div id="pageIntro" class="text-center" style="display: none;">
45
+ <p class="lead">Thank you for installing <strong>homebridge-matter</strong></p>
46
+ <button type="button" class="btn btn-primary" id="introContinue">
47
+ Continue &rarr;
48
+ </button>
49
+ </div>
50
+ <div
51
+ id="menuWrapper"
52
+ class="btn-group w-100 mb-0"
53
+ role="group"
54
+ aria-label="UI Menu"
55
+ style="display: none;"
56
+ >
57
+ <button type="button" class="btn btn-primary ml-0" id="menuSettings">
58
+ Settings
59
+ </button>
60
+ <button type="button" class="btn btn-primary" id="menuDevices">
61
+ My Devices
62
+ </button>
63
+ <button type="button" class="btn btn-primary mr-0" id="menuHome">
64
+ Support
65
+ </button>
66
+ </div>
67
+ <div
68
+ id="disabledBanner"
69
+ class="alert alert-secondary mb-0 mt-3"
70
+ role="alert"
71
+ style="display: none;"
72
+ >
73
+ Plugin is currently disabled
74
+ <button id="disabledEnable" type="button" class="btn btn-link p-0 m-0 float-right">
75
+ Enable
76
+ </button>
77
+ </div>
78
+ <div id="pageDevices" class="mt-4" style="display: none;">
79
+ <div id="deviceInfo">
80
+ <form>
81
+ <div class="form-group">
82
+ <select class="form-control" id="deviceSelect"></select>
83
+ </div>
84
+ </form>
85
+ <table class="table w-100 mt-3" id="deviceTable" style="display: none;">
86
+ <thead>
87
+ <tr class="table-active">
88
+ <th scope="col" style="width: 40%;">Device Name</th>
89
+ <th scope="col" style="width: 60%;" id="displayName"></th>
90
+ </tr>
91
+ </thead>
92
+ <tbody>
93
+ </tbody>
94
+ </table>
95
+ </div>
96
+ </div>
97
+ <div id="pageSupport" class="mt-4" style="display: none;">
98
+ <p class="text-center lead">Thank you for using <strong>homebridge-matter</strong></p>
99
+ <p class="text-center">The links below will take you to our GitHub wiki</p>
100
+ <h4>Setup</h4>
101
+ <ul>
102
+ <li>
103
+ <a href="https://github.com/homebridge/homebridge/wiki/How-to-Install-Alternate-Plugin-Versions" target="_blank"
104
+ >Beta Version</a
105
+ >
106
+ </li>
107
+ </ul>
108
+ <h4>Help/About</h4>
109
+ <ul>
110
+ <li>
111
+ <a href="https://github.com/homebridge-plugins/homebridge-matter/issues/new/choose" target="_blank"
112
+ >Support Request</a
113
+ >
114
+ </li>
115
+ <li>
116
+ <a href="https://github.com/homebridge-plugins/homebridge-matter/blob/latest/CHANGELOG.md" target="_blank"
117
+ >Changelog</a
118
+ >
119
+ </li>
120
+ <li>
121
+ <a href="https://github.com/sponsors/bwp91" target="_blank">About Me</a>
122
+ </li>
123
+ </ul>
124
+ <h4>Credits</h4>
125
+ <ul>
126
+ <li>
127
+ To the developers of <a href="https://github.com/matter-js/matter.js" target="_blank">matter.js</a> who make the Matter integration possible.
128
+ </li>
129
+ </ul>
130
+
131
+ <h4>Disclaimer</h4>
132
+ <ul>
133
+ <li>
134
+ I am in no way affiliated with Matter and this
135
+ plugin is a personal project that I maintain in my free time.
136
+ </li>
137
+ <li>
138
+ Use this plugin entirely at your own risk - please see licence for more information.
139
+ </li>
140
+ </ul>
141
+ </div>
142
+ <script>
143
+ ;(async () => {
144
+ try {
145
+ const currentConfig = await homebridge.getPluginConfig()
146
+ showIntro = () => {
147
+ homebridge.disableSaveButton?.()
148
+ const introContinue = document.getElementById('introContinue')
149
+ introContinue.addEventListener('click', () => {
150
+ homebridge.showSpinner()
151
+ document.getElementById('pageIntro').style.display = 'none'
152
+ document.getElementById('menuWrapper').style.display = 'inline-flex'
153
+ showSettings()
154
+ homebridge.hideSpinner()
155
+ })
156
+ document.getElementById('pageIntro').style.display = 'block'
157
+ }
158
+ showDevices = async () => {
159
+ homebridge.showSpinner()
160
+ homebridge.disableSaveButton?.()
161
+ homebridge.hideSchemaForm()
162
+ document.getElementById('menuHome').classList.remove('btn-elegant')
163
+ document.getElementById('menuHome').classList.add('btn-primary')
164
+ document.getElementById('menuDevices').classList.add('btn-elegant')
165
+ document.getElementById('menuDevices').classList.remove('btn-primary')
166
+ document.getElementById('menuSettings').classList.remove('btn-elegant')
167
+ document.getElementById('menuSettings').classList.add('btn-primary')
168
+ document.getElementById('pageSupport').style.display = 'none'
169
+ document.getElementById('pageDevices').style.display = 'block'
170
+ const cachedAccessories =
171
+ typeof homebridge.getCachedAccessories === 'function'
172
+ ? await homebridge.getCachedAccessories()
173
+ : await homebridge.request('/getCachedAccessories')
174
+ if (cachedAccessories.length > 0) {
175
+ cachedAccessories.sort((a, b) => {
176
+ return a.displayName.toLowerCase() > b.displayName.toLowerCase()
177
+ ? 1
178
+ : b.displayName.toLowerCase() > a.displayName.toLowerCase()
179
+ ? -1
180
+ : 0
181
+ })
182
+ }
183
+ const deviceSelect = document.getElementById('deviceSelect')
184
+ deviceSelect.innerHTML = ''
185
+ cachedAccessories.forEach(a => {
186
+ const option = document.createElement('option')
187
+ option.text = a.displayName
188
+ option.value = a.context.hbDeviceId
189
+ deviceSelect.add(option)
190
+ })
191
+ showDeviceInfo = async hbDeviceId => {
192
+ homebridge.showSpinner()
193
+ const thisAcc = cachedAccessories.find(x => x.context.hbDeviceId === hbDeviceId)
194
+ const context = thisAcc.context
195
+ document.getElementById('deviceTable').style.display = 'inline-table'
196
+ homebridge.hideSpinner()
197
+ }
198
+ deviceSelect.addEventListener('change', event => showDeviceInfo(event.target.value))
199
+ if (cachedAccessories.length > 0) {
200
+ showDeviceInfo(cachedAccessories[0].context.hbDeviceId)
201
+ } else {
202
+ const option = document.createElement('option')
203
+ option.text = 'No Devices'
204
+ deviceSelect.add(option)
205
+ deviceSelect.disabled = true
206
+ }
207
+ homebridge.hideSpinner()
208
+ }
209
+ showSupport = () => {
210
+ homebridge.showSpinner()
211
+ homebridge.disableSaveButton?.()
212
+ homebridge.hideSchemaForm()
213
+ document.getElementById('menuHome').classList.add('btn-elegant')
214
+ document.getElementById('menuHome').classList.remove('btn-primary')
215
+ document.getElementById('menuDevices').classList.remove('btn-elegant')
216
+ document.getElementById('menuDevices').classList.add('btn-primary')
217
+ document.getElementById('menuSettings').classList.remove('btn-elegant')
218
+ document.getElementById('menuSettings').classList.add('btn-primary')
219
+ document.getElementById('pageSupport').style.display = 'block'
220
+ document.getElementById('pageDevices').style.display = 'none'
221
+ homebridge.hideSpinner()
222
+ }
223
+ showSettings = () => {
224
+ homebridge.showSpinner()
225
+ homebridge.enableSaveButton?.()
226
+ document.getElementById('menuHome').classList.remove('btn-elegant')
227
+ document.getElementById('menuHome').classList.add('btn-primary')
228
+ document.getElementById('menuDevices').classList.remove('btn-elegant')
229
+ document.getElementById('menuDevices').classList.add('btn-primary')
230
+ document.getElementById('menuSettings').classList.add('btn-elegant')
231
+ document.getElementById('menuSettings').classList.remove('btn-primary')
232
+ document.getElementById('pageSupport').style.display = 'none'
233
+ document.getElementById('pageDevices').style.display = 'none'
234
+ homebridge.showSchemaForm()
235
+ homebridge.hideSpinner()
236
+ }
237
+ showDisabledBanner = () => {
238
+ document.getElementById('disabledBanner').style.display = 'block'
239
+ }
240
+ enablePlugin = async () => {
241
+ homebridge.showSpinner()
242
+ document.getElementById('disabledBanner').style.display = 'none'
243
+ currentConfig[0].disablePlugin = false
244
+ await homebridge.updatePluginConfig(currentConfig)
245
+ await homebridge.savePluginConfig()
246
+ homebridge.hideSpinner()
247
+ }
248
+ menuHome.addEventListener('click', () => showSupport())
249
+ menuDevices.addEventListener('click', () => showDevices())
250
+ menuSettings.addEventListener('click', () => showSettings())
251
+ disabledEnable.addEventListener('click', () => enablePlugin())
252
+ if (currentConfig.length) {
253
+ document.getElementById('menuWrapper').style.display = 'inline-flex'
254
+ showSettings()
255
+ if (currentConfig[0].disablePlugin) {
256
+ showDisabledBanner()
257
+ }
258
+ } else {
259
+ currentConfig.push({ name: 'Homebridge Matter' })
260
+ await homebridge.updatePluginConfig(currentConfig)
261
+ showIntro()
262
+ }
263
+ } catch (err) {
264
+ homebridge.toast.error(err.message, 'Error')
265
+ } finally {
266
+ homebridge.hideSpinner()
267
+ }
268
+ })()
269
+ </script>
@@ -0,0 +1,47 @@
1
+ import fs from 'node:fs'
2
+
3
+ import { HomebridgePluginUiServer } from '@homebridge/plugin-ui-utils'
4
+
5
+ class PluginUiServer extends HomebridgePluginUiServer {
6
+ constructor() {
7
+ super()
8
+
9
+ /*
10
+ A native method getCachedAccessories() was introduced in config-ui-x v4.37.0
11
+ The following is for users who have a lower version of config-ui-x
12
+ */
13
+ this.onRequest('/getCachedAccessories', async () => {
14
+ try {
15
+ // Define the plugin and create the array to return
16
+ const plugin = '@homebridge-plugins/homebridge-matter'
17
+ const devicesToReturn = []
18
+
19
+ // The path and file of the cached accessories
20
+ const accFile = `${this.homebridgeStoragePath}/accessories/cachedAccessories`
21
+
22
+ // Check the file exists
23
+ if (fs.existsSync(accFile)) {
24
+ // Read the cached accessories file
25
+ let cachedAccessories = await fs.promises.readFile(accFile)
26
+
27
+ // Parse the JSON
28
+ cachedAccessories = JSON.parse(cachedAccessories)
29
+
30
+ // We only want the accessories for this plugin
31
+ cachedAccessories
32
+ .filter(accessory => accessory.plugin === plugin)
33
+ .forEach(accessory => devicesToReturn.push(accessory))
34
+ }
35
+
36
+ // Return the array
37
+ return devicesToReturn
38
+ } catch (err) {
39
+ // Just return an empty accessory list in case of any errors
40
+ return []
41
+ }
42
+ })
43
+ this.ready()
44
+ }
45
+ }
46
+
47
+ (() => new PluginUiServer())()
@@ -1,59 +1,63 @@
1
- import type { API, DynamicPlatformPlugin, Logging, PlatformAccessory, PlatformConfig } from 'homebridge';
1
+ import type { API, DynamicPlatformPlugin, Logging, PlatformConfig } from 'homebridge';
2
2
  /**
3
3
  * MatterPlatform
4
4
  * Demonstrates all available Matter device types in Homebridge
5
+ *
6
+ * Organized by official Matter Specification v1.4.1 categories
5
7
  */
6
8
  export declare class ExampleHomebridgePlatform implements DynamicPlatformPlugin {
7
9
  readonly log: Logging;
8
10
  readonly config: PlatformConfig;
9
11
  readonly api: API;
10
- readonly accessories: Map<string, PlatformAccessory>;
11
12
  readonly matterAccessories: Map<string, any>;
12
13
  constructor(log: Logging, config: PlatformConfig, api: API);
13
14
  /**
14
15
  * Required for DynamicPlatformPlugin
15
16
  * Called when homebridge restores cached accessories from disk at startup
16
17
  */
17
- configureAccessory(accessory: PlatformAccessory): void;
18
+ configureAccessory(): void;
18
19
  /**
19
- * Called for each cached Matter accessory restored from disk
20
- * Track these so we can determine which accessories to remove in didFinishLaunching
20
+ * Called when homebridge restores cached Matter accessories from disk at startup
21
21
  */
22
22
  configureMatterAccessory(accessory: any): void;
23
23
  /**
24
- * Register all Matter accessory examples
24
+ * Register all Matter accessories
25
25
  */
26
26
  private registerMatterAccessories;
27
27
  /**
28
- * Remove disabled accessories from cache
28
+ * Remove accessories that are disabled in config
29
29
  */
30
30
  private removeDisabledAccessories;
31
31
  /**
32
- * Lighting Devices
32
+ * Section 4: Lighting Devices (Matter Spec § 4)
33
33
  */
34
- private registerLightingDevices;
34
+ private registerSection4Lighting;
35
35
  /**
36
- * Switches and Outlets
36
+ * Section 5: Smart Plugs/Actuators (Matter Spec § 5)
37
37
  */
38
- private registerSwitchesAndOutlets;
38
+ private registerSection5SmartPlugs;
39
39
  /**
40
- * Register Matter sensor accessories
40
+ * Section 6: Switches & Controllers (Matter Spec § 6)
41
41
  */
42
- private registerSensors;
42
+ private registerSection6Switches;
43
43
  /**
44
- * Register Matter HVAC accessories (Thermostats, Fans)
44
+ * Section 7: Sensors (Matter Spec § 7)
45
45
  */
46
- private registerHVAC;
46
+ private registerSection7Sensors;
47
47
  /**
48
- * Register Matter Security & Access accessories (Door Locks, Garage Doors)
48
+ * Section 8: Closure Devices (Matter Spec § 8)
49
49
  */
50
- private registerSecurity;
50
+ private registerSection8Closure;
51
51
  /**
52
- * Register Matter Window Covering accessories (Blinds, Shades)
52
+ * Section 9: HVAC (Matter Spec § 9)
53
53
  */
54
- private registerWindowCoverings;
54
+ private registerSection9HVAC;
55
55
  /**
56
- * Register Matter Appliance accessories (Robotic Vacuum Cleaners, etc.)
56
+ * Section 12: Robotic Devices (Matter Spec § 12)
57
+ *
58
+ * ⚠️ IMPORTANT: RVC devices are published as external accessories
59
+ * Apple Home requires RVC devices to be on their own dedicated Matter bridge.
60
+ * Using publishExternalAccessories ensures each RVC device gets its own bridge.
57
61
  */
58
- private registerAppliances;
62
+ private registerSection12Robotic;
59
63
  }