@homebridge-plugins/homebridge-matter 0.1.3 → 0.1.4

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 (61) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/MATTER_API.md +1189 -182
  3. package/README.md +1 -1
  4. package/dist/devices/section-12-robotic/robotic-vacuum-cleaner.d.ts +9 -53
  5. package/dist/devices/section-12-robotic/robotic-vacuum-cleaner.js +12 -62
  6. package/dist/devices/section-12-robotic/robotic-vacuum-cleaner.js.map +1 -1
  7. package/dist/devices/section-4-lighting/color-temperature-light.d.ts +8 -1
  8. package/dist/devices/section-4-lighting/color-temperature-light.js +27 -23
  9. package/dist/devices/section-4-lighting/color-temperature-light.js.map +1 -1
  10. package/dist/devices/section-4-lighting/dimmable-light.d.ts +5 -22
  11. package/dist/devices/section-4-lighting/dimmable-light.js +40 -319
  12. package/dist/devices/section-4-lighting/dimmable-light.js.map +1 -1
  13. package/dist/devices/section-4-lighting/extended-color-light.d.ts +6 -25
  14. package/dist/devices/section-4-lighting/extended-color-light.js +33 -399
  15. package/dist/devices/section-4-lighting/extended-color-light.js.map +1 -1
  16. package/dist/devices/section-4-lighting/on-off-light.d.ts +8 -28
  17. package/dist/devices/section-4-lighting/on-off-light.js +64 -434
  18. package/dist/devices/section-4-lighting/on-off-light.js.map +1 -1
  19. package/dist/devices/section-5-smart-plugs/dimmable-plug-in-unit.d.ts +6 -0
  20. package/dist/devices/section-5-smart-plugs/dimmable-plug-in-unit.js +13 -3
  21. package/dist/devices/section-5-smart-plugs/dimmable-plug-in-unit.js.map +1 -1
  22. package/dist/devices/section-5-smart-plugs/on-off-plug-in-unit.d.ts +5 -0
  23. package/dist/devices/section-5-smart-plugs/on-off-plug-in-unit.js +9 -2
  24. package/dist/devices/section-5-smart-plugs/on-off-plug-in-unit.js.map +1 -1
  25. package/dist/devices/section-6-switches/on-off-light-switch.d.ts +5 -0
  26. package/dist/devices/section-6-switches/on-off-light-switch.js +19 -5
  27. package/dist/devices/section-6-switches/on-off-light-switch.js.map +1 -1
  28. package/dist/devices/section-7-sensors/contact-sensor.d.ts +5 -0
  29. package/dist/devices/section-7-sensors/contact-sensor.js +5 -0
  30. package/dist/devices/section-7-sensors/contact-sensor.js.map +1 -1
  31. package/dist/devices/section-7-sensors/humidity-sensor.d.ts +5 -0
  32. package/dist/devices/section-7-sensors/humidity-sensor.js +5 -0
  33. package/dist/devices/section-7-sensors/humidity-sensor.js.map +1 -1
  34. package/dist/devices/section-7-sensors/light-sensor.d.ts +5 -0
  35. package/dist/devices/section-7-sensors/light-sensor.js +5 -0
  36. package/dist/devices/section-7-sensors/light-sensor.js.map +1 -1
  37. package/dist/devices/section-7-sensors/occupancy-sensor.d.ts +6 -0
  38. package/dist/devices/section-7-sensors/occupancy-sensor.js +6 -0
  39. package/dist/devices/section-7-sensors/occupancy-sensor.js.map +1 -1
  40. package/dist/devices/section-7-sensors/smoke-co-alarm.d.ts +6 -0
  41. package/dist/devices/section-7-sensors/smoke-co-alarm.js +6 -0
  42. package/dist/devices/section-7-sensors/smoke-co-alarm.js.map +1 -1
  43. package/dist/devices/section-7-sensors/temperature-sensor.d.ts +5 -0
  44. package/dist/devices/section-7-sensors/temperature-sensor.js +5 -0
  45. package/dist/devices/section-7-sensors/temperature-sensor.js.map +1 -1
  46. package/dist/devices/section-7-sensors/water-leak-detector.d.ts +5 -0
  47. package/dist/devices/section-7-sensors/water-leak-detector.js +5 -0
  48. package/dist/devices/section-7-sensors/water-leak-detector.js.map +1 -1
  49. package/dist/devices/section-8-closure/door-lock.d.ts +6 -0
  50. package/dist/devices/section-8-closure/door-lock.js +12 -27
  51. package/dist/devices/section-8-closure/door-lock.js.map +1 -1
  52. package/dist/devices/section-8-closure/window-covering.d.ts +7 -0
  53. package/dist/devices/section-8-closure/window-covering.js +27 -43
  54. package/dist/devices/section-8-closure/window-covering.js.map +1 -1
  55. package/dist/devices/section-9-hvac/fan.d.ts +7 -0
  56. package/dist/devices/section-9-hvac/fan.js +17 -23
  57. package/dist/devices/section-9-hvac/fan.js.map +1 -1
  58. package/dist/devices/section-9-hvac/thermostat.d.ts +7 -0
  59. package/dist/devices/section-9-hvac/thermostat.js +21 -25
  60. package/dist/devices/section-9-hvac/thermostat.js.map +1 -1
  61. package/package.json +3 -3
@@ -5,32 +5,13 @@
5
5
  * - Color Light (HS): Hue/Saturation only
6
6
  * - Extended Color Light (HS+CCT): Hue/Saturation + Color Temperature
7
7
  *
8
- * Both use the same Matter device type (ExtendedColorLight) but with different
9
- * cluster configurations.
8
+ * For comprehensive documentation, see: ../../../MATTER_API.md
10
9
  *
11
- * ═══════════════════════════════════════════════════════════════════════════════
12
- * ARCHITECTURE: THE TWO-WAY FLOW (applies to all Matter accessories)
13
- * ═══════════════════════════════════════════════════════════════════════════════
14
- *
15
- * FLOW A: Home App Physical Device (AUTOMATIC - via handlers)
16
- * ────────────────────────────────────────────────────────────────
17
- * 1. User controls via Home App
18
- * 2. Matter command → Homebridge → Your handler runs
19
- * 3. You control your physical device (API, MQTT, etc.)
20
- * 4. Homebridge AUTOMATICALLY updates Matter state
21
- * 5. All controllers are notified
22
- * ✅ No manual state update needed!
23
- *
24
- * FLOW B: Physical Device → Home App (MANUAL - you must update state)
25
- * ────────────────────────────────────────────────────────────────
26
- * 1. Physical device changes (button, cloud app, automation)
27
- * 2. ❌ Homebridge has NO IDEA this happened!
28
- * 3. You MUST monitor device and detect changes
29
- * 4. You MUST call api.matter.updateAccessoryState() for changed clusters
30
- * 5. Then all controllers are notified
31
- *
32
- * This demonstrates the MOST COMPLEX case with multiple color modes and clusters.
33
- * ═══════════════════════════════════════════════════════════════════════════════
10
+ * This example demonstrates:
11
+ * - Multiple color modes (HS, XY, Color Temperature)
12
+ * - Color value conversions (hue/saturation, mireds/Kelvin, XY)
13
+ * - Type-safe handlers with MatterRequests
14
+ * - Most complex lighting scenario with mode switching
34
15
  */
