Skip to content

Commit ba30999

Browse files
v3.1.1
* expand Matter device registration/mapping across supported device families (WallDimmer, WallSwitch, Serena tilt-only blinds, occupancy sensors, and Pico remotes) using `api.matter.deviceTypes.*` * refactor platform layout into dedicated HAP and Matter modules (`Platform.HAP.ts`, `Platform.Matter.ts`) and add Matter cluster helpers in device classes * Matter registration: set required accessory metadata on root object (fixes missing `manufacturer` validation failures) * Matter registration: constrain bridged accessory display names to Matter nodeLabel length limits (fixes `Behaviors have errors` on long room/device names) * Pico Matter behavior: move to GenericSwitch state updates for button presses, expand Pico button map coverage, and include Pico4Button in Matter GenericSwitch registration mapping * add `options.excludedDeviceTypes` support to skip selected device types in both HAP and Matter registration paths (including removing cached accessories for explicitly excluded types) * excluded-device cleanup: in Matter mode, unregister excluded cached accessories from both HAP and Matter registries for deterministic removal * Pico button mapping robustness: improve `Pico3ButtonRaiseLower` alias resolution (including `Favorite` center-button naming variants) and skip unknown button definitions without failing whole-remote initialization * Matter command handling: add explicit handlers so WallDimmer and WallSwitch On/Off/Level commands always dispatch LEAP `GoToLevel` requests * Matter blind control: add `windowCovering.goToTiltPercentage` handler for Serena tilt-only blinds to map Matter tilt commands to LEAP blind tilt writes * Matter external-state sync: propagate unsolicited bridge updates back into Matter cluster state for WallDimmer (`onOff` + `levelControl`), WallSwitch (`onOff`), Serena tilt-only blinds (`windowCovering` tilt), and occupancy sensors (`occupancySensing`) * Pico Matter composed endpoint polish: use `BridgedNode` as Pico parent in composed mode and provide part `displayName` values to avoid undefined child labels in UI * align imports/file naming with ESM casing expectations and update docs output * bump Homebridge beta compatibility to `^2.0.0-beta.109` and refresh lint/tooling dependencies **Full Changelog**: v3.1.0...v3.1.1 Co-Authored-By: donavanbecker <9875439+donavanbecker@users.noreply.github.com> Co-Authored-By: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 7dc2a2b commit ba30999

18 files changed

Lines changed: 1221 additions & 443 deletions

.github/copilot-instructions.md

Lines changed: 102 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,67 @@
22

33
Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.
44

