@homebridge-plugins/homebridge-matter 0.0.5 → 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 +17 -0
  2. package/README.md +67 -33
  3. package/config.schema.json +222 -2
  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 +28 -20
  91. package/dist/platform.js +187 -973
  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,318 @@
1
+ /**
2
+ * Robotic Vacuum Cleaner Device (Matter Spec § 12.1)
3
+ *
4
+ * A robotic vacuum cleaner with autonomous cleaning capabilities.
5
+ *
6
+ * ✅ Apple Home Compatibility - EXTERNAL ACCESSORIES
7
+ * This device is published using api.matter.publishExternalAccessories() in platform.ts.
8
+ * RVC devices MUST be on their own dedicated Matter bridge for Apple Home compatibility.
9
+ *
10
+ * IMPORTANT: This function only CREATES the accessory configuration.
11
+ * The actual publishing happens in platform.ts using publishExternalAccessories().
12
+ *
13
+ * What happens when this device is published as external:
14
+ * ─────────────────────────────────────────────────────────────
15
+ * 1. Dedicated Matter Server: Gets its own MatterServer instance
16
+ * 2. Automatic Port Allocation: Receives a unique port (e.g., 5541)
17
+ * 3. Separate Commissioning: Gets its own QR code and manual pairing code
18
+ * 4. Isolation: Completely independent from other Matter accessories
19
+ * 5. Apple Home Compatible: Works properly with Apple Home's RVC requirements
20
+ *
21
+ * When you start Homebridge, you'll see logs like:
22
+ * ```
23
+ * [Matter] Publishing 1 external Matter accessory
24
+ * [Matter] Allocated port 5541 for external Matter accessory: Robot Vacuum
25
+ * [Matter] ✓ External Matter accessory published: Robot Vacuum on port 5541
26
+ * [Matter] 📱 Commissioning codes for Robot Vacuum:
27
+ * [Matter] QR Code: MT:Y.K9042C00KA0648G00
28
+ * [Matter] Manual Code: 3492-8840-7309-5200-911
29
+ * ```
30
+ *
31
+ * Use the separate QR code to commission this device in Apple Home.
32
+ *
33
+ * For developers implementing similar devices:
34
+ * ──────────────────────────────────────────────
35
+ * If you need to create your own device that requires isolation (like cameras,
36
+ * doorbells, or other complex devices that Apple Home requires on separate bridges),
37
+ * follow this pattern:
38
+ *
39
+ * 1. Create the accessory configuration in a device file (like this one)
40
+ * 2. Return it from your registration function
41
+ * 3. In platform.ts, use api.matter.publishExternalAccessories() instead of
42
+ * api.matter.registerPlatformAccessories()
43
+ *
44
+ * Example in your platform.ts:
45
+ * ```typescript
46
+ * const accessories = [...registerYourDevice(context)]
47
+ * if (accessories.length > 0) {
48
+ * // Use publishExternalAccessories for devices that need isolation
49
+ * this.api.matter.publishExternalAccessories(PLUGIN_NAME, accessories)
50
+ * }
51
+ * ```
52
+ */
53
+ /**
54
+ * Registers a Robotic Vacuum Cleaner accessory.
55
+ *
56
+ * NOTE: This returns the accessory configuration but does NOT publish it.
57
+ * Publishing happens in platform.ts using api.matter.publishExternalAccessories().
58
+ *
59
+ * @param context - Device context containing API, logger, and config
60
+ * @returns Array of RVC accessory configurations (empty if disabled)
61
+ */
62
+ export function registerRoboticVacuumCleaner(context) {
63
+ const { api, log, config } = context;
64
+ const accessories = [];
65
+ if (!config.enableRobotVacuum) {
66
+ return accessories;
67
+ }
68
+ // Generate UUID for this accessory - will be used for external bridge identification
69
+ const uuid = api.matter.uuid.generate('matter-robot-vacuum');
70
+ accessories.push({
71
+ // Unique identifier for this accessory
72
+ // This UUID will also be used to identify the external Matter bridge
73
+ uuid,
74
+ // Display name shown in Home apps
75
+ displayName: 'Robot Vacuum',
76
+ // Matter device type - RoboticVacuumCleaner (from Matter Spec § 12.1)
77
+ deviceType: api.matter.deviceTypes.RoboticVacuumCleaner,
78
+ // Device identification
79
+ serialNumber: 'VACUUM-001',
80
+ manufacturer: 'Matter Examples',
81
+ model: 'RobotVacuum v1',
82
+ // Matter clusters define the functionality of this device
83
+ // RVC devices require these three clusters: rvcRunMode, rvcOperationalState, rvcCleanMode
84
+ clusters: {
85
+ // RVC Run Mode Cluster (0x0054) - Defines operational modes
86
+ rvcRunMode: {
87
+ // Supported run modes (0=Idle, 1=Cleaning, 2=Mapping)
88
+ // These are the modes users can select in the Home app
89
+ supportedModes: [
90
+ { label: 'Idle', mode: 0, modeTags: [{ value: 16384 }] }, // 16384 = Idle tag
91
+ { label: 'Cleaning', mode: 1, modeTags: [{ value: 16385 }] }, // 16385 = Cleaning tag
92
+ { label: 'Mapping', mode: 2, modeTags: [{ value: 16386 }] }, // 16386 = Mapping tag
93
+ ],
94
+ // Current mode - initial state
95
+ currentMode: 0, // Start in Idle mode
96
+ },
97
+ // RVC Operational State Cluster (0x0061) - Tracks current activity
98
+ rvcOperationalState: {
99
+ // List of all possible operational states
100
+ // Must include at least an error state (ID 3)
101
+ operationalStateList: [
102
+ { operationalStateId: 0 }, // Stopped
103
+ { operationalStateId: 1 }, // Running
104
+ { operationalStateId: 2 }, // Paused
105
+ { operationalStateId: 3 }, // Error (REQUIRED by Matter spec)
106
+ { operationalStateId: 64 }, // SeekingCharger
107
+ { operationalStateId: 65 }, // Charging
108
+ { operationalStateId: 66 }, // Docked
109
+ ],
110
+ // Current operational state (just the ID number, not an object)
111
+ operationalState: 66, // Start in Docked state
112
+ // Error state - indicates if device has an error
113
+ operationalError: {
114
+ errorStateId: 0, // No error
115
+ },
116
+ },
117
+ // RVC Clean Mode Cluster (0x0055) - Defines cleaning method
118
+ rvcCleanMode: {
119
+ // Supported clean modes (0=Vacuum, 1=Mop, 2=Vacuum+Mop)
120
+ // These are the cleaning methods users can select
121
+ supportedModes: [
122
+ { label: 'Vacuum', mode: 0, modeTags: [] },
123
+ { label: 'Mop', mode: 1, modeTags: [] },
124
+ { label: 'Vacuum & Mop', mode: 2, modeTags: [] },
125
+ ],
126
+ // Current clean mode - initial state
127
+ currentMode: 0, // Start with Vacuum mode
128
+ },
129
+ },
130
+ // Handlers respond to commands from Home apps (Apple Home, Google Home, etc.)
131
+ // These are called when users interact with the device in their Home app
132
+ handlers: {
133
+ // RVC Operational State handlers - control device operation
134
+ rvcOperationalState: {
135
+ /**
136
+ * pause() - Called when user presses "pause" in Home app
137
+ *
138
+ * In a real implementation:
139
+ * - Send pause command to your actual robot vacuum
140
+ * - Wait for confirmation
141
+ * - Then update the Matter state
142
+ */
143
+ pause: async () => {
144
+ log.info('[Robot Vacuum] ✓ Handler `pause` called - Pausing cleaning');
145
+ // TODO: Send pause command to your actual robot vacuum here
146
+ // Example: await yourVacuumAPI.pause()
147
+ // Update Matter state to reflect the change
148
+ // This notifies all connected Home apps of the new state
149
+ await api.matter.updateAccessoryState(uuid, // Use the same UUID we generated above
150
+ 'rvcOperationalState', { operationalState: 2 });
151
+ },
152
+ /**
153
+ * resume() - Called when user presses "resume" or "start" in Home app
154
+ *
155
+ * In a real implementation:
156
+ * - Send start/resume command to your actual robot vacuum
157
+ * - Wait for confirmation
158
+ * - Then update the Matter state
159
+ */
160
+ resume: async () => {
161
+ log.info('[Robot Vacuum] ✓ Handler `resume` called - Resuming cleaning');
162
+ // TODO: Send resume command to your actual robot vacuum here
163
+ // Example: await yourVacuumAPI.resume()
164
+ // Update Matter state to Running
165
+ await api.matter.updateAccessoryState(uuid, 'rvcOperationalState', { operationalState: 1 });
166
+ },
167
+ /**
168
+ * goHome() - Called when user sends robot to charging dock
169
+ *
170
+ * In a real implementation:
171
+ * - Send return-to-dock command to your actual robot vacuum
172
+ * - Wait for confirmation
173
+ * - Then update the Matter state
174
+ */
175
+ goHome: async () => {
176
+ log.info('[Robot Vacuum] ✓ Handler `goHome` called - Returning to dock');
177
+ // TODO: Send return-to-dock command to your actual robot vacuum here
178
+ // Example: await yourVacuumAPI.returnToDock()
179
+ // Update Matter state to SeekingCharger
180
+ await api.matter.updateAccessoryState(uuid, 'rvcOperationalState', { operationalState: 64 });
181
+ // TIP: You could set up a timer or polling to detect when the vacuum
182
+ // actually docks, then update to state 66 (Docked) or 65 (Charging)
183
+ },
184
+ },
185
+ // RVC Run Mode handlers - change operational modes
186
+ rvcRunMode: {
187
+ /**
188
+ * changeToMode() - Called when user changes the run mode
189
+ *
190
+ * Modes: 0=Idle, 1=Cleaning, 2=Mapping
191
+ *
192
+ * In a real implementation:
193
+ * - Send mode change command to your actual robot vacuum
194
+ * - Wait for confirmation
195
+ * - Then update the Matter state
196
+ */
197
+ changeToMode: async (request) => {
198
+ const modes = ['Idle', 'Cleaning', 'Mapping'];
199
+ const modeName = modes[request.newMode] || `Unknown (${request.newMode})`;
200
+ log.info(`[Robot Vacuum] ✓ Handler \`changeToMode\` called: ${request.newMode} (${modeName})`);
201
+ // TODO: Send mode change command to your actual robot vacuum here
202
+ // Example:
203
+ // if (request.newMode === 1) {
204
+ // await yourVacuumAPI.startCleaning()
205
+ // } else if (request.newMode === 2) {
206
+ // await yourVacuumAPI.startMapping()
207
+ // } else {
208
+ // await yourVacuumAPI.idle()
209
+ // }
210
+ // Update Matter state
211
+ await api.matter.updateAccessoryState(uuid, 'rvcRunMode', { currentMode: request.newMode });
212
+ },
213
+ },
214
+ // RVC Clean Mode handlers - change cleaning method
215
+ rvcCleanMode: {
216
+ /**
217
+ * changeToMode() - Called when user changes the clean mode
218
+ *
219
+ * Modes: 0=Vacuum, 1=Mop, 2=Vacuum & Mop
220
+ *
221
+ * In a real implementation:
222
+ * - Send clean mode change command to your actual robot vacuum
223
+ * - Wait for confirmation
224
+ * - Then update the Matter state
225
+ */
226
+ changeToMode: async (request) => {
227
+ const modes = ['Vacuum', 'Mop', 'Vacuum & Mop'];
228
+ const modeName = modes[request.newMode] || `Unknown (${request.newMode})`;
229
+ log.info(`[Robot Vacuum] ✓ Handler \`changeToMode\` (clean mode) called: ${request.newMode} (${modeName})`);
230
+ // TODO: Send clean mode change to your actual robot vacuum here
231
+ // Example:
232
+ // if (request.newMode === 0) {
233
+ // await yourVacuumAPI.setMode('vacuum')
234
+ // } else if (request.newMode === 1) {
235
+ // await yourVacuumAPI.setMode('mop')
236
+ // } else if (request.newMode === 2) {
237
+ // await yourVacuumAPI.setMode('vacuum_and_mop')
238
+ // }
239
+ // Update Matter state
240
+ await api.matter.updateAccessoryState(uuid, 'rvcCleanMode', { currentMode: request.newMode });
241
+ },
242
+ },
243
+ },
244
+ });
245
+ // Log helpful information
246
+ log.info('[Robot Vacuum] Configuration created');
247
+ log.info('[Robot Vacuum] This device will be published on its own external bridge');
248
+ log.info('[Robot Vacuum] Look for separate commissioning codes in the logs when Homebridge starts');
249
+ return accessories;
250
+ }
251
+ // ────────────────────────────────────────────────────────────────────────────
252
+ // DEVELOPER NOTES: Implementing a Real Robot Vacuum Integration
253
+ // ────────────────────────────────────────────────────────────────────────────
254
+ //
255
+ // This example uses static states and logs commands. For a real integration:
256
+ //
257
+ // 1. INITIAL SETUP:
258
+ // - Store the robot vacuum API client in your platform instance
259
+ // - Authenticate with the vacuum's cloud service or local API
260
+ // - Set up any required polling or webhooks to receive state updates
261
+ //
262
+ // 2. STATE UPDATES FROM VACUUM:
263
+ // When your vacuum's state changes (via app, button, schedule, etc.):
264
+ // ```typescript
265
+ // // Listen for state changes from your vacuum
266
+ // vacuumAPI.on('stateChanged', (newState) => {
267
+ // api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
268
+ // operationalState: convertToMatterState(newState)
269
+ // })
270
+ // })
271
+ // ```
272
+ //
273
+ // 3. COMMANDS TO VACUUM:
274
+ // In your handlers, send actual commands to the vacuum:
275
+ // ```typescript
276
+ // pause: async () => {
277
+ // try {
278
+ // await vacuumAPI.pause()
279
+ // log.info('Successfully paused vacuum')
280
+ // await api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
281
+ // operationalState: 2 // Paused
282
+ // })
283
+ // } catch (error) {
284
+ // log.error('Failed to pause vacuum:', error)
285
+ // // Optionally set error state
286
+ // await api.matter.updateAccessoryState(uuid, 'rvcOperationalState', {
287
+ // operationalState: 3, // Error
288
+ // operationalError: { errorStateId: 1 }
289
+ // })
290
+ // }
291
+ // }
292
+ // ```
293
+ //
294
+ // 4. ERROR HANDLING:
295
+ // - Always wrap API calls in try/catch
296
+ // - Update Matter state to reflect errors
297
+ // - Log detailed error information for debugging
298
+ //
299
+ // 5. BATTERY LEVEL (optional):
300
+ // Add a PowerSource cluster to report battery:
301
+ // ```typescript
302
+ // clusters: {
303
+ // powerSource: {
304
+ // status: 1, // BatCharging
305
+ // batChargeLevel: 80, // 0-100%
306
+ // }
307
+ // }
308
+ // ```
309
+ //
310
+ // 6. TESTING:
311
+ // - Test with Apple Home (requires external bridge - done automatically!)
312
+ // - Test with Google Home
313
+ // - Test with Alexa (if supported)
314
+ // - Test all operational states and modes
315
+ // - Test error conditions
316
+ //
317
+ // ────────────────────────────────────────────────────────────────────────────
318
+ //# sourceMappingURL=robotic-vacuum-cleaner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"robotic-vacuum-cleaner.js","sourceRoot":"","sources":["../../../src/devices/section-12-robotic/robotic-vacuum-cleaner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Color Temperature Light Device (Matter Spec § 4.3)
3
+ *
4
+ * A lighting device with color temperature control.
5
+ */
6
+ import type { DeviceContext } from '../types.js';
7
+ export declare function registerColorTemperatureLight(context: DeviceContext): any[];
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Color Temperature Light Device (Matter Spec § 4.3)
3
+ *
4
+ * A lighting device with color temperature control.
5
+ */
6
+ export function registerColorTemperatureLight(context) {
7
+ const { api, log, config } = context;
8
+ const accessories = [];
9
+ if (!config.enableColourTemperatureLight) {
10
+ return accessories;
11
+ }
12
+ accessories.push({
13
+ uuid: api.matter.uuid.generate('matter-colour-temp-light'),
14
+ displayName: 'Colour Temperature Light',
15
+ deviceType: api.matter.deviceTypes.ColorTemperatureLight,
16
+ serialNumber: 'LIGHT-003',
17
+ manufacturer: 'Matter Examples',
18
+ model: 'ColourTempLight v1',
19
+ clusters: {
20
+ onOff: {
21
+ onOff: false,
22
+ },
23
+ levelControl: {
24
+ currentLevel: 127,
25
+ minLevel: 1,
26
+ maxLevel: 254,
27
+ },
28
+ colorControl: {
29
+ colorMode: 2, // Colour temperature mode
30
+ colorTemperatureMireds: 250, // ~4000K
31
+ colorTempPhysicalMinMireds: 147, // 6800K (coolest)
32
+ colorTempPhysicalMaxMireds: 454, // 2200K (warmest)
33
+ coupleColorTempToLevelMinMireds: 147,
34
+ },
35
+ },
36
+ handlers: {
37
+ onOff: {
38
+ on: async () => {
39
+ log.info('[Colour Temp Light] ✓ Handler `on` called (user controlled via Home app)');
40
+ },
41
+ off: async () => {
42
+ log.info('[Colour Temp Light] ✓ Handler `off` called (user controlled via Home app)');
43
+ },
44
+ },
45
+ levelControl: {
46
+ moveToLevelWithOnOff: async (request) => {
47
+ const { level } = request;
48
+ log.info(`[Colour Temp Light] ✓ Handler \`moveToLevel\` called with ${level} (${Math.round(level / 254 * 100)}%)`);
49
+ },
50
+ },
51
+ colorControl: {
52
+ moveToColorTemperatureLogic: async (request) => {
53
+ const { targetMireds, transitionTime } = request;
54
+ const kelvin = Math.round(1000000 / targetMireds);
55
+ log.info(`[Colour Temp Light] ✓ Handler \`moveToColorTemperatureLogic\` called with ${targetMireds} mireds (~${kelvin}K), transition: ${transitionTime}s`);
56
+ },
57
+ },
58
+ },
59
+ });
60
+ return accessories;
61
+ }
62
+ //# sourceMappingURL=color-temperature-light.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color-temperature-light.js","sourceRoot":"","sources":["../../../src/devices/section-4-lighting/color-temperature-light.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,UAAU,6BAA6B,CAAC,OAAsB;IAClE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IACpC,MAAM,WAAW,GAAU,EAAE,CAAA;IAE7B,IAAI,CAAC,MAAM,CAAC,4BAA4B,EAAE,CAAC;QACzC,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,WAAW,CAAC,IAAI,CAAC;QACf,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC;QAC1D,WAAW,EAAE,0BAA0B;QACvC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,qBAAqB;QACxD,YAAY,EAAE,WAAW;QACzB,YAAY,EAAE,iBAAiB;QAC/B,KAAK,EAAE,oBAAoB;QAE3B,QAAQ,EAAE;YACR,KAAK,EAAE;gBACL,KAAK,EAAE,KAAK;aACb;YACD,YAAY,EAAE;gBACZ,YAAY,EAAE,GAAG;gBACjB,QAAQ,EAAE,CAAC;gBACX,QAAQ,EAAE,GAAG;aACd;YACD,YAAY,EAAE;gBACZ,SAAS,EAAE,CAAC,EAAE,0BAA0B;gBACxC,sBAAsB,EAAE,GAAG,EAAE,SAAS;gBACtC,0BAA0B,EAAE,GAAG,EAAE,kBAAkB;gBACnD,0BAA0B,EAAE,GAAG,EAAE,kBAAkB;gBACnD,+BAA+B,EAAE,GAAG;aACrC;SACF;QAED,QAAQ,EAAE;YACR,KAAK,EAAE;gBACL,EAAE,EAAE,KAAK,IAAI,EAAE;oBACb,GAAG,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAA;gBACtF,CAAC;gBACD,GAAG,EAAE,KAAK,IAAI,EAAE;oBACd,GAAG,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAA;gBACvF,CAAC;aACF;YACD,YAAY,EAAE;gBACZ,oBAAoB,EAAE,KAAK,EAAE,OAAmC,EAAE,EAAE;oBAClE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;oBACzB,GAAG,CAAC,IAAI,CAAC,6DAA6D,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAA;gBACpH,CAAC;aACF;YACD,YAAY,EAAE;gBACZ,2BAA2B,EAAE,KAAK,EAAE,OAAyD,EAAE,EAAE;oBAC/F,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,OAAO,CAAA;oBAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,YAAY,CAAC,CAAA;oBACjD,GAAG,CAAC,IAAI,CAAC,6EAA6E,YAAY,aAAa,MAAM,mBAAmB,cAAc,GAAG,CAAC,CAAA;gBAC5J,CAAC;aACF;SACF;KACF,CAAC,CAAA;IAEF,OAAO,WAAW,CAAA;AACpB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Dimmable Light Device (Matter Spec § 4.2)
3
+ *
4
+ * A lighting device with on/off and level control (brightness).
5
+ */
6
+ import type { DeviceContext } from '../types.js';
7
+ export declare function registerDimmableLight(context: DeviceContext): any[];
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Dimmable Light Device (Matter Spec § 4.2)
3
+ *
4
+ * A lighting device with on/off and level control (brightness).
5
+ */
6
+ export function registerDimmableLight(context) {
7
+ const { api, log, config } = context;
8
+ const accessories = [];
9
+ if (!config.enableDimmableLight) {
10
+ return accessories;
11
+ }
12
+ accessories.push({
13
+ uuid: api.matter.uuid.generate('matter-dimmable-light'),
14
+ displayName: 'Dimmable Light',
15
+ deviceType: api.matter.deviceTypes.DimmableLight,
16
+ serialNumber: 'LIGHT-002',
17
+ manufacturer: 'Matter Examples',
18
+ model: 'DimmableLight v1',
19
+ clusters: {
20
+ onOff: {
21
+ onOff: false,
22
+ },
23
+ levelControl: {
24
+ currentLevel: 127,
25
+ minLevel: 1,
26
+ maxLevel: 254,
27
+ },
28
+ },
29
+ handlers: {
30
+ onOff: {
31
+ on: async () => {
32
+ log.info('[Dimmable Light] ✓ Handler `on` called (user controlled via Home app)');
33
+ },
34
+ off: async () => {
35
+ log.info('[Dimmable Light] ✓ Handler `off` called (user controlled via Home app)');
36
+ },
37
+ },
38
+ levelControl: {
39
+ moveToLevelWithOnOff: async (request) => {
40
+ const { level } = request;
41
+ log.info(`[Dimmable Light] ✓ Handler \`moveToLevel\` called with ${level} (${Math.round(level / 254 * 100)}%)`);
42
+ },
43
+ },
44
+ },
45
+ });
46
+ return accessories;
47
+ }
48
+ //# sourceMappingURL=dimmable-light.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dimmable-light.js","sourceRoot":"","sources":["../../../src/devices/section-4-lighting/dimmable-light.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,UAAU,qBAAqB,CAAC,OAAsB;IAC1D,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IACpC,MAAM,WAAW,GAAU,EAAE,CAAA;IAE7B,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAChC,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,WAAW,CAAC,IAAI,CAAC;QACf,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QACvD,WAAW,EAAE,gBAAgB;QAC7B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,aAAa;QAChD,YAAY,EAAE,WAAW;QACzB,YAAY,EAAE,iBAAiB;QAC/B,KAAK,EAAE,kBAAkB;QAEzB,QAAQ,EAAE;YACR,KAAK,EAAE;gBACL,KAAK,EAAE,KAAK;aACb;YACD,YAAY,EAAE;gBACZ,YAAY,EAAE,GAAG;gBACjB,QAAQ,EAAE,CAAC;gBACX,QAAQ,EAAE,GAAG;aACd;SACF;QAED,QAAQ,EAAE;YACR,KAAK,EAAE;gBACL,EAAE,EAAE,KAAK,IAAI,EAAE;oBACb,GAAG,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAA;gBACnF,CAAC;gBACD,GAAG,EAAE,KAAK,IAAI,EAAE;oBACd,GAAG,CAAC,IAAI,CAAC,wEAAwE,CAAC,CAAA;gBACpF,CAAC;aACF;YACD,YAAY,EAAE;gBACZ,oBAAoB,EAAE,KAAK,EAAE,OAAmC,EAAE,EAAE;oBAClE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;oBACzB,GAAG,CAAC,IAAI,CAAC,0DAA0D,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAA;gBACjH,CAAC;aACF;SACF;KACF,CAAC,CAAA;IAEF,OAAO,WAAW,CAAA;AACpB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Extended Color Light Device (Matter Spec § 4.4)
3
+ *
4
+ * Handles both variants:
5
+ * - Color Light (HS): Hue/Saturation only
6
+ * - Extended Color Light (HS+CCT): Hue/Saturation + Color Temperature
7
+ *
8
+ * Both use the same Matter device type (ExtendedColorLight) but with different
9
+ * cluster configurations.
10
+ */
11
+ import type { DeviceContext } from '../types.js';
12
+ export declare function registerExtendedColorLight(context: DeviceContext): any[];
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Extended Color Light Device (Matter Spec § 4.4)
3
+ *
4
+ * Handles both variants:
5
+ * - Color Light (HS): Hue/Saturation only
6
+ * - Extended Color Light (HS+CCT): Hue/Saturation + Color Temperature
7
+ *
8
+ * Both use the same Matter device type (ExtendedColorLight) but with different
9
+ * cluster configurations.
10
+ */
11
+ export function registerExtendedColorLight(context) {
12
+ const { api, log, config } = context;
13
+ const accessories = [];
14
+ // Variant 1: Color Light (HS only - no CCT)
15
+ if (config.enableColourLight) {
16
+ accessories.push({
17
+ uuid: api.matter.uuid.generate('matter-colour-light'),
18
+ displayName: 'Colour Light (HS)',
19
+ deviceType: api.matter.deviceTypes.ExtendedColorLight,
20
+ serialNumber: 'LIGHT-004',
21
+ manufacturer: 'Matter Examples',
22
+ model: 'ColorLight v1',
23
+ clusters: {
24
+ onOff: {
25
+ onOff: false,
26
+ },
27
+ levelControl: {
28
+ currentLevel: 127,
29
+ minLevel: 1,
30
+ maxLevel: 254,
31
+ },
32
+ colorControl: {
33
+ colorMode: 0, // Hue/Saturation mode
34
+ currentHue: 0, // Red (0 degrees)
35
+ currentSaturation: 254, // Full saturation
36
+ currentX: 41942, // Also provide XY for compatibility
37
+ currentY: 21626,
38
+ },
39
+ },
40
+ handlers: {
41
+ onOff: {
42
+ on: async () => {
43
+ log.info('[Colour Light HS] ✓ Handler `on` called (user controlled via Home app)');
44
+ },
45
+ off: async () => {
46
+ log.info('[Colour Light HS] ✓ Handler `off` called (user controlled via Home app)');
47
+ },
48
+ },
49
+ levelControl: {
50
+ moveToLevelWithOnOff: async (request) => {
51
+ const { level } = request;
52
+ log.info(`[Colour Light HS] ✓ Handler \`moveToLevel\` called with ${level} (${Math.round(level / 254 * 100)}%)`);
53
+ },
54
+ },
55
+ colorControl: {
56
+ moveToColorLogic: async (request) => {
57
+ const { targetX, targetY, transitionTime } = request;
58
+ const xFloat = (targetX / 65535).toFixed(4);
59
+ const yFloat = (targetY / 65535).toFixed(4);
60
+ log.info(`[Colour Light HS] ✓ Handler \`moveToColorLogic\` called with x=${targetX} (~${xFloat}), y=${targetY} (~${yFloat}), transition: ${transitionTime}s`);
61
+ },
62
+ moveToHueAndSaturationLogic: async (request) => {
63
+ const { targetHue, targetSaturation, transitionTime } = request;
64
+ const hueDegrees = Math.round((targetHue / 254) * 360);
65
+ const saturationPercent = Math.round((targetSaturation / 254) * 100);
66
+ log.info(`[Colour Light HS] ✓ Handler \`moveToHueAndSaturationLogic\` called with hue=${targetHue} (~${hueDegrees}°), saturation=${targetSaturation} (~${saturationPercent}%), transition: ${transitionTime}s`);
67
+ },
68
+ // NOTE: No moveToColorTemperatureLogic handler - this variant only supports color, not CCT
69
+ },
70
+ },
71
+ });
72
+ }
73
+ // Variant 2: Extended Color Light (HS + CCT)
74
+ if (config.enableExtendedColourLight) {
75
+ accessories.push({
76
+ uuid: api.matter.uuid.generate('matter-extended-colour-light'),
77
+ displayName: 'Extended Colour Light (HS+CCT)',
78
+ deviceType: api.matter.deviceTypes.ExtendedColorLight,
79
+ serialNumber: 'LIGHT-005',
80
+ manufacturer: 'Matter Examples',
81
+ model: 'ExtendedColorLight v1',
82
+ clusters: {
83
+ onOff: {
84
+ onOff: false,
85
+ },
86
+ levelControl: {
87
+ currentLevel: 127,
88
+ minLevel: 1,
89
+ maxLevel: 254,
90
+ },
91
+ colorControl: {
92
+ colorMode: 0, // Hue/Saturation mode
93
+ currentHue: 0, // Red (0 degrees)
94
+ currentSaturation: 254, // Full saturation
95
+ currentX: 41942, // Also provide XY for compatibility
96
+ currentY: 21626,
97
+ colorTemperatureMireds: 250, // ~4000K (for CCT mode)
98
+ colorTempPhysicalMinMireds: 147, // 6800K (coolest)
99
+ colorTempPhysicalMaxMireds: 454, // 2200K (warmest)
100
+ coupleColorTempToLevelMinMireds: 147,
101
+ },
102
+ },
103
+ handlers: {
104
+ onOff: {
105
+ on: async () => {
106
+ log.info('[Extended Colour Light] ✓ Handler `on` called (user controlled via Home app)');
107
+ },
108
+ off: async () => {
109
+ log.info('[Extended Colour Light] ✓ Handler `off` called (user controlled via Home app)');
110
+ },
111
+ },
112
+ levelControl: {
113
+ moveToLevelWithOnOff: async (request) => {
114
+ const { level } = request;
115
+ log.info(`[Extended Colour Light] ✓ Handler \`moveToLevel\` called with ${level} (${Math.round(level / 254 * 100)}%)`);
116
+ },
117
+ },
118
+ colorControl: {
119
+ moveToColorLogic: async (request) => {
120
+ const { targetX, targetY, transitionTime } = request;
121
+ const xFloat = (targetX / 65535).toFixed(4);
122
+ const yFloat = (targetY / 65535).toFixed(4);
123
+ log.info(`[Extended Colour Light] ✓ Handler \`moveToColorLogic\` called with x=${targetX} (~${xFloat}), y=${targetY} (~${yFloat}), transition: ${transitionTime}s`);
124
+ },
125
+ moveToHueAndSaturationLogic: async (request) => {
126
+ const { targetHue, targetSaturation, transitionTime } = request;
127
+ const hueDegrees = Math.round((targetHue / 254) * 360);
128
+ const saturationPercent = Math.round((targetSaturation / 254) * 100);
129
+ log.info(`[Extended Colour Light] ✓ Handler \`moveToHueAndSaturationLogic\` called with hue=${targetHue} (~${hueDegrees}°), saturation=${targetSaturation} (~${saturationPercent}%), transition: ${transitionTime}s`);
130
+ },
131
+ moveToColorTemperatureLogic: async (request) => {
132
+ const { targetMireds, transitionTime } = request;
133
+ const kelvin = Math.round(1000000 / targetMireds);
134
+ log.info(`[Extended Colour Light] ✓ Handler \`moveToColorTemperatureLogic\` called with ${targetMireds} mireds (~${kelvin}K), transition: ${transitionTime}s`);
135
+ },
136
+ },
137
+ },
138
+ });
139
+ }
140
+ return accessories;
141
+ }
142
+ //# sourceMappingURL=extended-color-light.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extended-color-light.js","sourceRoot":"","sources":["../../../src/devices/section-4-lighting/extended-color-light.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Section 4: Lighting Devices
3
+ *
4
+ * Matter Specification § 4 - Fundamental lighting device types
5
+ */
6
+ export { registerColorTemperatureLight } from './color-temperature-light.js';
7
+ export { registerDimmableLight } from './dimmable-light.js';
8
+ export { registerExtendedColorLight } from './extended-color-light.js';
9
+ export { registerOnOffLight } from './on-off-light.js';