35
16
  export function registerExtendedColorLight(context) {
36
17
  const { api, log, config } = context;
@@ -64,16 +45,20 @@ export function registerExtendedColorLight(context) {
64
45
  handlers: {
65
46
  onOff: {
66
47
  on: async () => {
67
- log.info('[Colour Light HS] Handler `on` called (user controlled via Home app)');
48
+ log.info('[Colour Light HS] Turning ON');
49
+ // TODO: await myLightAPI.turnOn()
68
50
  },
69
51
  off: async () => {
70
- log.info('[Colour Light HS] Handler `off` called (user controlled via Home app)');
52
+ log.info('[Colour Light HS] Turning OFF');
53
+ // TODO: await myLightAPI.turnOff()
71
54
  },
72
55
  },
73
56
  levelControl: {
74
57
  moveToLevelWithOnOff: async (request) => {
75
58
  const { level } = request;
76
- log.info(`[Colour Light HS] ✓ Handler \`moveToLevel\` called with ${level} (${Math.round(level / 254 * 100)}%)`);
59
+ const brightnessPercent = Math.round((level / 254) * 100);
60
+ log.info(`[Colour Light HS] Setting brightness to ${brightnessPercent}%`);
61
+ // TODO: await myLightAPI.setBrightness(brightnessPercent)
77
62
  },
78
63
  },
79
64
  colorControl: {
@@ -81,29 +66,23 @@ export function registerExtendedColorLight(context) {
81
66
  const { targetX, targetY, transitionTime } = request;
82
67
  const xFloat = (targetX / 65535).toFixed(4);
83
68
  const yFloat = (targetY / 65535).toFixed(4);
84
- log.info(`[Colour Light HS] Handler \`moveToColorLogic\` called with x=${targetX} (~${xFloat}), y=${targetY} (~${yFloat}), transition: ${transitionTime}s`);
69
+ log.info(`[Colour Light HS] Setting XY color to (${xFloat}, ${yFloat})`);
70
+ // TODO: await myLightAPI.setXY(xFloat, yFloat, transitionTime)
85
71
  },
86
72
  moveToHueAndSaturationLogic: async (request) => {
87
73
  const { targetHue, targetSaturation, transitionTime } = request;
88
74
  const hueDegrees = Math.round((targetHue / 254) * 360);
89
75
  const saturationPercent = Math.round((targetSaturation / 254) * 100);
90
- log.info(`[Colour Light HS] Handler \`moveToHueAndSaturationLogic\` called with hue=${targetHue} (~${hueDegrees}°), saturation=${targetSaturation} (~${saturationPercent}%), transition: ${transitionTime}s`);
76
+ log.info(`[Colour Light HS] Setting color to ${hueDegrees}°, ${saturationPercent}%`);
77
+ // TODO: await myLightAPI.setColor(hueDegrees, saturationPercent, transitionTime)
91
78
  },
92
- // NOTE: No moveToColorTemperatureLogic handler - this variant only supports color, not CCT
79
+ // NOTE: No moveToColorTemperatureLogic - this variant only supports color, not CCT
93
80
  },
94
81
  },
95
82
  });
96
83
  }
