Cluster Config and Device Params
Cluster config tells the app how to render a Matter device on the control screen — which features show up (Power, Brightness, Mode, …), what control to use (toggle, slider, dropdown), and how values map to Matter attributes or commands.
Without it, the SDK still knows the device’s clusters from cloud metadata, but the UI has little to bind to. With it, Matter metadata becomes the same kind of device params your RainMaker control screens already use.
Reference: Home app cluster.config.ts — register the clusters your product exposes, then pass as clusterConfig in ESPRMMatterBase.configure().
What the user sees
| Layer | Role |
|---|---|
| Matter metadata | What the device actually has (On/Off, Level, Color, …) |
| Cluster config | How your app presents those clusters as UI features |
| Device params | Bound by the control screen like normal RainMaker params |
| getValue / setValue | Read/write live state (Local or Remote Control) |
So cluster config is not a separate “Matter UI framework” — it is the bridge from Matter clusters → params the existing app UI can render and control.
How a node becomes a control screen
When you load node details (getNodesWithDetails() / getNodeDetails()):
- SDK reads metadata.Matter (endpoints + clusters + attribute IDs).
- For each non-root endpoint and each cluster, it looks up the cluster ID in clusterConfig.
- Registered cluster → one UI param per entry in that cluster’s params list (e.g. Power, Brightness).
- Unregistered cluster → a generic fallback param (works for control, poor labels/UI until you add config).
Live values are not filled at transform time. The control screen (or subscription) calls getValue() / listens for updates to show current state.
Register cluster config
import { ESPRMMatterBase } from "@espressif/rainmaker-matter-sdk";
import { myClusterConfig } from "./cluster.config";
ESPRMMatterBase.configure({
// ... other config
clusterConfig: myClusterConfig,
});
You can also call registerClusterConfig() later to add or merge entries.
Keys use hex cluster IDs (e.g. "0x6" On/Off, "0x8" Level Control, "0x54" RVC Run Mode).
Only register clusters you want as named controls on the device screen. You do not need every Matter cluster in the Spec.
What each config entry drives in the UI
| Field | Effect on the control screen |
|---|---|
| clusterId / name | Which Matter cluster this maps to |
| name | Feature label / param key (e.g. Power, runMode) |
| uiType | Widget: toggle, slider, dropdown, lock control, … |
| dataType | bool, int, string, … |
| valueAttribute | Which Matter attribute holds the current value |
| optionsAttribute | Source for dropdown / mode choices |
| resolver | Raw Matter value ↔ what the UI shows and sends |
| writeAsCommand / matterCommandId | Tap/action uses command invoke instead of attribute write |
The SDK also sets clusterId, endpointId, and matterAttributeId on each param so Controlling can target the right Matter path.
Example: mode dropdown on the device screen
import type { ClusterConfigMap } from "@espressif/rainmaker-matter-sdk";
export const myClusterConfig: ClusterConfigMap = {
"0x54": {
clusterId: 0x54,
name: "RVC Run Mode",
defaultOptions: [
{ value: "idle", label: "Idle", rawMode: 0 },
{ value: "cleaning", label: "Cleaning", rawMode: 1 },
],
params: [
{
name: "runMode",
type: "enum",
valueAttribute: 0x1,
optionsAttribute: 0x0,
uiType: "esp.ui.dropdown",
dataType: "string",
resolver: {
decodeOptions: (supportedModes) => {
/* map device modes to dropdown options */
return [];
},
decodeValue: (raw, rawModes) => "idle",
encodeValue: (uiValue, rawModes) => rawModes?.[uiValue] ?? null,
},
},
],
},
};
After loading the node, the control screen finds the same param it would for any RainMaker device:
const device = matterNode.devices?.[0];
const runMode = device?.params?.find((p) => p.name === "runMode");
// UI binds to runMode.uiType / options; user change → runMode.setValue(...)
Resolvers (UI ↔ Matter)
Matter attributes are often numbers or structured blobs. Resolvers keep the control screen simple:
| Resolver | Role |
|---|---|
| decodeOptions | Build dropdown / mode choices (or use defaultOptions) |
| decodeValue | Raw Matter read → value shown in the UI |
| encodeValue | UI value from setValue() → payload for write / invoke |
If a cluster is not in config
The SDK still creates a param so control can work, but with empty name and a generic type — weak for a polished control screen. Add a cluster config entry when you want a proper label, widget, and resolver.
Related
- Matter Nodes — listing nodes and cluster helpers
- Controlling — how params are read/written (local or remote)
- Getting Started — clusterConfig in configure
- Home app config:
cluster.config.ts