5-
This is a Homebridge plugin that provides HomeKit integration for Lutron Caseta Smart Bridge devices including Pico remotes, occupancy sensors, and Serena wood blinds. The plugin is written in TypeScript and uses the lutron-leap-js library to communicate with Lutron bridges via the LEAP protocol.
5+
This is a Homebridge plugin that provides HomeKit and Matter integration for Lutron Caseta Smart Bridge 2 devices. The plugin is written in TypeScript and uses the lutron-leap-js library to communicate with Lutron bridges via the LEAP protocol.
6+
7+
**Current Focus:** Full Matter support alongside HAP (HomeKit Accessory Protocol). All new devices support both HAP and Matter simultaneously.
8+
9+
## Device Support
10+
11+
### Currently Supported Devices
12+
- **WallDimmer** — Lutron dimmers (Matter: DimmableLight)
13+
- **WallSwitch** — Lutron switches (Matter: OnOffLight)
14+
- **SerenaTiltOnlyWoodBlind** — Serena wood blinds, tilt-only (Matter: WindowCovering)
15+
- **RPSOccupancySensor** — Lutron occupancy sensors (Matter: OccupancySensor)
16+
- **Pico Remotes** — All Pico remote models:
17+
- Pico2Button, Pico2ButtonRaiseLower
18+
- Pico3Button, Pico3ButtonRaiseLower
19+
- Pico4Button, Pico4Button2Group, Pico4ButtonScene, Pico4ButtonZone
20+
- PaddleSwitchPico
21+
- (Matter: GenericSwitch)
22+
23+
### Devices Not Yet Supported (Contributions Welcome)
24+
- Color temperature lighting
25+
- Additional blind types (vertical rails, honeycomb, etc.)
26+
- Motorized shades with position feedback
27+
28+
## Matter and HomeKit Integration
29+
30+
### Matter Implementation
31+
The plugin implements dual-mode device registration:
32+
- **HAP mode** (HomeKit Accessory Protocol): Base implementation via `LutronCasetaLeap` class
33+
- **Matter mode**: Extended via `LutronCasetaLeapMatterPlatform` class that overrides `processDevice()`
34+
35+
When Homebridge's Matter API is available, `LutronCasetaLeapMatterPlatform.processDevice()` registers accessories with both HAP and Matter simultaneously. If Matter API is not available, the plugin transparently falls back to HAP-only mode.
36+
37+
### Matter Device Type Mapping
38+
All Matter device types use `api.matter.deviceTypes.*` objects from the homebridge-matter API:
39+
40+
| Device Type | HAP Service | Matter DeviceType | Matter Clusters |
41+
|---|---|---|---|
42+
| WallDimmer | Lightbulb | `DimmableLight` | onOff, levelControl |
43+
| WallSwitch | Switch | `OnOffLight` | onOff |
44+
| SerenaTiltOnlyWoodBlind | WindowCovering | `WindowCovering` | windowCovering |
45+
| RPSOccupancySensor | OccupancySensor | `OccupancySensor` | occupancySensing |
46+
| Pico Remotes | StatelessProgrammableSwitch | `GenericSwitch` | switch |
47+
48+
### Authoritative Matter References
49+
For all Matter cluster, attribute, and device type specifications, use the official homebridge-matter wiki:
50+
- [Introduction](https://github.com/homebridge-plugins/homebridge-matter/wiki/Introduction)
51+
- [Core Concepts](https://github.com/homebridge-plugins/homebridge-matter/wiki/Core-Concepts)
52+
- [Getting Started](https://github.com/homebridge-plugins/homebridge-matter/wiki/Getting-Started)
53+
- [State Management](https://github.com/homebridge-plugins/homebridge-matter/wiki/State-Management)
54+
- [Monitoring External Changes](https://github.com/homebridge-plugins/homebridge-matter/wiki/Monitoring-External-Changes)
55+
- [Best Practices](https://github.com/homebridge-plugins/homebridge-matter/wiki/Best-Practices)
56+
- [Advanced Patterns](https://github.com/homebridge-plugins/homebridge-matter/wiki/Advanced-Patterns)
57+
- [API Reference](https://github.com/homebridge-plugins/homebridge-matter/wiki/API-Reference)
58+
- [Matter Types](https://github.com/homebridge-plugins/homebridge-matter/wiki/Matter-Types)
59+
- [Value Conversions](https://github.com/homebridge-plugins/homebridge-matter/wiki/Value-Conversions)
60+
61+
**Device References:**
62+
- [Lighting Devices (§4)](https://github.com/homebridge-plugins/homebridge-matter/wiki/Section-4-Lighting) — DimmableLight, OnOffLight
63+
- [Switches (§6)](https://github.com/homebridge-plugins/homebridge-matter/wiki/Section-6-Switches) — OnOffSwitch
64+
- [Sensors (§7)](https://github.com/homebridge-plugins/homebridge-matter/wiki/Section-7-Sensors) — OccupancySensor
65+
- [Closure Devices (§8)](https://github.com/homebridge-plugins/homebridge-matter/wiki/Section-8-Closure) — WindowCovering
666

767
## Working Effectively
868

@@ -14,7 +74,7 @@ This is a Homebridge plugin that provides HomeKit integration for Lutron Caseta
1474
- Check for outdated packages: `npm run check` -- runs npm install && npm outdated (may exit with code 1 if packages are outdated, this is normal)
1575

1676
### Testing and Quality Assurance
17-
- Run tests: `npm run test` -- takes ~1 second. Minimal test suite (only 2 tests in 1 file).
77+
- Run tests: `npm run test` -- takes ~1 second. Validates utility functions and OccupancySensorRouter singleton pattern.
1878
- Run tests with coverage: `npm run test-coverage` -- takes ~2 seconds. Shows coverage report.
1979
- Watch tests: `npm run test:watch` -- for continuous testing during development.
2080
- Lint code: `npm run lint` -- takes ~1 second. Uses ESLint with @antfu/eslint-config.
@@ -42,6 +102,7 @@ After making code changes, ALWAYS validate by:
42102
3. Running `npm run test` to verify existing functionality
43103
4. If changing UI components, validate the configuration UI works properly
44104
5. For bridge communication changes, test with actual Lutron hardware if possible
105+
6. For Matter changes, verify Matter registration succeeds in Homebridge logs
45106

46107
### End-to-End Validation Workflow
47108
To verify the complete development workflow works:
@@ -59,14 +120,19 @@ Both must pass for PRs to be merged. The workflow runs on pushes to 'latest' bra
59120
## Important Directories and Files
60121

61122
### Source Code Structure
62-
- `src/index.ts` -- Main plugin entry point, registers platform
63-
- `src/platform.ts` -- Core platform implementation, device discovery and management
123+
- `src/index.ts` -- Main plugin entry point, registers platform (choose HAP or Matter mode)
124+
- `src/Platform.HAP.ts` -- Core HAP-only platform implementation, device discovery and management
125+
- `src/Platform.Matter.ts` -- Matter platform that extends HAP, adds Matter registration for all supported device types
64126
- `src/settings.ts` -- Plugin configuration constants
65-
- `src/PicoRemote.ts` -- Pico remote button handling
66-
- `src/OccupancySensor.ts` -- Occupancy sensor implementation
67-
- `src/SerenaTiltOnlyWoodBlinds.ts` -- Serena blinds support
68-
- `src/ButtonState.ts` -- Button press state management
69-
- `src/OccupancySensorRouter.ts` -- Routing logic for occupancy sensors
127+
- `src/WallDimmer.ts` -- Dimmable light device (Matter: DimmableLight)
128+
- `src/WallSwitch.ts` -- On/off switch device (Matter: OnOffLight)
129+
- `src/SerenaTiltOnlyWoodBlinds.ts` -- Serena wood blinds with tilt control (Matter: WindowCovering)
130+
- `src/OccupancySensor.ts` -- Occupancy/motion sensor (Matter: OccupancySensor)
131+
- `src/PicoRemote.ts` -- Pico remote button handling for all remote types (Matter: OnOffSwitch)
132+
- `src/ButtonState.ts` -- Button press state machine and click detection
133+
- `src/OccupancySensorRouter.ts` -- Singleton routing logic for occupancy sensor events
134+
- `src/Logger.ts` -- Logging utilities respecting user verbosity settings
135+
- `src/utils.ts` -- Utility functions for UUID generation and device lookup
70136
- `src/homebridge-ui/` -- Custom Homebridge configuration UI
71137
- `src/homebridge-ui/server.ts` -- UI backend server for bridge discovery/pairing
72138
- `src/homebridge-ui/public/index.html` -- Frontend configuration interface
@@ -78,6 +144,7 @@ Both must pass for PRs to be merged. The workflow runs on pushes to 'latest' bra
78144
- `config.schema.json` -- Homebridge configuration schema
79145
- `nodemon.json` -- Development watch configuration
80146
- `typedoc.json` -- Documentation generation settings
147+
- `.github/copilot-instructions.md` -- This file
81148

82149
### Generated/Output
83150
- `dist/` -- Compiled JavaScript output (generated by `npm run build`)
@@ -87,8 +154,8 @@ Both must pass for PRs to be merged. The workflow runs on pushes to 'latest' bra
87154
## Dependencies and Requirements
88155

89156
### Runtime Requirements
90-
- Node.js 20 or 22 (specified in package.json engines)
91-
- Homebridge ^1.9.0 || ^2.0.0 || ^2.0.0-beta.26 || ^2.0.0-alpha.37
157+
- Node.js 22 or 24 (specified in package.json engines)
158+
- Homebridge ^1.11.4 || ^2.0.0-beta.106
92159

93160
### Key Dependencies
94161
- `lutron-leap` ^3.4.2 -- Core LEAP protocol library for bridge communication
@@ -98,20 +165,29 @@ Both must pass for PRs to be merged. The workflow runs on pushes to 'latest' bra
98165

99166
### Development Dependencies
100167
- `typescript` ^5.8.2 -- TypeScript compiler
101-
- `eslint` ^9.21.0 -- Code linting
102-
- `vitest` ^3.0.7 -- Testing framework
103-
- `typedoc` ^0.27.9 -- Documentation generation
168+
- `eslint` ^10.3.0 -- Code linting
169+
- `vitest` ^4.0.0+ -- Testing framework
170+
- `typedoc` ^0.27.9+ -- Documentation generation
104171
- `nodemon` ^3.1.9 -- Development file watching
105172

106173
## Common Development Tasks
107174

108175
### Adding New Device Support
109-
1. Add device type case to `platform.ts` in `configureAccessory` and `handleBridgeDiscovery`
176+
1. Add device type case to `Platform.HAP.ts` in `configureAccessory` and `handleBridgeDiscovery`
110177
2. Create new device class file in `src/` following pattern of existing devices
111178
3. Implement HomeKit services and characteristics in the new class
112-
4. Add LEAP protocol commands to lutron-leap-js library if needed
113-
5. Wire up event handlers for unsolicited bridge updates
114-
6. Test with actual hardware
179+
4. Add Matter device type and clusters via `Platform.Matter.ts` override
180+
5. Add LEAP protocol commands to lutron-leap-js library if needed
181+
6. Wire up event handlers for unsolicited bridge updates
182+
7. Test with actual hardware
183+
184+
### Adding Matter Support to Existing Device
185+
1. Create or update device's `getMatterClusters()` method to return Matter clusters object
186+
2. Add case statement to `Platform.Matter.ts` processDevice switch with `mApi.deviceTypes.*` assignment
187+
3. Set `(accessory as any).clusters` directly on the accessory (for single-endpoint) or `(accessory as any).parts` (for composed)
188+
4. Validate deviceType uses `api.matter.deviceTypes.*` object, not number array
189+
5. For composed devices, ensure each part has an `id: string` field
190+
6. Test both HAP and Matter registration via Homebridge logs
115191

116192
### UI Configuration Changes
117193
1. Modify `src/homebridge-ui/public/index.html` for frontend changes (bridge discovery/pairing UI)
@@ -141,7 +217,7 @@ The rough development workflow according to the maintainer:
141217
## Common Issues and Solutions
142218

143219
### Build or Link Failures
144-
- Ensure Node.js version 20 or 22 is installed
220+
- Ensure Node.js version 22 or 24 is installed
145221
- Run `npm install` to ensure all dependencies are current
146222
- Clear and rebuild: `npm run clean && npm run build`
147223

@@ -151,10 +227,9 @@ The rough development workflow according to the maintainer:
151227
- Import statements must use .js extensions (ESM requirement)
152228

153229
### Test Failures
154-
- Current test suite is minimal (only OccupancySensorRouter tests in 1 file)
230+
- Current test suite validates utility functions and OccupancySensorRouter singleton pattern
155231
- Tests use Vitest framework with TypeScript
156232
- Test files follow pattern: `*.test.ts` in src/ directory
157-
- Tests validate singleton pattern and state management for occupancy sensors
158233
- Failures likely indicate breaking changes to core functionality
159234
- Add tests for new features following existing vitest patterns
160235

@@ -163,6 +238,12 @@ The rough development workflow according to the maintainer:
163238
- Network configuration can prevent discovery (broadcast relay, VLANs, etc.)
164239
- Bridge must be on same network segment as Homebridge server
165240

241+
### Matter Registration Failures
242+
- Ensure `deviceType` is set via `mApi.deviceTypes.*` object, not a number array (causes "behaviors" must be array error)
243+
- For composed devices (parts array), each part must have an `id: string` field (causes "missing required field 'id'" error)
244+
- Verify all returned clusters match Matter spec — use homebridge-matter wiki to validate cluster attributes
245+
- Check Homebridge logs for Matter registration errors during startup
246+
166247
NEVER CANCEL long-running commands. Measured timings on standard development machine:
167248
- `npm install`: ~40 seconds
168249
- `npm run build`: ~5 seconds (includes clean, tsc, plugin-ui)

CHANGELOG.md

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,54 @@
1-
# [3.1.0](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/compare/v3.0.5...v3.1.0) (2026-04-29)
2-
1+
## [3.1.1](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/releases/tag/v3.1.1) (2026-05-02)
32

43
### Features
54

6-
* configurable log verbosity (logLevel + buttonPressLogging) ([#228](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/issues/228)) ([40b1fd9](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/commit/40b1fd9116c2b8b4877d70001ddac4f6c3f7ee5c))
5+
* expand Matter device registration/mapping across supported device families (WallDimmer, WallSwitch, Serena tilt-only blinds, occupancy sensors, and Pico remotes) using `api.matter.deviceTypes.*`
6+
* refactor platform layout into dedicated HAP and Matter modules (`Platform.HAP.ts`, `Platform.Matter.ts`) and add Matter cluster helpers in device classes
77

8+
### Bug Fixes
89

10+
* Matter registration: set required accessory metadata on root object (fixes missing `manufacturer` validation failures)
11+
* Matter registration: constrain bridged accessory display names to Matter nodeLabel length limits (fixes `Behaviors have errors` on long room/device names)
12+
* Pico Matter behavior: move to GenericSwitch state updates for button presses, expand Pico button map coverage, and include Pico4Button in Matter GenericSwitch registration mapping
13+
* add `options.excludedDeviceTypes` support to skip selected device types in both HAP and Matter registration paths (including removing cached accessories for explicitly excluded types)
14+
* excluded-device cleanup: in Matter mode, unregister excluded cached accessories from both HAP and Matter registries for deterministic removal
15+
* Pico button mapping robustness: improve `Pico3ButtonRaiseLower` alias resolution (including `Favorite` center-button naming variants) and skip unknown button definitions without failing whole-remote initialization
16+
* Matter command handling: add explicit handlers so WallDimmer and WallSwitch On/Off/Level commands always dispatch LEAP `GoToLevel` requests
17+
* Matter blind control: add `windowCovering.goToTiltPercentage` handler for Serena tilt-only blinds to map Matter tilt commands to LEAP blind tilt writes
18+
* Matter external-state sync: propagate unsolicited bridge updates back into Matter cluster state for WallDimmer (`onOff` + `levelControl`), WallSwitch (`onOff`), Serena tilt-only blinds (`windowCovering` tilt), and occupancy sensors (`occupancySensing`)
19+
* Pico Matter composed endpoint polish: use `BridgedNode` as Pico parent in composed mode and provide part `displayName` values to avoid undefined child labels in UI
920

10-
## [3.0.5](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/compare/v3.0.4...v3.0.5) (2026-04-27)
21+
### Maintenance
1122

23+
* align imports/file naming with ESM casing expectations and update docs output
24+
* bump Homebridge beta compatibility to `^2.0.0-beta.109` and refresh lint/tooling dependencies
1225

13-
### Bug Fixes
26+
**Full Changelog**: https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/compare/v3.1.0...v3.1.1
1427

15-
* cached accessory loss on Skipped, listener leak, inventory retry ([#227](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/issues/227)) ([4856be2](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/commit/4856be2accc95aec4a1cf778b4bef1610540ee0e))
28+
## [3.1.0](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/releases/tag/v3.1.0) (2026-04-29)
1629

30+
### Features
1731

32+
* configurable log verbosity (logLevel + buttonPressLogging) ([#228](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/issues/228)) ([40b1fd9](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/commit/40b1fd9116c2b8b4877d70001ddac4f6c3f7ee5c))
1833

19-
## [3.0.4](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/compare/v3.0.1...v3.0.4) (2026-04-25)
34+
**Full Changelog**: https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/compare/v3.0.5...v3.1.0
2035

36+
## [3.0.5](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/releases/tag/v3.0.5) (2026-04-27)
2137

2238
### Bug Fixes
2339

24-
* This accessory will not be registered. ([fb3c249](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/commit/fb3c2492cdcb30b2abe58aa9368be7e410d396c2))
25-
* This accessory will not be registered. ([#225](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/issues/225)) ([ff7cadf](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/commit/ff7cadfe493d38933740398a4a6f4faf6ad0b6f3))
40+
* cached accessory loss on Skipped, listener leak, inventory retry ([#227](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/issues/227)) ([4856be2](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/commit/4856be2accc95aec4a1cf778b4bef1610540ee0e))
2641

42+
**Full Changelog**: https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/compare/v3.0.4...v3.0.5
2743

44+
## [3.0.4](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/releases/tag/v3.0.4) (2026-04-25)
2845

29-
# Changelog
46+
### Bug Fixes
47+
48+
* This accessory will not be registered. ([fb3c249](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/commit/fb3c2492cdcb30b2abe58aa9368be7e410d396c2))
49+
* This accessory will not be registered. ([#225](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/issues/225)) ([ff7cadf](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/commit/ff7cadfe493d38933740398a4a6f4faf6ad0b6f3))
3050

31-
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
51+
**Full Changelog**: https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/compare/v3.0.3...v3.0.4
3252

3353
## [3.0.3](https://github.com/homebridge-plugins/homebridge-lutron-caseta-leap/releases/tag/v3.0.3) (2026-04-23)
3454

0 commit comments

Comments
 (0)