97
- // ═══════════════════════════════════════════════════════════════════════════
98
- // Variant 2: Extended Color Light (HS + CCT) - THE FULL EXAMPLE
99
- // ═══════════════════════════════════════════════════════════════════════════
100
- //
101
- // This variant supports BOTH color modes:
102
- // - Color mode (Hue/Saturation or XY)
103
- // - White mode (Color Temperature in Mireds/Kelvin)
104
- //
105
- // HomeKit switches between these modes automatically based on user selection
106
- // in the Home app.
84
+ // Variant 2: Extended Color Light (HS + CCT)
85
+ // Supports both color (Hue/Saturation or XY) and white (Color Temperature) modes
107
86
  if (config.enableExtendedColourLight) {
108
87
  const accessory = {
109
88
  uuid: api.matter.uuid.generate('matter-extended-colour-light'),
@@ -136,16 +115,20 @@ export function registerExtendedColorLight(context) {
136
115
  handlers: {
137
116
  onOff: {
138
117
  on: async () => {
139
- log.info('[Extended Colour Light] Handler `on` called (user controlled via Home app)');
118
+ log.info('[Extended Colour Light] Turning ON');
119
+ // TODO: await myLightAPI.turnOn()
140
120
  },
141
121
  off: async () => {
142
- log.info('[Extended Colour Light] Handler `off` called (user controlled via Home app)');
122
+ log.info('[Extended Colour Light] Turning OFF');
123
+ // TODO: await myLightAPI.turnOff()
143
124
  },
144
125
  },
145
126
  levelControl: {
146
127
  moveToLevelWithOnOff: async (request) => {
147
128
  const { level } = request;
148
- log.info(`[Extended Colour Light] ✓ Handler \`moveToLevel\` called with ${level} (${Math.round(level / 254 * 100)}%)`);
129
+ const brightnessPercent = Math.round((level / 254) * 100);
130
+ log.info(`[Extended Colour Light] Setting brightness to ${brightnessPercent}%`);
131
+ // TODO: await myLightAPI.setBrightness(brightnessPercent)
149
132
  },
150
133
  },
151
134
  colorControl: {
@@ -153,375 +136,26 @@ export function registerExtendedColorLight(context) {
153
136
  const { targetX, targetY, transitionTime } = request;
154
137
  const xFloat = (targetX / 65535).toFixed(4);
155
138
  const yFloat = (targetY / 65535).toFixed(4);
156
- log.info(`[Extended Colour Light] Handler \`moveToColorLogic\` called with x=${targetX} (~${xFloat}), y=${targetY} (~${yFloat}), transition: ${transitionTime}s`);
139
+ log.info(`[Extended Colour Light] Setting XY color to (${xFloat}, ${yFloat})`);
140
+ // TODO: await myLightAPI.setXY(xFloat, yFloat, transitionTime)
157
141
  },
158
142
  moveToHueAndSaturationLogic: async (request) => {
159
143
  const { targetHue, targetSaturation, transitionTime } = request;
160
144
  const hueDegrees = Math.round((targetHue / 254) * 360);
161
145
  const saturationPercent = Math.round((targetSaturation / 254) * 100);
162
- log.info(`[Extended Colour Light] Handler \`moveToHueAndSaturationLogic\` called with hue=${targetHue} (~${hueDegrees}°), saturation=${targetSaturation} (~${saturationPercent}%), transition: ${transitionTime}s`);
146
+ log.info(`[Extended Colour Light] Setting color to ${hueDegrees}°, ${saturationPercent}%`);
147
+ // TODO: await myLightAPI.setColor(hueDegrees, saturationPercent, transitionTime)
163
148
  },
164
149
  moveToColorTemperatureLogic: async (request) => {
165
150
  const { targetMireds, transitionTime } = request;
166
151
  const kelvin = Math.round(1000000 / targetMireds);
167
- log.info(`[Extended Colour Light] Handler \`moveToColorTemperatureLogic\` called with ${targetMireds} mireds (~${kelvin}K), transition: ${transitionTime}s`);
152
+ log.info(`[Extended Colour Light] Setting color temp to ${kelvin}K`);
153
+ // TODO: await myLightAPI.setColorTemperature(kelvin, transitionTime)
168
154
  },
169
155
  },
170
156
  },
171
157
  };
172
158
  accessories.push(accessory);
173
- // ═════════════════════════════════════════════════════════════════════════════
174
- // READING STATE: Understanding Extended Color Light State
175
- // ═════════════════════════════════════════════════════════════════════════════
176
- //
177
- // An Extended Color Light has MULTIPLE properties across THREE clusters:
178
- //
179
- // 1. onOff cluster (power state):
180
- // - onOff: boolean (true = on, false = off)
181
- //
182
- // 2. levelControl cluster (brightness):
183
- // - currentLevel: number (1-254, where 254 = 100%)
184
- //
185
- // 3. colorControl cluster (color/white):
186
- // - colorMode: number (0 = HS, 1 = XY, 2 = ColorTemp)
187
- // - currentHue: number (0-254, maps to 0-360 degrees)
188
- // - currentSaturation: number (0-254, maps to 0-100%)
189
- // - currentX: number (0-65535, CIE 1931 x coordinate)
190
- // - currentY: number (0-65535, CIE 1931 y coordinate)
191
- // - colorTemperatureMireds: number (147-454, reciprocal megakelvin)
192
- //
193
- // Example: Reading all properties at once
194
- const readAllStateExample = () => {
195
- // Power state
196
- const isOn = accessory.clusters.onOff.onOff;
197
- // Brightness
198
- const level = accessory.clusters.levelControl.currentLevel;
199
- const brightnessPercent = Math.round((level / 254) * 100);
200
- // Color mode
201
- const mode = accessory.clusters.colorControl.colorMode;
202
- const modeNames = {
203
- [api.matter.types.ColorControl.ColorMode.CurrentHueAndCurrentSaturation]: 'Hue/Saturation',
204
- [api.matter.types.ColorControl.ColorMode.CurrentXAndCurrentY]: 'XY',
205
- [api.matter.types.ColorControl.ColorMode.ColorTemperatureMireds]: 'Color Temperature',
206
- };
207
- const modeName = modeNames[mode] || 'Unknown';
208
- // Color values (HS)
209
- const hue = accessory.clusters.colorControl.currentHue;
210
- const saturation = accessory.clusters.colorControl.currentSaturation;
211
- const hueDegrees = Math.round((hue / 254) * 360);
212
- const saturationPercent = Math.round((saturation / 254) * 100);
213
- // Color values (XY)
214
- const x = accessory.clusters.colorControl.currentX;
215
- const y = accessory.clusters.colorControl.currentY;
216
- const xFloat = (x / 65535).toFixed(4);
217
- const yFloat = (y / 65535).toFixed(4);
218
- // White values (Color Temperature)
219
- const mireds = accessory.clusters.colorControl.colorTemperatureMireds;
220
- const kelvin = Math.round(1000000 / mireds);
221
- log.info('[Extended Color Light] Complete State:');
222
- log.info(` Power: ${isOn ? 'ON' : 'OFF'}`);
223
- log.info(` Brightness: ${brightnessPercent}%`);
224
- log.info(` Color Mode: ${modeName}`);
225
- log.info(` Hue: ${hueDegrees}° (${hue})`);
226
- log.info(` Saturation: ${saturationPercent}% (${saturation})`);
227
- log.info(` X/Y: ${xFloat}, ${yFloat}`);
228
- log.info(` Color Temp: ${kelvin}K (${mireds} mireds)`);
229
- };
230
- // Uncomment to log complete state:
231
- // readAllStateExample()
232
- // ═════════════════════════════════════════════════════════════════════════════
233
- // EXTERNAL UPDATES: Updating Extended Color Light State
234
- // ═════════════════════════════════════════════════════════════════════════════
235
- //
236
- // With color lights, you need to handle different scenarios:
237
- // 1. User changes power (on/off)
238
- // 2. User changes brightness
239
- // 3. User changes color (hue/saturation)
240
- // 4. User changes to white mode (color temperature)
241
- // 5. Any combination of the above!
242
- //
243
- // The key challenge: Your device API might use different formats than Matter
244
- /**
245
- * Example: Comprehensive polling for Extended Color Light
246
- */
247
- const startPollingExample = () => {
248
- setInterval(async () => {
249
- try {
250
- // ──────────────────────────────────────────────────────────────────────
251
- // STEP 1: Fetch state from your device
252
- // ──────────────────────────────────────────────────────────────────────
253
- // TODO: Replace with your actual device API
254
- // const state = await myLightAPI.getState(accessory.context.deviceId)
255
- //
256
- // Your device might return data like:
257
- // {
258
- // "power": "on",
259
- // "brightness": 75, // 0-100%
260
- // "mode": "color", // "color" or "white"
261
- // "hue": 180, // 0-360 degrees
262
- // "saturation": 100, // 0-100%
263
- // "colorTemp": 4000 // Kelvin
264
- // }
265
- // For this example, simulate device state:
266
- // const deviceState = {
267
- // power: 'on',
268
- // brightness: 75,
269
- // mode: 'color',
270
- // hue: 180,
271
- // saturation: 100,
272
- // colorTemp: 4000,
273
- // }
274
- // ──────────────────────────────────────────────────────────────────────
275
- // STEP 2: Read current HomeKit state
276
- // ──────────────────────────────────────────────────────────────────────
277
- const homekitIsOn = accessory.clusters.onOff.onOff;
278
- const homekitLevel = accessory.clusters.levelControl.currentLevel;
279
- const homekitBrightnessPercent = Math.round((homekitLevel / 254) * 100);
280
- const homekitColorMode = accessory.clusters.colorControl.colorMode;
281
- const homekitHue = accessory.clusters.colorControl.currentHue;
282
- const homekitSaturation = accessory.clusters.colorControl.currentSaturation;
283
- const homekitMireds = accessory.clusters.colorControl.colorTemperatureMireds;
284
- // ──────────────────────────────────────────────────────────────────────
285
- // STEP 3: Compare and update as needed
286
- // ──────────────────────────────────────────────────────────────────────
287
- // Power changed?
288
- // const deviceIsOn = deviceState.power === 'on'
289
- // if (deviceIsOn !== homekitIsOn) {
290
- // log.info(`[Extended Color Light] Power changed: ${deviceIsOn ? 'ON' : 'OFF'}`)
291
- // accessory.clusters.onOff.onOff = deviceIsOn
292
- // await api.matter.updateAccessoryState(accessory.uuid, api.matter.clusterNames.OnOff, { onOff: deviceIsOn })
293
- // }
294
- // Brightness changed?
295
- // if (deviceState.brightness !== homekitBrightnessPercent) {
296
- // log.info(`[Extended Color Light] Brightness changed: ${deviceState.brightness}%`)
297
- // const newLevel = Math.max(1, Math.round((deviceState.brightness / 100) * 254))
298
- // accessory.clusters.levelControl.currentLevel = newLevel
299
- // await api.matter.updateAccessoryState(accessory.uuid, api.matter.clusterNames.LevelControl, { currentLevel: newLevel })
300
- // }
301
- // Color mode or values changed?
302
- // if (deviceState.mode === 'color') {
303
- // // ────────────────────────────────────────────────────────────────
304
- // // SCENARIO A: Device is in COLOR mode
305
- // // ────────────────────────────────────────────────────────────────
306
- //
307
- // // Convert device hue (0-360) to Matter hue (0-254)
308
- // const newHue = Math.round((deviceState.hue / 360) * 254)
309
- //
310
- // // Convert device saturation (0-100) to Matter saturation (0-254)
311
- // const newSaturation = Math.round((deviceState.saturation / 100) * 254)
312
- //
313
- // // Check if color actually changed
314
- // const hueChanged = newHue !== homekitHue
315
- // const saturationChanged = newSaturation !== homekitSaturation
316
- // const modeChanged = homekitColorMode !== 0 // Not in HS mode
317
- //
318
- // if (hueChanged || saturationChanged || modeChanged) {
319
- // log.info(`[Extended Color Light] Color changed: H=${deviceState.hue}° S=${deviceState.saturation}%`)
320
- //
321
- // // IMPORTANT: When updating color, you should update MULTIPLE properties
322
- // // to keep HS and XY in sync (HomeKit can use either)
323
- //
324
- // // Update colorMode to indicate we're using Hue/Saturation
325
- // accessory.clusters.colorControl.colorMode = api.matter.types.ColorControl.ColorMode.CurrentHueAndCurrentSaturation
326
- //
327
- // // Update hue and saturation
328
- // accessory.clusters.colorControl.currentHue = newHue
329
- // accessory.clusters.colorControl.currentSaturation = newSaturation
330
- //
331
- // // Optional but recommended: Calculate and update XY values too
332
- // // This ensures compatibility with controllers that prefer XY
333
- // // You can use a color conversion library for this, or approximate:
334
- // // const { x, y } = hueAndSaturationToXY(deviceState.hue, deviceState.saturation)
335
- // // accessory.clusters.colorControl.currentX = Math.round(x * 65535)
336
- // // accessory.clusters.colorControl.currentY = Math.round(y * 65535)
337
- //
338
- // // Notify HomeKit of all color control changes at once
339
- // await api.matter.updateAccessoryState(accessory.uuid, api.matter.clusterNames.ColorControl, {
340
- // colorMode: api.matter.types.ColorControl.ColorMode.CurrentHueAndCurrentSaturation,
341
- // currentHue: newHue,
342
- // currentSaturation: newSaturation,
343
- // // currentX: Math.round(x * 65535),
344
- // // currentY: Math.round(y * 65535),
345
- // })
346
- //
347
- // log.info(`[Extended Color Light] ✓ Updated to color mode: H=${deviceState.hue}° S=${deviceState.saturation}%`)
348
- // }
349
- // } else if (deviceState.mode === 'white') {
350
- // // ────────────────────────────────────────────────────────────────
351
- // // SCENARIO B: Device is in WHITE mode (Color Temperature)
352
- // // ────────────────────────────────────────────────────────────────
353
- //
354
- // // Convert Kelvin to Mireds: mireds = 1,000,000 / kelvin
355
- // const newMireds = Math.round(1000000 / deviceState.colorTemp)
356
- //
357
- // // Check if color temp actually changed or mode switched
358
- // const miredsChanged = newMireds !== homekitMireds
359
- // const modeChanged = homekitColorMode !== api.matter.types.ColorControl.ColorMode.ColorTemperatureMireds // Not in ColorTemp mode
360
- //
361
- // if (miredsChanged || modeChanged) {
362
- // log.info(`[Extended Color Light] Color temp changed: ${deviceState.colorTemp}K (${newMireds} mireds)`)
363
- //
364
- // // Update colorMode to indicate we're using Color Temperature
365
- // accessory.clusters.colorControl.colorMode = api.matter.types.ColorControl.ColorMode.ColorTemperatureMireds
366
- //
367
- // // Update color temperature
368
- // accessory.clusters.colorControl.colorTemperatureMireds = newMireds
369
- //
370
- // // Notify HomeKit
371
- // await api.matter.updateAccessoryState(accessory.uuid, api.matter.clusterNames.ColorControl, {
372
- // colorMode: api.matter.types.ColorControl.ColorMode.ColorTemperatureMireds,
373
- // colorTemperatureMireds: newMireds,
374
- // })
375
- //
376
- // log.info(`[Extended Color Light] ✓ Updated to white mode: ${deviceState.colorTemp}K`)
377
- // }
378
- // }
379
- }
380
- catch (error) {
381
- log.error(`[Extended Color Light] Error polling device state: ${error}`);
382
- }
383
- }, 5000);
384
- };
385
- // Uncomment to enable polling:
386
- // startPollingExample()
387
- /**
388
- * Example: Event-based updates (MQTT example with color support)
389
- */
390
- const startEventListenerExample = () => {
391
- // Example: MQTT listener that handles color changes
392
- // mqttClient.subscribe('home/extended-light/state')
393
- // mqttClient.on('message', async (topic, message) => {
394
- // if (topic === 'home/extended-light/state') {
395
- // const deviceState = JSON.parse(message.toString())
396
- // // Example: { "power": "on", "brightness": 75, "mode": "color", "hue": 180, "saturation": 100 }
397
- //
398
- // let updated = false
399
- //
400
- // // Update power
401
- // const deviceIsOn = deviceState.power === 'on'
402
- // if (deviceIsOn !== accessory.clusters.onOff.onOff) {
403
- // accessory.clusters.onOff.onOff = deviceIsOn
404
- // await api.matter.updateAccessoryState(accessory.uuid, api.matter.clusterNames.OnOff, { onOff: deviceIsOn })
405
- // updated = true
406
- // }
407
- //
408
- // // Update brightness
409
- // const currentPercent = Math.round((accessory.clusters.levelControl.currentLevel / 254) * 100)
410
- // if (deviceState.brightness !== currentPercent) {
411
- // const newLevel = Math.max(1, Math.round((deviceState.brightness / 100) * 254))
412
- // accessory.clusters.levelControl.currentLevel = newLevel
413
- // await api.matter.updateAccessoryState(accessory.uuid, api.matter.clusterNames.LevelControl, { currentLevel: newLevel })
414
- // updated = true
415
- // }
416
- //
417
- // // Update color
418
- // if (deviceState.mode === 'color') {
419
- // const newHue = Math.round((deviceState.hue / 360) * 254)
420
- // const newSat = Math.round((deviceState.saturation / 100) * 254)
421
- // if (newHue !== accessory.clusters.colorControl.currentHue ||
422
- // newSat !== accessory.clusters.colorControl.currentSaturation ||
423
- // accessory.clusters.colorControl.colorMode !== api.matter.types.ColorControl.ColorMode.CurrentHueAndCurrentSaturation) {
424
- // accessory.clusters.colorControl.colorMode = api.matter.types.ColorControl.ColorMode.CurrentHueAndCurrentSaturation
425
- // accessory.clusters.colorControl.currentHue = newHue
426
- // accessory.clusters.colorControl.currentSaturation = newSat
427
- // await api.matter.updateAccessoryState(accessory.uuid, api.matter.clusterNames.ColorControl, {
428
- // colorMode: api.matter.types.ColorControl.ColorMode.CurrentHueAndCurrentSaturation,
429
- // currentHue: newHue,
430
- // currentSaturation: newSat,
431
- // })
432
- // updated = true
433
- // }
434
- // } else if (deviceState.mode === 'white' && deviceState.colorTemp) {
435
- // const newMireds = Math.round(1000000 / deviceState.colorTemp)
436
- // if (newMireds !== accessory.clusters.colorControl.colorTemperatureMireds ||
437
- // accessory.clusters.colorControl.colorMode !== api.matter.types.ColorControl.ColorMode.ColorTemperatureMireds) {
438
- // accessory.clusters.colorControl.colorMode = api.matter.types.ColorControl.ColorMode.ColorTemperatureMireds
439
- // accessory.clusters.colorControl.colorTemperatureMireds = newMireds
440
- // await api.matter.updateAccessoryState(accessory.uuid, api.matter.clusterNames.ColorControl, {
441
- // colorMode: api.matter.types.ColorControl.ColorMode.ColorTemperatureMireds,
442
- // colorTemperatureMireds: newMireds,
443
- // })
444
- // updated = true
445
- // }
446
- // }
447
- //
448
- // if (updated) {
449
- // log.info(`[Extended Color Light] ✓ Updated from MQTT`)
450
- // }
451
- // }
452
- // })
453
- };
454
- // Uncomment to enable event listeners:
455
- // startEventListenerExample()
456
- // ═════════════════════════════════════════════════════════════════════════════
457
- // KEY TAKEAWAYS FOR EXTENDED COLOR LIGHTS:
458
- // ═════════════════════════════════════════════════════════════════════════════
459
- //
460
- // 0. TWO SEPARATE FLOWS (applies to all devices):
461
- // FLOW A (Home App → Physical Device):
462
- // - Handlers run when user controls via Home app
463
- // - You control the physical device
464
- // - Homebridge AUTOMATICALLY updates Matter state after handler
465
- // - DO NOT call api.matter.updateAccessoryState() in handlers!
466
- //
467
- // FLOW B (Physical Device → Home App):
468
- // - Physical device changes externally
469
- // - You MUST monitor device and detect changes
470
- // - You MUST call api.matter.updateAccessoryState() for changed clusters
471
- // - Then all controllers are notified
472
- //
473
- // 1. COLOR MODES:
474
- // - api.matter.types.ColorControl.ColorMode.CurrentHueAndCurrentSaturation (0): Hue/Saturation (0-254 each)
475
- // - api.matter.types.ColorControl.ColorMode.CurrentXAndCurrentY (1): CIE 1931 color space (0-65535 each)
476
- // - api.matter.types.ColorControl.ColorMode.ColorTemperatureMireds (2): Color Temperature in mireds
477
- // - Always update colorMode when switching between color and white
478
- //
479
- // 2. VALUE CONVERSIONS:
480
- // Hue:
481
- // - Device (degrees): 0-360
482
- // - Matter: 0-254
483
- // - To Matter: Math.round((degrees / 360) * 254)
484
- // - From Matter: Math.round((value / 254) * 360)
485
- //
486
- // Saturation:
487
- // - Device (percent): 0-100
488
- // - Matter: 0-254
489
- // - To Matter: Math.round((percent / 100) * 254)
490
- // - From Matter: Math.round((value / 254) * 100)
491
- //
492
- // Color Temperature:
493
- // - Device (Kelvin): 2200-6800
494
- // - Matter (Mireds): 147-454
495
- // - To Mireds: Math.round(1000000 / kelvin)
496
- // - To Kelvin: Math.round(1000000 / mireds)
497
- //
498
- // XY (if needed):
499
- // - Device (float): 0.0-1.0
500
- // - Matter: 0-65535
501
- // - To Matter: Math.round(float * 65535)
502
- // - From Matter: (value / 65535)
503
- //
504
- // 3. UPDATING COLOR STATE (Physical Device → Home App):
505
- // - Always update colorMode when switching between color and white
506
- // - Use api.matter.updateAccessoryState(uuid, api.matter.clusterNames.ColorControl, { ... })
507
- // - Update all color values at once in the attributes object
508
- // - Keep HS and XY in sync for best compatibility (use color conversion)
509
- // - ONLY use this for FLOW B (external changes), NOT in handlers!
510
- //
511
- // 4. READING STATE:
512
- // - Check colorMode to know which values are currently active
513
- // - CurrentHueAndCurrentSaturation or CurrentXAndCurrentY: Use color values (hue/sat or XY)
514
- // - ColorTemperatureMireds: Use colorTemperatureMireds
515
- // - Brightness (currentLevel) is independent of color mode
516
- // - Access via: accessory.clusters.colorControl.colorMode, etc.
517
- //
518
- // 5. COMMON PITFALLS:
519
- // - Calling updateAccessoryState() in handlers (it's automatic!)
520
- // - Forgetting to update colorMode when switching between color and white
521
- // - Using wrong conversion formulas (degrees vs 0-254 range)
522
- // - Not handling all three color modes your device supports
523
- // - Using old api.matter.updateCluster() instead of updateAccessoryState()
524
- // ═════════════════════════════════════════════════════════════════════════════
525
159
  }
526
160
  return accessories;
527
161
  }
