fix: format sensor readings + name multi-function devices by role#66
Conversation
Two device-presentation fixes surfaced commissioning a multi-sensor node
(HomePod mini: temperature + humidity), plus the architecture call on
device grouping.
Display (the "6 decimal places" report):
- Add a ClusterHandler.format_kv() hook that turns a {state: value} dict
into an Indigo updateStatesOnServer kvlist. The sensor base overrides it
to attach uiValue + decimalPlaces, so a reading renders as "21.5 °C"
instead of the raw float (a round(x,2) still shows 21.340000000001
without it). device_sync routes every handler-produced state write —
live updates, node events, battery fan-out, and create-time priming —
through handler.format_kv(). Per-sensor precision/units set for
temperature, humidity, illuminance, pressure, flow, CO2, PM2.5, TVOC;
boolean sensors pass through untouched.
Naming (the "(endpoint 1)" report):
- Name a node's devices "{name} - {role}" (e.g. "HomePod - Temperature")
via a device-type -> role map, instead of the opaque Matter endpoint
number. The endpoint number remains only as a fallback (unmapped type)
or to disambiguate genuinely identical siblings (a 4-outlet strip ->
"- Switch 1..4"). Bridged children with their own identity unaffected.
- Stamp dev.model = product name on every device so a node's siblings
share one Model-column value — the grouping Indigo offers short of a
Device Factory (which is dialog-driven and a poor fit for the automated
commission/reconcile path; standalone devices stay first-class for
triggers, control pages, and Domio).
Tests: +sensor formatting, +role naming/model stamping; updated the Patio
multi-endpoint naming expectations. 773 pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR refactors device naming to use handler role labels and introduces handler-driven state formatting. Multi-function nodes now display as " - " (e.g., "HomePod - Temperature"), and state updates are formatted per-handler with numeric display hints like decimal places and unit suffixes instead of using a single generic conversion path. ChangesRole-Based Naming and Handler Formatting
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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
🤖 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/Info.plist`:
- Line 23: Replace the existing PluginVersion string "2026.2.26" with a new,
unused version (for example "2026.2.27") so the CI version-check won't fail;
locate the "2026.2.26" entry in Info.plist and update that string to the bumped
version.
🪄 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: b9a4490e-3b16-4610-97de-c2fc836d796e
📒 Files selected for processing (8)
indigo-matter.indigoPlugin/Contents/Info.plistindigo-matter.indigoPlugin/Contents/Server Plugin/device_sync.pyindigo-matter.indigoPlugin/Contents/Server Plugin/matter_handlers/air_quality.pyindigo-matter.indigoPlugin/Contents/Server Plugin/matter_handlers/base.pyindigo-matter.indigoPlugin/Contents/Server Plugin/matter_handlers/sensors.pytests/test_bridges.pytests/test_device_sync.pytests/test_sensors.py
| <string>1.0.0</string> | ||
| <key>PluginVersion</key> | ||
| <string>2026.2.25</string> | ||
| <string>2026.2.26</string> |
There was a problem hiding this comment.
Version 2026.2.26 already exists as a git tag; the CI version-check workflow will fail.
The version-check pipeline confirms that v2026.2.26 is already tagged in the repository. Reusing a version number violates release hygiene and breaks the CI gate. Increment PluginVersion to an unused version (e.g., 2026.2.27).
🔖 Proposed fix to bump to the next available version
- <string>2026.2.26</string>
+ <string>2026.2.27</string>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <string>2026.2.26</string> | |
| <string>2026.2.27</string> |
🤖 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/Info.plist` at line 23, Replace the
existing PluginVersion string "2026.2.26" with a new, unused version (for
example "2026.2.27") so the CI version-check won't fail; locate the "2026.2.26"
entry in Info.plist and update that string to the bumped version.
Source: Pipeline failures
Surfaced commissioning a multi-sensor Matter node (HomePod mini: temperature + humidity).
1. Readings showed 6 decimal places
Sensor handlers rounded the value, but it reached Indigo as a bare
{key, value}— and Indigo renders aNumberstate at full float precision without auiValue/decimalPlaces(around(x, 2)still displays as21.340000000001). The plugin set neither anywhere.ClusterHandler.format_kv()hook converts a{state: value}dict into an IndigoupdateStatesOnServerkvlist. The sensor base overrides it to attachuiValue+decimalPlaces.device_syncnow routes every handler-produced state write (live updates, node events, node-scoped battery fan-out, create-time priming) throughhandler.format_kv().21.5 °C, Humidity47.5%, Illuminance123 lux, Pressure1013 hPa, Flow2.5 m³/h, CO₂ppm, PM2.5µg/m³. Boolean sensors (motion/contact) pass through untouched.2. Devices named "(endpoint 1)"
{name} - {role}(e.g. HomePod - Temperature / HomePod - Humidity) via a device-type → role map. Endpoint-number naming is kept only as a fallback (unmapped type) or to disambiguate genuinely identical siblings (a 4-outlet strip →- Switch 1..4). Bridged children with their own identity are unaffected.dev.modelis stamped with the product name on every device, so a node's siblings share one Model column value.3. Master device + children — investigated, kept standalone
Indigo's only master/children mechanism is the Device Factory (shared
model+subType, tabbed editor), which is dialog-driven and fights the automated Domio-commission + WebSocket-reconcile creation path — and the children stay independent devices for triggers/control-pages/Domio regardless. Standalone devices + role naming + shared model column deliver the grouping without the factory machinery.Notes
🤖 Generated with Claude Code
Summary by CodeRabbit