Enable Controller Transport
Register the built-in matter_controller transport on each peer Matter node you want to control remotely. The SDK’s matterControllerControlHandler then sends RainMaker command-response requests to the controller node.
Requires @espressif/rainmaker-matter-sdk 3.1.0+. Cmd-resp create, poll, and parse are owned by the SDK; your app supplies controllerNodeId (and optionally timeoutSeconds).
Register transport on the peer
import type { ESPRMMatterNode } from "@espressif/rainmaker-matter-sdk";
// peerNode: ESPRMMatterNode (or base ESPRMNode with Matter params)
peerNode.availableTransports.matter_controller = {
type: "matter_controller",
metadata: {
controllerNodeId: "<CONTROLLER_RAINMAKER_NODE_ID>",
// timeoutSeconds: 60, // optional; default 60
},
};
| Field | Required | Description |
|---|---|---|
| type | Yes | Must be "matter_controller" |
| metadata.controllerNodeId | Yes | RainMaker node id of the RainMaker Controller |
| metadata.timeoutSeconds | No | Create/poll timeout in seconds (default 60) |
Default transportOrder on Matter nodes is already [matter_local, matter_controller]. Local discovery typically fills matter_local; your app fills matter_controller.
After registration, the same param APIs work for remote ops:
await powerParam.getValue(); // tries local, then controller
await powerParam.setValue(true);
How the SDK executes remote control
executeMatterControlwalksnode.transportOrder- For
matter_controller, it calls the built-in handler (unless overridden incustomTransportManagers) - Handler builds a CLI-parity payload and calls
user.createCmdRespRequesttargetingcontrollerNodeId - Polls until a terminal status (success / failure / timeout)
- Parses
response_datafor reads, or asserts success for write/invoke
Command IDs
| Operation | Cmd ID | Constant |
|---|---|---|
| Invoke | 4352 | MatterControllerCmdIds.INVOKE |
| Write | 4353 | MatterControllerCmdIds.WRITE |
| Read | 4354 | MatterControllerCmdIds.READ |
Payload shapes match RainMaker Matter controller CLI/REST conventions (attribute_paths for read; objects + request_payload for write/invoke). You normally do not build these yourself — getValue / setValue and cluster config drive the fields.
Key symbols
| Symbol | Role |
|---|---|
| executeMatterControl | Entry point used by ESPRMMatterDeviceParam |
| matterControllerControlHandler | Built-in remote transport |
| matterLocalControlHandler | Built-in local transport (adapter) |
| ESPMatterTransportMode | matter_local / matter_controller |
| DEFAULT_MATTER_TRANSPORT_ORDER | Default priority list |
| MatterControllerTransportMetadata | controllerNodeId, optional timeoutSeconds |
| matterTransportHandlers | Map of built-in mode → handler |
Remove transport
When the controller goes offline or is lost, remove the mode from peers so control does not keep failing into a dead hub:
delete peerNode.availableTransports.matter_controller;
In CDF-based apps, use your store’s transport update helper (Home app: handleNodeTransportUpdate(..., "remove")).
What could go wrong
| Symptom | Likely cause |
|---|---|
| Missing controller transport error | Empty or non-string controllerNodeId |
| Poll timeout | Controller offline; peer not known to hub; network/API delay |
| Unsupported operation | Param metadata missing attribute/command id for the op |
| Always uses local only | Local succeeds — expected; disable/remove matter_local only when testing remote |