0.3.0 Track A: attribute cache + publish_* wired#33
Merged
Conversation
publish_reading and publish_alert no longer call unimplemented!().
The wohl bridge now keeps a thread-safe HashMap of the latest
Matter-encoded value per (endpoint, cluster, attribute) — mediating
the push/pull boundary between wohl's dispatcher (which produces
events) and rs-matter's DataModel (which polls for current values
when a controller subscribes).
What's in this slice
src/cache.rs (new)
- `AttributeKey { endpoint_id: u32, cluster_id: u32,
attribute_id: u32 }` — wohl-side endpoint id; the Matter
endpoint-id mapping (DESIGN.md §7.1) happens at the
DataModel handler boundary in slice 6.
- `AttributeValue` enum with variants matching Matter wire
encodings: Bool (BooleanState), Int16 (Temperature centi-°C),
Int64 (ActivePower milliwatts), Float32 (concentration
clusters).
- `AttributeCache` = `Mutex<HashMap<...>>`; thread-safe set/get;
sharable as `Arc<AttributeCache>` so the future commissioning
thread can hold its own handle.
- 4 unit tests covering empty / set+get / overwrite / distinct
keys.
src/conversion.rs (new)
- `convert_reading(kind, value: i64, mapping)` and
`convert_alert(kind, Option<i64>, mapping)` apply the
DESIGN.md §7.4 contract:
Temperature: i64 centi-°C → Int16 (saturating cast)
Power: i64 watts → Int64 mW (× 1000 saturating)
CO2/PM2.5/VOC: i64 → Float32 (`as` cast)
BooleanState (numeric reading): bool = (value != 0)
BooleanState (alert, no value): always true (alert IS trigger)
- 10 unit tests including saturation, mapping correctness,
alert-without-value semantics, water-leak polarity.
src/rs_matter.rs
- `RsMatterBridge` gains an `Arc<AttributeCache>` field +
`.cache()` accessor.
- publish_reading: lookup mapping → convert → set cache.
- publish_alert: lookup mapping → convert (None branch skips
cache update for numeric clusters without a value) → derive
endpoint_id from zone_id/contact_id/circuit_id → set cache.
- 6 new integration tests verify publish path roundtrips
(Temperature, WaterLeak, PowerSpike, HealthMiss drop,
Freeze-without-value skip, Arc sharing).
src/lib.rs
- Declares cache + conversion modules (not feature-gated;
both compile + test cleanly without rs-matter).
What's NOT in this slice (still)
The cache is written but NOT YET READ by rs-matter's
`DataModelHandler`. A commissioned controller subscribing to a
bridged attribute today gets... nothing back from the bridge
endpoints (the commissioning_only_handler in commissioning.rs
has only the root endpoint). Slice 6 wires:
- Per-zone/contact/circuit Matter endpoint registration with
the right device-type descriptor (ContactSensor 0x0015,
WaterLeakDetector 0x0043, etc. per DESIGN.md §2),
- A custom DataModelHandler that pulls from this cache when
rs-matter asks for an attribute value,
- Endpoint-id allocation policy decision (DESIGN.md §7.1
open question).
Until then, the cache infrastructure stands on its own merits:
publish_* is non-panicking, the conversion contract is unit-
tested, and the cache is observable from the bridge owner for
debugging or test-rig wiring.
Oracles green
cargo +1.87.0 fmt -p wohl-matter-bridge --check OK
cargo +1.87.0 clippy -p wohl-matter-bridge -D warnings OK (no features)
cargo +1.87.0 clippy ... --features rs-matter-backend OK
cargo +1.87.0 test -p wohl-matter-bridge --lib 34/34 (feature off; was 19, +15 cache+conversion+wiring)
cargo +1.87.0 test ... --features rs-matter-backend --lib 43/43 (feature on; was 22, +21)
cargo +1.87.0 test --workspace 21 test binaries pass
cargo kani -p wohl-alert 4/4 harnesses
spar analyze (StarterHome.Deployed) 0 errors
rivet validate PASS (1 pre-existing warning)
Verified line: untouched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
RsMatterBridge::publish_readingandpublish_alertno longer callunimplemented!(). They now translate the wohl event to the right Matter cluster + attribute (via the cluster mapping table from PR #27 + B1 fix), apply the unit conversion (per DESIGN.md §7.4), and write the typed value into a thread-safe in-memory cache.This is the push side of the push/pull mediation the architecture critic flagged in PR #29 and that the AADL
c_attrcomment documents. The pull side (rs-matterDataModelHandlerreading from this cache when a controller subscribes) is the next slice — same one that registers per-zone/contact/circuit endpoints with the right device-type descriptors.What this PR ships
src/cache.rs(new)AttributeKey,AttributeValue { Bool / Int16 / Int64 / Float32 },AttributeCache=Mutex<HashMap<...>>withset/get/len/is_empty. Shareable asArc<AttributeCache>. 4 unit tests.src/conversion.rs(new)convert_reading+convert_alertimplementing the DESIGN.md §7.4 table: Temperature saturating cast, Power × 1000 (saturating), Concentrationas f32, BooleanState bool. Alert-without-value semantics:Bool(true)on boolean clusters (the alert IS the trigger),Noneon numeric clusters (caller skips cache update). 10 unit tests.src/rs_matter.rsRsMatterBridgegainsArc<AttributeCache>field +.cache()accessor.publish_*are now real: lookup mapping → convert → set cache. 6 new integration tests.src/lib.rscache+conversionmodules (not feature-gated; both work without rs-matter).Test counts
Oracles
What's NOT in this PR (still)
0x0015, WaterLeakDetector0x0043, etc. per DESIGN.md §2),DataModelHandlerthat pulls from this cache when rs-matter asks for an attribute value,u16space, tagged-high-byte or register-on-demand).publish_*is non-panicking, the conversion contract is unit-tested, and the cache is observable from the bridge owner for test rigs or operator debug commands.Verified line: still untouched
Zero edits to
crates/wohl-{leak,temp,air,door,power,alert,ota,fw-door-bench}/,proofs/verus/, orfuzz/. Kani 4/4 onwohl-alert.Test plan
DataModelHandler+ endpoint registration + cache-pull integration.🤖 Generated with Claude Code