Boolean State Configuration (0x0080): sensitivity state + Set Sensitivity action#87
Conversation
…action (closes #85) Aqara FP300-class sensors expose a writable sensitivity level via Matter 1.3's Boolean State Configuration cluster. New merge-only BooleanStateConfigHandler maps CurrentSensitivityLevel (0x0000) onto a sensitivityLevel state on the endpoint's sensor device (motion + contact types), primed at creation and updated live. New 'Set Sensitivity Level' device action — the plugin's first custom action — with a dynamic level menu driven by the device's live SupportedSensitivityLevels (friendly Low/Standard/High labels when 3), writing via the existing MatterWrite path with an optimistic echo gated on the server's RPC confirmation. Registering the handler also retires the 0x0080 leftover-cluster log from #81. 868 tests (40 new). Version 2026.5.0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Arj5R66d73tc3PMPvHS65Z
|
Warning Review limit reached
Next review available in: 43 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds Matter BooleanStateConfiguration (0x0080) cluster support: a new non-primary handler surfaces CurrentSensitivityLevel into existing motion/contact sensor devices, DeviceSync caches SupportedSensitivityLevels per endpoint, and a new plugin action with a dynamic picker lets users set sensitivity level via Matter attribute writes. Includes XML config updates, tests, and a version bump. ChangesSensitivity Level Feature
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant Plugin
participant DeviceSync
participant MatterWrite
participant IndigoDevice
User->>Plugin: actionSetSensitivityLevel(action, dev)
Plugin->>DeviceSync: sensitivity_levels_supported(node_id, endpoint_id)
Plugin->>Plugin: validate level against supported range
Plugin->>MatterWrite: write CurrentSensitivityLevel attribute
Plugin->>Plugin: _send_matter_command(action, dev)
alt write succeeds
Plugin->>IndigoDevice: updateStateOnServer(sensitivityLevel, level)
else write fails
Plugin-->>User: no state echo
end
sequenceDiagram
participant MatterNode
participant BooleanStateConfigHandler
participant IndigoDevice
MatterNode->>BooleanStateConfigHandler: CurrentSensitivityLevel attribute update
BooleanStateConfigHandler->>BooleanStateConfigHandler: _parse_sensitivity(value)
BooleanStateConfigHandler->>IndigoDevice: check declared states for sensitivityLevel
alt state declared
BooleanStateConfigHandler->>IndigoDevice: update sensitivityLevel state
else not declared
BooleanStateConfigHandler-->>MatterNode: no-op
end
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
indigo-matter.indigoPlugin/Contents/Server Plugin/device_sync.py (1)
165-170: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winConsider clearing
_sensitivity_supportedentries on node decommission.
delete_noderemoves entries from_indexbut never touches_sensitivity_supported, unlike_power_source_epswhich is popped per node-id when empty. This means cached sensitivity-level counts for a decommissioned node's endpoints persist indefinitely, and could resurface incorrect data if the node id is ever reused by a different device (Matter allows arbitrary node-id assignment by the commissioner).♻️ Suggested cleanup in delete_node
self.logger.warning("could not delete Indigo device %s: %s", dev_id, exc) deleted_set = set(deleted) # Drop successfully-deleted devices from the nested index new_index: dict[tuple[int, int], dict[str, int]] = {} for key, type_map in self._index.items(): if key[0] == target: remaining = {tid: did for tid, did in type_map.items() if did not in deleted_set} if remaining: new_index[key] = remaining else: new_index[key] = type_map self._index = new_index + self._sensitivity_supported = { + k: v for k, v in self._sensitivity_supported.items() if k[0] != target + } return deletedAlso applies to: 1023-1050
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@indigo-matter.indigoPlugin/Contents/Server` Plugin/device_sync.py around lines 165 - 170, Clear stale sensitivity cache entries when a node is decommissioned. Update delete_node in device_sync.py to remove any _sensitivity_supported entries associated with the deleted node-id, similar to how _power_source_eps is cleaned up when empty. Use the existing node/endpoint bookkeeping in _index and the _sensitivity_supported dict so cached SupportedSensitivityLevels values cannot persist after a node is removed and later be reused incorrectly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@indigo-matter.indigoPlugin/Contents/Server` Plugin/Actions.xml:
- Around line 17-18: The setSensitivityLevel action is using an invalid
multi-device deviceFilter value, since deviceFilter only accepts one filter
string and cannot scope to both motion and contact sensors at once. Update the
Action entry in Actions.xml by either splitting it into two separate Action
definitions for setSensitivityLevel, one for matterMotionSensor and one for
matterContactSensor, or by replacing it with a single broader filter if a shared
one exists. Use the setSensitivityLevel Action and its deviceFilter attribute to
locate and adjust the mapping.
---
Nitpick comments:
In `@indigo-matter.indigoPlugin/Contents/Server` Plugin/device_sync.py:
- Around line 165-170: Clear stale sensitivity cache entries when a node is
decommissioned. Update delete_node in device_sync.py to remove any
_sensitivity_supported entries associated with the deleted node-id, similar to
how _power_source_eps is cleaned up when empty. Use the existing node/endpoint
bookkeeping in _index and the _sensitivity_supported dict so cached
SupportedSensitivityLevels values cannot persist after a node is removed and
later be reused incorrectly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 76030a29-bafd-4c92-b504-7f855b75346a
📒 Files selected for processing (11)
indigo-matter.indigoPlugin/Contents/Info.plistindigo-matter.indigoPlugin/Contents/Server Plugin/Actions.xmlindigo-matter.indigoPlugin/Contents/Server Plugin/Devices.xmlindigo-matter.indigoPlugin/Contents/Server Plugin/device_sync.pyindigo-matter.indigoPlugin/Contents/Server Plugin/matter_handlers/boolean_state_config.pyindigo-matter.indigoPlugin/Contents/Server Plugin/matter_handlers/registry.pyindigo-matter.indigoPlugin/Contents/Server Plugin/plugin.pytests/test_boolean_state_config.pytests/test_device_sync.pytests/test_device_zoo.pytests/test_plugin_module.py
…ate guard Live-verified on jarvis: Indigo's deviceFilter takes exactly one filter; both "a, b" and "a,b" comma forms yield an empty device picker. Fall back to deviceFilter="self" and reject devices without the sensitivityLevel state in the action callback (new test). 869 tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Arj5R66d73tc3PMPvHS65Z
…ve-verified) deviceFilter="self.matterMotionSensor" works; comma lists don't. Ship two scoped <Action> entries sharing one callback — motion (FP300 pairing) + contact (spec BooleanState pairing) — so the picker never lists plugs/relays. State guard kept as defense-in-depth. 869 tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Arj5R66d73tc3PMPvHS65Z
Summary
Closes #85. First live catch of the #81 leftover-cluster diagnostic, now implemented: sensors with Matter 1.3 Boolean State Configuration (Aqara FP300 presence on the house fabric — node 0x2D ep1, co-located with OccupancySensing) get a
sensitivityLevelstate and a Set Sensitivity Level device action (the plugin's first custom action).BooleanStateConfigHandler(electrical.py shape, endpoint-scoped) — attr 0x0000 →sensitivityLevelon the endpoint's sensor device; declared onmatterMotionSensor+matterContactSensor(spec pairs 0x0080 with BooleanState; Aqara pairs it with occupancy — both covered).SupportedSensitivityLevels(cached per reconcile, lock-guarded): 3 levels → Low/Standard/High labels; otherwise generic. Level semantics treated as opaque ordinals — the spec text for which end is 'most sensitive' isn't publicly verifiable; to be confirmed empirically on the FP300.MatterWritepath (thermostat-proven); optimistic state echo only after matter-server confirms the RPC (_send_matter_commandnow returns bool — verified genuine confirmation, not fire-and-forget).Review
Single code-reviewer pass (proportionate): no findings; bool-return semantics, cache thread-safety, and test genuineness all positively verified.
Open live-verification items (pre-merge, on jarvis)
deviceFilter="self.matterMotionSensor, self.matterContactSensor"comma-list — no workspace precedent; if the action doesn't appear on the FP300 motion device, fall back todeviceFilter="self"(callbacks already guard).Tests / version
868 passing (40 new: handler unit, device_sync priming/live/log-retirement, zoo fixture, menu + action callbacks). 2026.4.2 → 2026.5.0 (user-visible feature).
🤖 Generated with Claude Code
https://claude.ai/code/session_01Arj5R66d73tc3PMPvHS65Z
Summary by CodeRabbit
New Features
Bug Fixes
Chores