|
| 1 | +# Matter Clusters - Implementation, Usage and Support |
| 2 | + |
| 3 | +Matter clusters vary in their complexity and hence different implementation patterns have been developed to address different levels of complexity. What follows is a description of the different patterns, when to use them, how to implement them (for SDK contributors) and how to use them (for SDK consumers). A summary detailing the patterns used for different clusters is also provided. |
| 4 | + |
| 5 | +Note: `rs-matter` is still evolving and hence there may be needs that are not met by the patterns discussed here. One pattern of note that is currently missing is that for derived clusters. |
| 6 | + |
| 7 | +# Implementation patterns |
| 8 | + |
| 9 | +`rs-matter` utilises the Interface Definition Language (IDL) to auto-generate all Matter data types and traits for commands. This is the basis of all cluster implementation patterns discussed below. |
| 10 | + |
| 11 | +## Pattern A: Simple Handler |
| 12 | + |
| 13 | +**When to use**: Clusters with no spec-defined logic, purely data-driven, no interdependencies. |
| 14 | + |
| 15 | +**Characteristics**: |
| 16 | +- Read-only or simple read/write attributes |
| 17 | +- No complex state management |
| 18 | +- No coupling with other clusters |
| 19 | +- Examples: AirQuality, most measurement clusters |
| 20 | + |
| 21 | +### Implementation |
| 22 | + |
| 23 | +The SDK supports all clusters in this way and does not require any further implementation. |
| 24 | + |
| 25 | +### Usage |
| 26 | + |
| 27 | +1. Import the auto-generated cluster data types and trait using the `rs_matter::import!(<ClusterName>)` macro. |
| 28 | +2. Implement the `<cluster>::ClusterHandler` trait on a `<Cluster>Handler` struct. See code snippet below. |
| 29 | +3. Instantiate the `<Cluster>Handler` struct and chain it to the endpoint handler. |
| 30 | + |
| 31 | +```rust |
| 32 | +use rs_matter::{self, import}; |
| 33 | +import!(AirQuality); |
| 34 | + |
| 35 | +struct AirQualityHandler { |
| 36 | + sensor: SensorInterface, // Mock interface |
| 37 | +} |
| 38 | + |
| 39 | +impl air_quality::ClusterHandler for AirQualityHandler { |
| 40 | + const CLUSTER: rs_matter::dm::Cluster<'static> = air_quality::FULL_CLUSTER |
| 41 | + .with_revision(1) |
| 42 | + .with_attrs(with!( |
| 43 | + required; |
| 44 | + air_quality::AttributeId::AirQuality |
| 45 | + )); |
| 46 | + |
| 47 | + fn air_quality(&self, _ctx: impl ReadContext) -> Result<AirQualityEnum, Error> { |
| 48 | + Ok(self.sensor.read_aqi()) |
| 49 | + } |
| 50 | +} |
| 51 | + |
| 52 | +fn main() { |
| 53 | + // Instantiate cluster handler |
| 54 | + let air_quality_handler = AirQualityHandler::new(); |
| 55 | + |
| 56 | + // Build endpoint handler for device clusters |
| 57 | + let device_handler = EmptyHandler |
| 58 | + .chain( |
| 59 | + EpClMatcher::new(Some(1), Some(AirQualityHandler::CLUSTER.id)), |
| 60 | + Async(air_quality_handler.adapt()), |
| 61 | + ) |
| 62 | + // Continue chaining device clusters |
| 63 | +} |
| 64 | +``` |
| 65 | + |
| 66 | +## Pattern B: Implemented Handler |
| 67 | + |
| 68 | +**When to use**: |
| 69 | +- The Matter spec defines complex command logic (e.g., state machines, timing requirements) |
| 70 | +- The cluster has side effects beyond simple attribute updates |
| 71 | +- There are validation rules that must be enforced consistently |
| 72 | +- No device specific logic. |
| 73 | +- No coupling with other clusters |
| 74 | + |
| 75 | +The Simple Handler pattern works for all clusters, however, some clusters define complex Matter logic which would have to be implemented by every consumer. For these clusters, `rs-matter` implements a `<Cluster>Handler` struct matching the cluster name, e.g. `OnOffHandler`. This struct implements the corresponding `<Cluster>Handler` trait with all the Matter spec-defined logic. |
| 76 | + |
| 77 | +### Implementation |
| 78 | + |
| 79 | +1. Add the cluster to the `import!` macro call in `rs-matter/src/dm/clusters.rs`. |
| 80 | +2. Implement the cluster in `rs-matter/src/dm/clusters`, similar to the usage instructions in **A**. |
| 81 | + |
| 82 | + |
| 83 | + |
| 84 | +_Fig 1: Representative UML diagram for Pattern B_ |
| 85 | + |
| 86 | +### Usage |
| 87 | + |
| 88 | +1. `use rs_matter::dm::clusters::<cluster>::{<Cluster>Handler}`; |
| 89 | +2. Instantiate the `<Cluster>Handler` struct and chain it to the endpoint handler. |
| 90 | + |
| 91 | +```rust |
| 92 | +use rs_matter::dm::clusters::desc::{DescHandler} |
| 93 | + |
| 94 | +fn main() { |
| 95 | + // Instantiate cluster handler |
| 96 | + let descriptor_handler = DescHandler::new(); |
| 97 | + |
| 98 | + // Build endpoint handler for device clusters |
| 99 | + let device_handler = EmptyHandler |
| 100 | + .chain( |
| 101 | + EpClMatcher::new(Some(1), Some(DescHandler::CLUSTER.id)), |
| 102 | + Async(identify_handler.adapt()), |
| 103 | + ) |
| 104 | + // Continue chaining device clusters |
| 105 | +} |
| 106 | +``` |
| 107 | + |
| 108 | +## Pattern B1: Hooks-Based Handler |
| 109 | + |
| 110 | +**When to use**: |
| 111 | +- The Matter spec defines complex command logic (e.g., state machines, timing requirements) |
| 112 | +- The cluster has side effects beyond simple attribute updates |
| 113 | +- There are validation rules that must be enforced consistently |
| 114 | +- Device specific logic is required |
| 115 | +- No coupling with other clusters |
| 116 | + |
| 117 | +On top of patter B, this pattern provides a `<Cluster>Hooks` trait, delegating business logic implementation to the SDK consumer. For example; a method to switch the device on or off. Attributes that require persistence are also delegated to the SDK consumer, allowing them to use their own persistence strategy. |
| 118 | + |
| 119 | +### Implementation |
| 120 | + |
| 121 | +1. Follow all instruction for pattern B. |
| 122 | +2. Implement a `<Cluster>Hooks` trait for delegating business logic implementation to the SDK consumer. |
| 123 | + |
| 124 | + |
| 125 | + |
| 126 | +_Fig 2: Representative UML diagram for Pattern B1_ |
| 127 | + |
| 128 | +### Usage |
| 129 | + |
| 130 | +1. `use rs_matter::dm::clusters::<cluster>::{<Cluster>Handler, <Cluster>Hooks};` |
| 131 | +2. Implement `<Cluster>Hooks` for a `DeviceLogic` struct. |
| 132 | +3. Instantiate the `<Cluster>Handler` struct with the `DeviceLogic` struct and chain it to the endpoint handler. |
| 133 | + |
| 134 | +```rust |
| 135 | +use rs_matter::dm::clusters::fan_mode::{self, FanModeHandler, FanModeHooks, StepDirectionEnum}; |
| 136 | + |
| 137 | +// Create device logic functionality |
| 138 | +struct FanModeDeviceLogic { |
| 139 | + // Mock controller |
| 140 | + fan_controller: FanController |
| 141 | +} |
| 142 | + |
| 143 | +impl FanModeDeviceLogic { |
| 144 | + pub fn new() -> Self { |
| 145 | + Self { |
| 146 | + fan_controller: FanController::new(), |
| 147 | + } |
| 148 | + } |
| 149 | +} |
| 150 | + |
| 151 | +// Implement the Hooks trait |
| 152 | +impl FanModeHooks for FanModeDeviceLogic { |
| 153 | + // Set the cluster configuration |
| 154 | + const CLUSTER:crate::dm::Cluster<'static> = FanMode::FULL_CLUSTER |
| 155 | + .with_revision(4) |
| 156 | + .with_attrs(with!( |
| 157 | + required; |
| 158 | + fan_mode::AttributeId::FanMode |
| 159 | + | fan_mode::AttributeId::PercentSetting |
| 160 | + // ... |
| 161 | + )) |
| 162 | + .with_cmds(with!( |
| 163 | + fan_mode::CommandId::Step |
| 164 | + )); |
| 165 | + |
| 166 | + // Implement delegated logic |
| 167 | + fn step(&self, direction: StepDirectionEnum, wrap: bool, lowest_off: bool) { |
| 168 | + self.fan_controller(direction, wrap, lowest_off) |
| 169 | + } |
| 170 | +} |
| 171 | + |
| 172 | +fn main() { |
| 173 | + // Instantiate application cluster |
| 174 | + let fan_mode_handler = FanModeHandler::new(FanModeDeviceLogic::new()) |
| 175 | + |
| 176 | + // Build endpoint handler similar to patter B. |
| 177 | +} |
| 178 | + |
| 179 | +``` |
| 180 | +## Pattern C: Coupled clusters |
| 181 | + |
| 182 | +**When to use**: Clusters coupled with other clusters. |
| 183 | + |
| 184 | +Certain Matter clusters define coupling behaviour with other clusters. These behaviours often require custom logic, different from cluster commands. Hence, cluster handlers of coupled clusters will need to be aware of each other. |
| 185 | + |
| 186 | +### Implementation |
| 187 | + |
| 188 | +Structurally, pattern C is very similar to patter B with the following additions to the `<Cluster>Handler` |
| 189 | +- Attributes for optionally containing references to coupled clusters. See `level_control_handler` in the UML diagram below. |
| 190 | +- A public `init()` method that optionally takes references to the coupled handlers and validates the handler against the `<Cluster>Hooks::CLUSTER` configuration. For example, if LevelControl's OnOff feature is enabled, an OnOff cluster must be present |
| 191 | + |
| 192 | + |
| 193 | + |
| 194 | +### Usage |
| 195 | + |
| 196 | +1. `use rs_matter::dm::clusters::<cluster>::{<Cluster>Handler, <Cluster>Hooks};` |
| 197 | +2. Implement `<Cluster>Hooks` for a `DeviceLogic` struct. |
| 198 | +3. Instantiate the `<Cluster>Handler` struct with the `DeviceLogic` struct. |
| 199 | +4. Call `init(&<coupled cluster>)` on `<Cluster>Handler`. This initialises the cluster on startup by wiring the coupled handlers and validating the handler setup with the configuration. |
| 200 | +5. Chain the `<Cluster>Handler` to the endpoint handler. |
| 201 | + |
| 202 | +```rust |
| 203 | +// Implement device logic similar to pattern B. |
| 204 | + |
| 205 | +fn main() { |
| 206 | + |
| 207 | + // Instantiate device logic handlers |
| 208 | + let on_off_logic = OnOffDeviceLogic::new(); |
| 209 | + let level_control_logic = LevelControlDeviceLogic::new(); |
| 210 | + |
| 211 | + // Instantiate cluster handlers |
| 212 | + let on_off_handler = OnOffHandler::new(on_off_logic); |
| 213 | + let level_control_handler = LevelControlHandler::new(level_control_logic); |
| 214 | + |
| 215 | + // Initialize cluster handlers, coupling clusters if required. |
| 216 | + on_off_handler.init(Some(&level_control_handler))?; |
| 217 | + level_control_handler.init(Some(&on_off_handler))?; |
| 218 | + |
| 219 | + // Build endpoint handler similar to patter B. |
| 220 | +} |
| 221 | +``` |
| 222 | + |
| 223 | +# Cluster Support |
| 224 | + |
| 225 | +The following table summarises the implementation pattern types used for Matter v1.3 clusters. |
| 226 | +Non-provisional clusters are not included. |
| 227 | + |
| 228 | +All clusters are supported by pattern A. |
| 229 | +⚫ indicates that a pattern is not required. |
| 230 | +❌ indicates that a pattern is not yet implemented. |
| 231 | +Blank entries indicate that an assessment has not yet been made to identify if a pattern needs to be implemented. |
| 232 | + |
| 233 | +**Note** Some clusters support multiple patters, excluding pattern A. Consult the cluster documentation for further explanation on how to use them. |
| 234 | + |
| 235 | +**Note** Events are currently not supported. See issue [#36](https://github.com/project-chip/rs-matter/issues/36). |
| 236 | + |
| 237 | + |
| 238 | +| Cluster | A | B | B1 | C | notes | |
| 239 | +| ----------------------------------------------------- | -- | -- | -- | -- | ----- | |
| 240 | +| **System Clusters** Matter Specification v1.3.0.1 | | | | | | |
| 241 | +| | | | | | | |
| 242 | +| **9. System Model Specification** | | | | | | |
| 243 | +| Descriptor | ✅ | ✅ | ✅ | ⚫ | | |
| 244 | +| Binding | ✅ | | | | | |
| 245 | +| FixedLabel | ✅ | | | | | |
| 246 | +| UserLabel | ✅ | | | | | |
| 247 | +| AccessControl | ✅ | ✅ | ⚫ | ⚫ | | |
| 248 | +| BridgedDeviceBasicInformation | ✅ | ✅ | ⚫ | ⚫ | | |
| 249 | +| Actions | ✅ | | | | | |
| 250 | +| ProxyDiscovery | ✅ | | | | | |
| 251 | +| ProxyConfiguration | ✅ | | | | | |
| 252 | +| ProxyValid | ✅ | | | | | |
| 253 | +| IcdManagement | ✅ | | | | | |
| 254 | +| | | | | | | |
| 255 | +| **11. Service and Device Management** | | | | | | |
| 256 | +| BasicInformation | ✅ | ✅ | ⚫ | ⚫ | | |
| 257 | +| GroupKeyManagement | ✅ | | | | | |
| 258 | +| LocalizationConfiguration | ✅ | | | | | |
| 259 | +| TimeFormatLocalization | ✅ | | | | | |
| 260 | +| UnitLocalization | ✅ | | | | | |
| 261 | +| PowerSourceConfiguration | ✅ | ⚫ | ⚫ | ⚫ | | |
| 262 | +| PowerSource | ✅ | ⚫ | ⚫ | ⚫ | | |
| 263 | +| NetworkCommissioning | ✅ | ⚫ | ✅ | ⚫ | | |
| 264 | +| GeneralCommissioning | ✅ | ⚫ | ✅ | ⚫ | | |
| 265 | +| DiagnosticLogs | ✅ | | | | | |
| 266 | +| GeneralDiagnostics | ✅ | ✅ | ⚫ | ⚫ | | |
| 267 | +| SoftwareDiagnostics | ✅ | | | | | |
| 268 | +| ThreadNetworkDiagnostics | ✅ | ⚫ | ✅ | ⚫ | | |
| 269 | +| WiFiNetworkDiagnostics | ✅ | ⚫ | ✅ | ⚫ | | |
| 270 | +| EthernetNetworkDiagnostics | ✅ | ⚫ | ✅ | ⚫ | | |
| 271 | +| TimeSynchronization | ✅ | | | | | |
| 272 | +| OperationalCredentials | ✅ | ✅ | ⚫ | ⚫ | | |
| 273 | +| AdministratorCommissioning | ✅ | ✅ | ⚫ | ⚫ | | |
| 274 | +| OtaSoftwareUpdateProvider | ✅ | | | | | |
| 275 | +| OtaSoftwareUpdateRequestor | ✅ | | | | | |
| 276 | +| | | | | | | |
| 277 | +| **Application Clusters** Matter Application Clusters v1.3.0.1 | | | | | | |
| 278 | +| | | | | | | |
| 279 | +| **1. General** | | | | | | |
| 280 | +| Identify | ✅ | ⚫ | ⚫ | ⚫ | | |
| 281 | +| Groups | ✅ | | | | | |
| 282 | +| OnOff | ✅ | ⚫ | ✅ | ✅ | | |
| 283 | +| LevelControl | ✅ | ⚫ | ✅ | ✅ | | |
| 284 | +| BooleanState | ✅ | | | | | |
| 285 | +| ModeSelect | ✅ | | | | | |
| 286 | +| LowPower | ✅ | | | | | |
| 287 | +| WakeOnLan | ✅ | | | | | |
| 288 | +| Switch | ✅ | | | | | |
| 289 | +| OperationalState | ✅ | | | | | |
| 290 | +| | | | | | | |
| 291 | +| **2. Measurement and Sensing** | | | | | | |
| 292 | +| IlluminanceMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 293 | +| TemperatureMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 294 | +| PressureMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 295 | +| FlowMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 296 | +| RelativeHumidityMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 297 | +| OccupancySensing | ✅ | ⚫ | ⚫ | ⚫ | | |
| 298 | +| HepaFilterMonitoring | ✅ | ⚫ | ⚫ | ⚫ | | |
| 299 | +| ActivatedCarbonFilterMonitoring | ✅ | ⚫ | ⚫ | ⚫ | | |
| 300 | +| AirQuality | ✅ | ⚫ | ⚫ | ⚫ | | |
| 301 | +| CarbonMonoxideConcentrationMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 302 | +| CarbonDioxideConcentrationMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 303 | +| NitrogenDioxideConcentrationMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 304 | +| OzoneConcentrationMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 305 | +| Pm25ConcentrationMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 306 | +| FormaldehydeConcentrationMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 307 | +| Pm1ConcentrationMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 308 | +| Pm10ConcentrationMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 309 | +| TotalVolatileOrganicCompoundsConcentrationMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 310 | +| RadonConcentrationMeasurement | ✅ | ⚫ | ⚫ | ⚫ | | |
| 311 | +| SmokeCoAlarm | ✅ | | | | | |
| 312 | +| | | | | | | |
| 313 | +| **3. Lighting** | | | | | | |
| 314 | +| ColorControl | ✅ | | | | | |
| 315 | +| | | | | | | |
| 316 | +| **4. HVAC** | | | | | | |
| 317 | +| PumpConfigurationAndControl | ✅ | | | | | |
| 318 | +| Thermostat | ✅ | | | | | |
| 319 | +| FanControl | ✅ | ⚫ | ❌ | ⚫ | | |
| 320 | +| ThermostatUserInterfaceConfiguration | ✅ | | | | | |
| 321 | +| | | | | | | |
| 322 | +| **5. Closures** | | | | | | |
| 323 | +| DoorLock | ✅ | | | | | |
| 324 | +| WindowCovering | ✅ | | | | | |
| 325 | +| | | | | | | |
| 326 | +| **6. Media** | | | | | | |
| 327 | +| AccountLogin | ✅ | | | | | |
| 328 | +| ApplicationBasic | ✅ | | | | | |
| 329 | +| ApplicationLauncher | ✅ | | | | | |
| 330 | +| AudioOutput | ✅ | | | | | |
| 331 | +| Channel | ✅ | | | | | |
| 332 | +| ContentLauncher | ✅ | | | | | |
| 333 | +| KeypadInput | ✅ | | | | | |
| 334 | +| MediaInput | ✅ | | | | | |
| 335 | +| MediaPlayback | ✅ | | | | | |
| 336 | +| TargetNavigator | ✅ | | | | | |
| 337 | +| | | | | | | |
| 338 | +| **7. Robots** | | | | | | |
| 339 | +| RvcRunMode | ✅ | | | | | |
| 340 | +| RvcCleanMode | ✅ | | | | | |
| 341 | +| RvcOperationalState | ✅ | | | | | |
| 342 | +| | | | | | | |
| 343 | +| **8. Home Appliances** | | | | | | |
| 344 | +| TemperatureControl | ✅ | | | | | |
| 345 | +| DishwasherMode | ✅ | | | | | |
| 346 | +| DishwasherAlarm | ✅ | | | | | |
| 347 | +| LaundryWasherMode | ✅ | | | | | |
| 348 | +| LaundryWasherControls | ✅ | | | | | |
| 349 | +| RefrigeratorAndTemperatureControlledCabinetMode | ✅ | | | | | |
| 350 | +| RefrigeratorAlarm | ✅ | | | | | |
0 commit comments