@@ -1 +1 @@
1
- {"version":3,"file":"extended-color-light.js","sourceRoot":"","sources":["../../../src/devices/section-4-lighting/extended-color-light.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAMH,MAAM,UAAU,0BAA0B,CAAC,OAAsB;IAC/D,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IACpC,MAAM,WAAW,GAAU,EAAE,CAAA;IAE7B,4CAA4C;IAC5C,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAC7B,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC;YACrD,WAAW,EAAE,mBAAmB;YAChC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,kBAAkB;YACrD,YAAY,EAAE,WAAW;YACzB,YAAY,EAAE,iBAAiB;YAC/B,KAAK,EAAE,eAAe;YAEtB,QAAQ,EAAE;gBACR,KAAK,EAAE;oBACL,KAAK,EAAE,KAAK;iBACb;gBACD,YAAY,EAAE;oBACZ,YAAY,EAAE,GAAG;oBACjB,QAAQ,EAAE,CAAC;oBACX,QAAQ,EAAE,GAAG;iBACd;gBACD,YAAY,EAAE;oBACZ,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,8BAA8B,EAAE,sBAAsB;oBACzG,UAAU,EAAE,CAAC,EAAE,kBAAkB;oBACjC,iBAAiB,EAAE,GAAG,EAAE,kBAAkB;oBAC1C,QAAQ,EAAE,KAAK,EAAE,oCAAoC;oBACrD,QAAQ,EAAE,KAAK;iBAChB;aACF;YAED,QAAQ,EAAE;gBACR,KAAK,EAAE;oBACL,EAAE,EAAE,KAAK,IAAI,EAAE;wBACb,GAAG,CAAC,IAAI,CAAC,wEAAwE,CAAC,CAAA;oBACpF,CAAC;oBACD,GAAG,EAAE,KAAK,IAAI,EAAE;wBACd,GAAG,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAA;oBACrF,CAAC;iBACF;gBACD,YAAY,EAAE;oBACZ,oBAAoB,EAAE,KAAK,EAAE,OAAmC,EAAE,EAAE;wBAClE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;wBACzB,GAAG,CAAC,IAAI,CAAC,2DAA2D,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAA;oBAClH,CAAC;iBACF;gBACD,YAAY,EAAE;oBACZ,gBAAgB,EAAE,KAAK,EAAE,OAAqE,EAAE,EAAE;wBAChG,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAA;wBACpD,MAAM,MAAM,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;wBAC3C,MAAM,MAAM,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;wBAC3C,GAAG,CAAC,IAAI,CAAC,kEAAkE,OAAO,MAAM,MAAM,QAAQ,OAAO,MAAM,MAAM,kBAAkB,cAAc,GAAG,CAAC,CAAA;oBAC/J,CAAC;oBACD,2BAA2B,EAAE,KAAK,EAAE,OAAgF,EAAE,EAAE;wBACtH,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,cAAc,EAAE,GAAG,OAAO,CAAA;wBAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;wBACtD,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,gBAAgB,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;wBACpE,GAAG,CAAC,IAAI,CAAC,+EAA+E,SAAS,MAAM,UAAU,kBAAkB,gBAAgB,MAAM,iBAAiB,mBAAmB,cAAc,GAAG,CAAC,CAAA;oBACjN,CAAC;oBACD,2FAA2F;iBAC5F;aACF;SACF,CAAC,CAAA;IACJ,CAAC;IAED,8EAA8E;IAC9E,gEAAgE;IAChE,8EAA8E;IAC9E,EAAE;IACF,0CAA0C;IAC1C,sCAAsC;IACtC,oDAAoD;IACpD,EAAE;IACF,6EAA6E;IAC7E,mBAAmB;IACnB,IAAI,MAAM,CAAC,yBAAyB,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG;YAChB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,8BAA8B,CAAC;YAC9D,WAAW,EAAE,gCAAgC;YAC7C,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,kBAAkB;YACrD,YAAY,EAAE,WAAW;YACzB,YAAY,EAAE,iBAAiB;YAC/B,KAAK,EAAE,uBAAuB;YAE9B,QAAQ,EAAE;gBACR,KAAK,EAAE;oBACL,KAAK,EAAE,KAAK;iBACb;gBACD,YAAY,EAAE;oBACZ,YAAY,EAAE,GAAG;oBACjB,QAAQ,EAAE,CAAC;oBACX,QAAQ,EAAE,GAAG;iBACd;gBACD,YAAY,EAAE;oBACZ,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,8BAA8B,EAAE,sBAAsB;oBACzG,UAAU,EAAE,CAAC,EAAE,kBAAkB;oBACjC,iBAAiB,EAAE,GAAG,EAAE,kBAAkB;oBAC1C,QAAQ,EAAE,KAAK,EAAE,oCAAoC;oBACrD,QAAQ,EAAE,KAAK;oBACf,sBAAsB,EAAE,GAAG,EAAE,wBAAwB;oBACrD,0BAA0B,EAAE,GAAG,EAAE,kBAAkB;oBACnD,0BAA0B,EAAE,GAAG,EAAE,kBAAkB;oBACnD,+BAA+B,EAAE,GAAG;iBACrC;aACF;YAED,QAAQ,EAAE;gBACR,KAAK,EAAE;oBACL,EAAE,EAAE,KAAK,IAAI,EAAE;wBACb,GAAG,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAA;oBAC1F,CAAC;oBACD,GAAG,EAAE,KAAK,IAAI,EAAE;wBACd,GAAG,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAA;oBAC3F,CAAC;iBACF;gBACD,YAAY,EAAE;oBACZ,oBAAoB,EAAE,KAAK,EAAE,OAAmC,EAAE,EAAE;wBAClE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;wBACzB,GAAG,CAAC,IAAI,CAAC,iEAAiE,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAA;oBACxH,CAAC;iBACF;gBACD,YAAY,EAAE;oBACZ,gBAAgB,EAAE,KAAK,EAAE,OAAqE,EAAE,EAAE;wBAChG,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAA;wBACpD,MAAM,MAAM,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;wBAC3C,MAAM,MAAM,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;wBAC3C,GAAG,CAAC,IAAI,CAAC,wEAAwE,OAAO,MAAM,MAAM,QAAQ,OAAO,MAAM,MAAM,kBAAkB,cAAc,GAAG,CAAC,CAAA;oBACrK,CAAC;oBACD,2BAA2B,EAAE,KAAK,EAAE,OAAgF,EAAE,EAAE;wBACtH,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,cAAc,EAAE,GAAG,OAAO,CAAA;wBAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;wBACtD,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,gBAAgB,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;wBACpE,GAAG,CAAC,IAAI,CAAC,qFAAqF,SAAS,MAAM,UAAU,kBAAkB,gBAAgB,MAAM,iBAAiB,mBAAmB,cAAc,GAAG,CAAC,CAAA;oBACvN,CAAC;oBACD,2BAA2B,EAAE,KAAK,EAAE,OAAyD,EAAE,EAAE;wBAC/F,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,OAAO,CAAA;wBAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,YAAY,CAAC,CAAA;wBACjD,GAAG,CAAC,IAAI,CAAC,iFAAiF,YAAY,aAAa,MAAM,mBAAmB,cAAc,GAAG,CAAC,CAAA;oBAChK,CAAC;iBACF;aACF;SACF,CAAA;QAED,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAE3B,gFAAgF;QAChF,0DAA0D;QAC1D,gFAAgF;QAChF,EAAE;QACF,yEAAyE;QACzE,EAAE;QACF,kCAAkC;QAClC,+CAA+C;QAC/C,EAAE;QACF,wCAAwC;QACxC,sDAAsD;QACtD,EAAE;QACF,yCAAyC;QACzC,yDAAyD;QACzD,yDAAyD;QACzD,yDAAyD;QACzD,yDAAyD;QACzD,yDAAyD;QACzD,uEAAuE;QACvE,EAAE;QACF,0CAA0C;QAC1C,MAAM,mBAAmB,GAAG,GAAG,EAAE;YAC/B,cAAc;YACd,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAA;YAE3C,aAAa;YACb,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAA;YAC1D,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;YAEzD,aAAa;YACb,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAA;YACtD,MAAM,SAAS,GAA2B;gBACxC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,8BAA8B,CAAC,EAAE,gBAAgB;gBAC1F,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,mBAAmB,CAAC,EAAE,IAAI;gBACnE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,sBAAsB,CAAC,EAAE,mBAAmB;aACtF,CAAA;YACD,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,SAAS,CAAA;YAE7C,oBAAoB;YACpB,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAA;YACtD,MAAM,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,iBAAiB,CAAA;YACpE,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;YAChD,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;YAE9D,oBAAoB;YACpB,MAAM,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAA;YAClD,MAAM,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAA;YAClD,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;YACrC,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;YAErC,mCAAmC;YACnC,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,sBAAsB,CAAA;YACrE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,CAAA;YAE3C,GAAG,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAA;YAClD,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;YAC3C,GAAG,CAAC,IAAI,CAAC,iBAAiB,iBAAiB,GAAG,CAAC,CAAA;YAC/C,GAAG,CAAC,IAAI,CAAC,iBAAiB,QAAQ,EAAE,CAAC,CAAA;YACrC,GAAG,CAAC,IAAI,CAAC,UAAU,UAAU,MAAM,GAAG,GAAG,CAAC,CAAA;YAC1C,GAAG,CAAC,IAAI,CAAC,iBAAiB,iBAAiB,MAAM,UAAU,GAAG,CAAC,CAAA;YAC/D,GAAG,CAAC,IAAI,CAAC,UAAU,MAAM,KAAK,MAAM,EAAE,CAAC,CAAA;YACvC,GAAG,CAAC,IAAI,CAAC,iBAAiB,MAAM,MAAM,MAAM,UAAU,CAAC,CAAA;QACzD,CAAC,CAAA;QAED,mCAAmC;QACnC,wBAAwB;QAExB,gFAAgF;QAChF,wDAAwD;QACxD,gFAAgF;QAChF,EAAE;QACF,6DAA6D;QAC7D,iCAAiC;QACjC,6BAA6B;QAC7B,yCAAyC;QACzC,oDAAoD;QACpD,mCAAmC;QACnC,EAAE;QACF,6EAA6E;QAE7E;;WAEG;QACH,MAAM,mBAAmB,GAAG,GAAG,EAAE;YAC/B,WAAW,CAAC,KAAK,IAAI,EAAE;gBACrB,IAAI,CAAC;oBACH,yEAAyE;oBACzE,uCAAuC;oBACvC,yEAAyE;oBACzE,4CAA4C;oBAC5C,sEAAsE;oBACtE,EAAE;oBACF,sCAAsC;oBACtC,IAAI;oBACJ,mBAAmB;oBACnB,uCAAuC;oBACvC,mDAAmD;oBACnD,8CAA8C;oBAC9C,uCAAuC;oBACvC,uCAAuC;oBACvC,IAAI;oBAEJ,2CAA2C;oBAC3C,wBAAwB;oBACxB,iBAAiB;oBACjB,oBAAoB;oBACpB,mBAAmB;oBACnB,cAAc;oBACd,qBAAqB;oBACrB,qBAAqB;oBACrB,IAAI;oBAEJ,yEAAyE;oBACzE,qCAAqC;oBACrC,yEAAyE;oBACzE,MAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAA;oBAClD,MAAM,YAAY,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAA;oBACjE,MAAM,wBAAwB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;oBACvE,MAAM,gBAAgB,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAA;oBAClE,MAAM,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAA;oBAC7D,MAAM,iBAAiB,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,iBAAiB,CAAA;oBAC3E,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,sBAAsB,CAAA;oBAE5E,yEAAyE;oBACzE,uCAAuC;oBACvC,yEAAyE;oBAEzE,iBAAiB;oBACjB,gDAAgD;oBAChD,oCAAoC;oBACpC,mFAAmF;oBACnF,gDAAgD;oBAChD,gHAAgH;oBAChH,IAAI;oBAEJ,sBAAsB;oBACtB,6DAA6D;oBAC7D,sFAAsF;oBACtF,mFAAmF;oBACnF,4DAA4D;oBAC5D,4HAA4H;oBAC5H,IAAI;oBAEJ,gCAAgC;oBAChC,sCAAsC;oBACtC,wEAAwE;oBACxE,2CAA2C;oBAC3C,wEAAwE;oBACxE,EAAE;oBACF,wDAAwD;oBACxD,6DAA6D;oBAC7D,EAAE;oBACF,sEAAsE;oBACtE,2EAA2E;oBAC3E,EAAE;oBACF,uCAAuC;oBACvC,6CAA6C;oBAC7C,kEAAkE;oBAClE,iEAAiE;oBACjE,EAAE;oBACF,0DAA0D;oBAC1D,2GAA2G;oBAC3G,EAAE;oBACF,+EAA+E;oBAC/E,4DAA4D;oBAC5D,EAAE;oBACF,iEAAiE;oBACjE,yHAAyH;oBACzH,EAAE;oBACF,mCAAmC;oBACnC,0DAA0D;oBAC1D,wEAAwE;oBACxE,EAAE;oBACF,sEAAsE;oBACtE,oEAAoE;oBACpE,0EAA0E;oBAC1E,wFAAwF;oBACxF,0EAA0E;oBAC1E,0EAA0E;oBAC1E,EAAE;oBACF,6DAA6D;oBAC7D,oGAAoG;oBACpG,2FAA2F;oBAC3F,4BAA4B;oBAC5B,0CAA0C;oBAC1C,4CAA4C;oBAC5C,4CAA4C;oBAC5C,SAAS;oBACT,EAAE;oBACF,qHAAqH;oBACrH,MAAM;oBACN,6CAA6C;oBAC7C,wEAAwE;oBACxE,+DAA+D;oBAC/D,wEAAwE;oBACxE,EAAE;oBACF,6DAA6D;oBAC7D,kEAAkE;oBAClE,EAAE;oBACF,6DAA6D;oBAC7D,sDAAsD;oBACtD,qIAAqI;oBACrI,EAAE;oBACF,wCAAwC;oBACxC,6GAA6G;oBAC7G,EAAE;oBACF,oEAAoE;oBACpE,iHAAiH;oBACjH,EAAE;oBACF,kCAAkC;oBAClC,yEAAyE;oBACzE,EAAE;oBACF,wBAAwB;oBACxB,oGAAoG;oBACpG,mFAAmF;oBACnF,2CAA2C;oBAC3C,SAAS;oBACT,EAAE;oBACF,4FAA4F;oBAC5F,MAAM;oBACN,IAAI;gBACN,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,GAAG,CAAC,KAAK,CAAC,sDAAsD,KAAK,EAAE,CAAC,CAAA;gBAC1E,CAAC;YACH,CAAC,EAAE,IAAI,CAAC,CAAA;QACV,CAAC,CAAA;QAED,+BAA+B;QAC/B,wBAAwB;QAExB;;WAEG;QACH,MAAM,yBAAyB,GAAG,GAAG,EAAE;YACrC,oDAAoD;YACpD,oDAAoD;YACpD,uDAAuD;YACvD,iDAAiD;YACjD,yDAAyD;YACzD,sGAAsG;YACtG,EAAE;YACF,0BAA0B;YAC1B,EAAE;YACF,sBAAsB;YACtB,oDAAoD;YACpD,2DAA2D;YAC3D,oDAAoD;YACpD,oHAAoH;YACpH,uBAAuB;YACvB,QAAQ;YACR,EAAE;YACF,2BAA2B;YAC3B,oGAAoG;YACpG,uDAAuD;YACvD,uFAAuF;YACvF,gEAAgE;YAChE,gIAAgI;YAChI,uBAAuB;YACvB,QAAQ;YACR,EAAE;YACF,sBAAsB;YACtB,0CAA0C;YAC1C,iEAAiE;YACjE,wEAAwE;YACxE,qEAAqE;YACrE,4EAA4E;YAC5E,oIAAoI;YACpI,6HAA6H;YAC7H,8DAA8D;YAC9D,qEAAqE;YACrE,wGAAwG;YACxG,+FAA+F;YAC/F,gCAAgC;YAChC,uCAAuC;YACvC,aAAa;YACb,yBAAyB;YACzB,UAAU;YACV,0EAA0E;YAC1E,sEAAsE;YACtE,oFAAoF;YACpF,4HAA4H;YAC5H,qHAAqH;YACrH,6EAA6E;YAC7E,wGAAwG;YACxG,uFAAuF;YACvF,+CAA+C;YAC/C,aAAa;YACb,yBAAyB;YACzB,UAAU;YACV,QAAQ;YACR,EAAE;YACF,qBAAqB;YACrB,+DAA+D;YAC/D,QAAQ;YACR,MAAM;YACN,KAAK;QACP,CAAC,CAAA;QAED,uCAAuC;QACvC,8BAA8B;QAE9B,gFAAgF;QAChF,2CAA2C;QAC3C,gFAAgF;QAChF,EAAE;QACF,kDAAkD;QAClD,0CAA0C;QAC1C,oDAAoD;QACpD,uCAAuC;QACvC,mEAAmE;QACnE,kEAAkE;QAClE,EAAE;QACF,0CAA0C;QAC1C,0CAA0C;QAC1C,kDAAkD;QAClD,4EAA4E;QAC5E,yCAAyC;QACzC,EAAE;QACF,kBAAkB;QAClB,+GAA+G;QAC/G,4GAA4G;QAC5G,uGAAuG;QACvG,sEAAsE;QACtE,EAAE;QACF,wBAAwB;QACxB,UAAU;QACV,iCAAiC;QACjC,uBAAuB;QACvB,sDAAsD;QACtD,sDAAsD;QACtD,EAAE;QACF,iBAAiB;QACjB,iCAAiC;QACjC,uBAAuB;QACvB,sDAAsD;QACtD,sDAAsD;QACtD,EAAE;QACF,wBAAwB;QACxB,oCAAoC;QACpC,kCAAkC;QAClC,iDAAiD;QACjD,iDAAiD;QACjD,EAAE;QACF,qBAAqB;QACrB,iCAAiC;QACjC,yBAAyB;QACzB,8CAA8C;QAC9C,sCAAsC;QACtC,EAAE;QACF,wDAAwD;QACxD,sEAAsE;QACtE,gGAAgG;QAChG,gEAAgE;QAChE,4EAA4E;QAC5E,qEAAqE;QACrE,EAAE;QACF,oBAAoB;QACpB,iEAAiE;QACjE,+FAA+F;QAC/F,0DAA0D;QAC1D,8DAA8D;QAC9D,mEAAmE;QACnE,EAAE;QACF,sBAAsB;QACtB,oEAAoE;QACpE,6EAA6E;QAC7E,gEAAgE;QAChE,+DAA+D;QAC/D,8EAA8E;QAC9E,gFAAgF;IAClF,CAAC;IAED,OAAO,WAAW,CAAA;AACpB,CAAC"}
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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"}
@@ -1,36 +1,16 @@
1
1
  /**
2
2
  * On/Off Light Device (Matter Spec § 4.1)
3
3
  *
4
- * The On/Off Light is a lighting device that is capable of being switched on or off.
4
+ * A basic lighting device that can be switched on or off.
5
5
  *
6
- * ═══════════════════════════════════════════════════════════════════════════════
7
- * CRITICAL ARCHITECTURE UNDERSTANDING - THE TWO-WAY FLOW:
8
- * ═══════════════════════════════════════════════════════════════════════════════
6
+ * For comprehensive documentation on Matter concepts, handlers, state management,
7
+ * and the two-way flow architecture, see:
8
+ * ../../../MATTER_API.md
9
9
  *
10
- * There are TWO separate flows for a Homebridge Matter plugin:
11
- *
12
- * FLOW A: Home App Physical Device (AUTOMATIC - via handlers)
13
- * ────────────────────────────────────────────────────────────────
14
- * 1. User taps in Home App
15
- * 2. Matter command received by Homebridge
16
- * 3. Your handler runs (on/off methods below)
17
- * 4. You control your physical device (API call, MQTT, etc.)
18
- * 5. Homebridge AUTOMATICALLY updates Matter state
19
- * 6. All controllers (iPhone, iPad, etc.) are notified
20
- * ✅ No manual state update needed!
21
- *
22
- * FLOW B: Physical Device → Home App (MANUAL - you must update state)
23
- * ────────────────────────────────────────────────────────────────
24
- * 1. User presses physical button on device (OR cloud app, automation, etc.)
25
- * 2. Physical device changes state
26
- * 3. ❌ Homebridge has NO IDEA this happened!
27
- * 4. You MUST detect the change (via polling, MQTT, webhook, etc.)
28
- * 5. You MUST call api.matter.updateAccessoryState() to update Matter
29
- * 6. Then all controllers are notified
30
- * ⚠️ If you don't do step 5, Home App shows wrong state!
31
- *
32
- * This example demonstrates BOTH flows in detail.
33
- * ═══════════════════════════════════════════════════════════════════════════════
10
+ * This example demonstrates:
11
+ * - Basic OnOff cluster implementation
12
+ * - Handler setup for on/off commands (Flow A)
13
+ * - Event-based state monitoring (Flow B)
34
14
  */
35
15
  import type { DeviceContext } from '../types.js';
36
16
  export declare function registerOnOffLight(context: DeviceContext): any[];