matter-clusters
Typed Matter cluster definitions: per-cluster attribute/command/struct codecs,
feature flags, enums (with Unknown(n) forward-compat) and bitmaps. The modules
under gen/ are generated from a pinned @matter/model dump by the xtask
codegen tool.
Part of matter-rust. Milestone 7.
What this crate does
- Provides encode/decode functions for the attributes, commands, and structs of 47 Matter clusters (mandatory and optional attributes), as Matter TLV.
- Models cluster enums with an
Unknown(n)variant (forward-compatible decode), feature maps asbitflags, and nullable fields asNullable<T>(distinct fromOption<T>). - Generates all of the above from the spec model, gated against drift in CI.
What this crate does not do
- It is not a full cluster set — only the 47 clusters below today. More arrive in later batches.
- It does not provide generic or wildcard attribute access, or manufacturer-specific typed codecs. Reading arbitrary attributes a device publishes is the Interaction Model layer / high-level controller (see Reading attributes beyond these clusters).
- It performs no IO and no session/transport work — it only encodes/decodes bytes.
Status
0.3.0. The 10 M7 clusters are generated and byte-parity
tested against matter.js 0.16.11 (test-vectors/clusters/): BasicInformation,
Descriptor, Identify, OnOff, LevelControl, ColorControl, OccupancySensing,
TemperatureMeasurement, RelativeHumidityMeasurement, and DoorLock (Aliro
features excluded). The M9-A2.1 pilot batch adds 5 read-only clusters —
IlluminanceMeasurement, PressureMeasurement, FlowMeasurement, BooleanState, and
Switch — decode-smoke tested (they reuse datatype shapes already byte-parity
proven by the M7 set). The M9-A2.2 energy batch adds 4 more read-only clusters —
PowerSource, ElectricalPowerMeasurement, ElectricalEnergyMeasurement, and
AirQuality — decode-smoke tested, with a byte-parity vector for the new nested
MeasurementAccuracyStruct (a struct holding a list-of-struct with optional
fields). The M9-A2.3 actuator batch adds 5 read/write clusters — Thermostat,
FanControl, ThermostatUserInterfaceConfiguration, PumpConfigurationAndControl,
and WindowCovering — roundtrip (decode(encode(x)) == x) and decode-smoke
tested, with a byte-parity vector for the list-typed AtomicRequest command.
The M9-A2.4 utility batch adds 5 more clusters — Groups, Binding,
GeneralDiagnostics, FixedLabel, and UserLabel — decode-smoke tested (incl. the
Groups command encoders and the global FabricIndex typedef), with a byte-parity
vector for the new struct-with-byte-fields shape (GeneralDiagnostics
NetworkInterface: a hwadr bytes field, a keyword Type field, and
byte-string-element lists).
The M9-A2.5 management batch adds 4 more clusters — AccessControl,
GroupKeyManagement, AdministratorCommissioning, and OtaSoftwareUpdateRequestor —
codecs only (their protocol logic — ACL evaluation, group multicast,
window-open orchestration, OTA — belongs to later milestones). Decode-smoke
tested (incl. ACL entries whose subject-id subjects decode as u64), with a
byte-parity vector for the recursive list-of-struct command encode
(AccessControl.ReviewFabricRestrictions, whose Arl is a list of structs each
carrying a nested list-of-struct). Those five batches took the library from 10
clusters to 33.
Four more were added one at a time, each by the milestone that needed it:
OperationalCredentials (M9-D2), OtaSoftwareUpdateProvider (M9-F1 — command-only,
so it generates no attribute codecs), TimeSynchronization (M9-G-a), and
IcdManagement (M9-G-c). That is 37.
The concentration measurement family (Matter 1.2), reported missing by an
external adopter in #112, adds the 10 read-only clusters that bring the total
to the 47 generated today —
CarbonMonoxide (0x040C), CarbonDioxide (0x040D), NitrogenDioxide (0x0413),
Ozone (0x0415), Pm25 (0x042A), Formaldehyde (0x042B), Pm1 (0x042C),
Pm10 (0x042D), TotalVolatileOrganicCompounds (0x042E), and Radon (0x042F)
ConcentrationMeasurement. They derive from one base cluster and so share a
single shape, which is why they are added as a family rather than piecemeal.
That shape carries this crate's first float (single/FLOAT32) attributes,
so alongside the per-cluster decode-smoke tests it gets a matter.js byte-parity
vector, an explicit round-trip over the binary32 edges (signed zero, subnormals,
infinities, NaN — compared by bits), and a proptest round-trip drawn uniformly
from the whole binary32 bit space. A single attribute accepts a FLOAT32
element only, matching chip's strict TLVReader::Get(float&).
For any attribute not covered by these typed codecs — optional,
manufacturer-specific, or a cluster not in this list — the generic Value path
in matter-controller remains the universal answer. Hand-written support lives
in types (Nullable<T>), error (ClusterError), and datatypes
(SemanticTagStruct).
Usage
use ;
// Command payload — embed in an InvokeRequest.
let _toggle = encode_toggle;
// Attribute roundtrips: encode a value, decode it back.
let tlv = encode_on_time;
assert_eq!;
let tlv = encode_node_label;
assert_eq!;
# Ok::
See crates/matter-commissioning/examples/control_onoff.rs for an end-to-end
read / toggle / write against a real device (runbook:
docs/runbooks/m7.5-control-onoff.md).
Generated code
cargo xtask codegen writes src/gen/<cluster>.rs (+ globals.rs, mod.rs)
from xtask/model/clusters.json. Do not edit the generated files by hand —
change the emitter (xtask/src/codegen/) and regenerate. cargo xtask codegen --check gates drift in CI.
Reading attributes beyond these clusters
Typed codecs cover these clusters' mandatory and optional attributes. To read
attributes of other clusters, or manufacturer-specific attributes, use the
generic Interaction Model path: matter_interaction::parse_report_data yields
(AttributePath, matter_codec::Value) for any attribute without a typed codec.
A high-level generic + wildcard read API (and more typed clusters) arrive in
later milestones.
Correctness posture
- Byte-parity against matter.js 0.16.11 TLV combinators
(
test-vectors/clusters/): every generated codec round-trips to the captured oracle. proptestroundtrips over attribute values.- A
cargo-fuzztarget over the generated decoders (weekly CI). cargo xtask codegen --checkfails CI if the committedsrc/gen/drifts from what the emitter +clusters.jsonproduce.
Cryptographic posture
matter-clusters performs no cryptography. It is pure data encoding.
MSRV
Rust 1.88 (workspace MSRV). See the workspace CHANGELOG.md.
License
Apache 2.0. See LICENSE at the workspace root.