pub struct Node { /* private fields */ }Expand description
Handle to one commissioned device. Obtain via
MatterController::node.
Implementations§
Source§impl Node
impl Node
Sourcepub async fn read(
&self,
paths: &[ReadPath],
) -> Result<Vec<(AttributePath, Value)>, Error>
pub async fn read( &self, paths: &[ReadPath], ) -> Result<Vec<(AttributePath, Value)>, Error>
Read attributes (concrete or wildcard paths). Returns the device’s
(path, value) reports keyed by the concrete paths it reports. Values
are raw Value; decode them with matter-clusters codecs.
A wildcard read (e.g. ReadPath::all) whose response spans multiple
ReportData chunks is reassembled transparently — every chunk is
solicited and merged through ReportAccumulator, so the result is the
device’s complete attribute set, not just the first chunk.
§Errors
Error::ControllerStopped, any connect/transport error, or
Error::InteractionModel if a response chunk cannot be parsed.
Sourcepub async fn read_events(
&self,
paths: &[EventPath],
filters: &[EventFilter],
) -> Result<Vec<EventReport>, Error>
pub async fn read_events( &self, paths: &[EventPath], filters: &[EventFilter], ) -> Result<Vec<EventReport>, Error>
Read events for the given (concrete or wildcard) event paths, optionally
filtered to events with number >= event_min (via EventFilter).
Returns every reported EventReport in wire order, reassembled across
chunks. Decode the event payloads with matter-clusters codecs.
Events are discrete records (not list attributes), so — unlike
read — there is no merge step: each chunk’s events are
concatenated in arrival order.
§Errors
Error::ControllerStopped, any connect/transport error, or
Error::InteractionModel if a response chunk cannot be parsed.
Sourcepub async fn write(
&self,
writes: &[(AttributePath, Value)],
) -> Result<Vec<(AttributePath, ImStatus)>, Error>
pub async fn write( &self, writes: &[(AttributePath, Value)], ) -> Result<Vec<(AttributePath, ImStatus)>, Error>
Write attributes. Each Value is TLV-encoded into the write payload.
Returns the per-path statuses the device reported.
Timed writes are handled transparently: if the device rejects the write
with NEEDS_TIMED_INTERACTION, the controller retries it as a timed
interaction and remembers the path so later writes skip the wasted attempt.
Use write_timed to force the timed path explicitly.
§Errors
As Self::read, plus Error::Codec if a value fails to encode.
Sourcepub async fn write_timed(
&self,
writes: &[(AttributePath, Value)],
timeout_ms: Option<u16>,
) -> Result<Vec<(AttributePath, ImStatus)>, Error>
pub async fn write_timed( &self, writes: &[(AttributePath, Value)], timeout_ms: Option<u16>, ) -> Result<Vec<(AttributePath, ImStatus)>, Error>
Like write but always performs a timed interaction:
a TimedRequest precedes the write (required by some attributes, e.g.
certain DoorLock settings). timeout_ms defaults to TIMED_DEFAULT_MS.
Plain write already auto-upgrades to timed on a
NEEDS_TIMED_INTERACTION rejection; use this when you want to force the
timed path explicitly (e.g. to avoid the first wasted round-trip, or for
testing).
§Errors
As Self::write.
Sourcepub async fn invoke(
&self,
path: CommandPath,
fields: Value,
) -> Result<InvokeResult, Error>
pub async fn invoke( &self, path: CommandPath, fields: Value, ) -> Result<InvokeResult, Error>
Invoke a command with raw Value fields (TLV-encoded into the payload).
§Errors
As Self::read, plus Error::Codec if the fields fail to encode
or the response fields cannot be decoded.
Sourcepub async fn invoke_tlv(
&self,
path: CommandPath,
fields_tlv: Vec<u8>,
) -> Result<InvokeResult, Error>
pub async fn invoke_tlv( &self, path: CommandPath, fields_tlv: Vec<u8>, ) -> Result<InvokeResult, Error>
Invoke a command with pre-encoded TLV command fields — e.g. the
Vec<u8> returned by
matter_clusters::gen::<cluster>::encode_<command>() — passed straight
into the wire payload, avoiding a decode-then-re-encode round trip
through Value.
fields_tlv must be the TLV-encoded command fields structure (an
anonymous-tagged struct), exactly what the generated encode_* helpers
produce; pass the empty-structure encoding for a no-field command.
§Errors
As Self::read, plus Error::Codec if the response fields cannot be
decoded.
Sourcepub async fn invoke_timed(
&self,
path: CommandPath,
fields: Value,
timeout_ms: Option<u16>,
) -> Result<InvokeResult, Error>
pub async fn invoke_timed( &self, path: CommandPath, fields: Value, timeout_ms: Option<u16>, ) -> Result<InvokeResult, Error>
Like invoke but always performs a timed interaction
(a TimedRequest precedes the command — required by some commands, e.g.
DoorLock lock/unlock). timeout_ms defaults to TIMED_DEFAULT_MS.
Plain invoke already auto-upgrades to timed on a
NEEDS_TIMED_INTERACTION rejection; use this to force the timed path.
§Errors
As Self::invoke.
Sourcepub async fn invoke_timed_tlv(
&self,
path: CommandPath,
fields_tlv: Vec<u8>,
timeout_ms: Option<u16>,
) -> Result<InvokeResult, Error>
pub async fn invoke_timed_tlv( &self, path: CommandPath, fields_tlv: Vec<u8>, timeout_ms: Option<u16>, ) -> Result<InvokeResult, Error>
Like invoke_tlv (pre-encoded TLV fields) but always
performs a timed interaction, mirroring
invoke_timed. timeout_ms defaults to
TIMED_DEFAULT_MS.
§Errors
As Self::invoke_tlv.
Sourcepub async fn announce_ota_provider(
&self,
provider_node_id: u64,
vendor_id: u16,
endpoint: u16,
) -> Result<(), Error>
pub async fn announce_ota_provider( &self, provider_node_id: u64, vendor_id: u16, endpoint: u16, ) -> Result<(), Error>
Trigger AnnounceOTAProvider on this device’s
OtaSoftwareUpdateRequestor (0x002A) cluster — telling the device that
we (provider_node_id) are an OTA Provider it may query for firmware.
Sent as a SimpleAnnouncement (the device decides when to act): it
resolves us via operational mDNS, opens a CASE session to us, and invokes
QueryImage.
provider_node_id is our own operational node id; vendor_id is our
vendor id; endpoint is the endpoint on us that hosts the
OtaSoftwareUpdateProvider (0x0029) cluster. The command itself is
invoked on the device’s endpoint 0.
This only fires the announcement — the provider-server half (serving the image over BDX) is a separate piece.
§Errors
Returns Error::InteractionModel if the invoke fails to build or parse,
or Error::Operational if the device rejects the command with a
non-success IM status or answers with an unexpected response command.
Sourcepub async fn set_utc_time(
&self,
utc_us: u64,
granularity: TimeGranularity,
) -> Result<(), Error>
pub async fn set_utc_time( &self, utc_us: u64, granularity: TimeGranularity, ) -> Result<(), Error>
Set the device’s wall-clock via TimeSynchronization.SetUTCTime
(0x0038 cmd 0x00). utc_us is microseconds since the Matter epoch
(2000-01-01 UTC); granularity describes its precision.
§Errors
Error::Operational if the device rejects it (e.g. it already has a
finer-granularity time), else an interaction error.
Sourcepub async fn set_time_zone(
&self,
entries: &[TimeZoneEntry],
) -> Result<bool, Error>
pub async fn set_time_zone( &self, entries: &[TimeZoneEntry], ) -> Result<bool, Error>
Set the device’s time zone via SetTimeZone (0x0038 cmd 0x02). Returns
the device’s DSTOffsetRequired flag (whether you must also call
Self::set_dst_offset).
§Errors
Error::Operational on device rejection or a malformed response, else
an interaction error.
Sourcepub async fn set_dst_offset(
&self,
entries: &[DstOffsetEntry],
) -> Result<(), Error>
pub async fn set_dst_offset( &self, entries: &[DstOffsetEntry], ) -> Result<(), Error>
Set the device’s DST offsets via SetDSTOffset (0x0038 cmd 0x04).
§Errors
Error::Operational on device rejection, else an interaction error.
Sourcepub async fn read_utc_time(&self) -> Result<Option<u64>, Error>
pub async fn read_utc_time(&self) -> Result<Option<u64>, Error>
Read the device’s current UTCTime (0x0038 attr 0x00). None if the
device reports a null time (clock not set).
§Errors
An interaction error if the read fails.
Sourcepub async fn read_binding(
&self,
endpoint: u16,
) -> Result<Vec<BindingTarget>, Error>
pub async fn read_binding( &self, endpoint: u16, ) -> Result<Vec<BindingTarget>, Error>
Read this device’s Binding list on endpoint (0x001E attr 0x0000) —
the targets it is wired to send to.
§Errors
An interaction error if the read fails.
Sourcepub async fn write_binding(
&self,
endpoint: u16,
targets: &[BindingTarget],
) -> Result<Vec<(AttributePath, ImStatus)>, Error>
pub async fn write_binding( &self, endpoint: u16, targets: &[BindingTarget], ) -> Result<Vec<(AttributePath, ImStatus)>, Error>
Replace this device’s Binding list on endpoint with targets (a
full-list, fabric-scoped write). Returns the per-path device status.
§Errors
An interaction error, or a per-path device status.
Sourcepub async fn register_icd_client(
&self,
monitored_subject: u64,
client_type: IcdClientType,
) -> Result<IcdRegistration, Error>
pub async fn register_icd_client( &self, monitored_subject: u64, client_type: IcdClientType, ) -> Result<IcdRegistration, Error>
Register the controller as a check-in client with this ICD
(IcdManagement.RegisterClient, 0x0046 cmd 0x00). Generates a fresh
16-byte symmetric key, registers our commissioner node id as the
CheckInNodeID, persists an IcdRegistration
(so the check-in listener can later verify this device’s Check-Ins), and
returns it. monitored_subject is the subject the ICD watches for us
(usually our node id).
§Errors
Error::Operational on RNG failure or device rejection; an interaction
error; or a persistence error.
Sourcepub async fn unregister_icd_client(&self) -> Result<(), Error>
pub async fn unregister_icd_client(&self) -> Result<(), Error>
Unregister the controller from this ICD (UnregisterClient, cmd 0x02),
using our commissioner node id as the CheckInNodeID.
§Errors
Error::Operational on device rejection, else an interaction error.
Sourcepub async fn stay_active_request(
&self,
stay_active_ms: u32,
) -> Result<u32, Error>
pub async fn stay_active_request( &self, stay_active_ms: u32, ) -> Result<u32, Error>
Ask this ICD to stay in active mode for at least stay_active_ms
(StayActiveRequest, cmd 0x03). Returns the device’s promised active
duration (ms).
§Errors
Error::Operational on device rejection or a malformed response, else
an interaction error.
Sourcepub async fn commissioning_window_status(&self) -> Result<WindowStatus, Error>
pub async fn commissioning_window_status(&self) -> Result<WindowStatus, Error>
Read AdministratorCommissioning WindowStatus, AdminFabricIndex, and
AdminVendorId from endpoint 0. Returns a snapshot of the current
commissioning-window state.
§Errors
An interaction error if the read fails.
Sourcepub async fn list_fabrics(&self) -> Result<Vec<FabricDescriptor>, Error>
pub async fn list_fabrics(&self) -> Result<Vec<FabricDescriptor>, Error>
Read the device’s Fabrics list (every fabric it is commissioned onto).
§Errors
An interaction error if the read fails.
Sourcepub async fn write_acl(
&self,
entries: &[AclEntry],
) -> Result<Vec<(AttributePath, ImStatus)>, Error>
pub async fn write_acl( &self, entries: &[AclEntry], ) -> Result<Vec<(AttributePath, ImStatus)>, Error>
Write the device’s AccessControl.Acl list to exactly entries.
Refuses (before sending) any list that would strip our own administrative
access (Error::AclWouldLockOut). Small lists go in one
WriteRequestMessage (byte-identical to a normal write); larger lists are
chunked (ReplaceAll+AppendItem) without ever sending an empty ReplaceAll.
ACL writes are NOT timed (the spec does not require TimedRequest for
AccessControl.Acl); however, if the device unexpectedly rejects the write
with NEEDS_TIMED_INTERACTION the controller’s timed-auto-upgrade will
transparently retry on the single-chunk path (the same bytes are safe to
re-send because the whole list is idempotent). The multi-chunk path fails
cleanly on a 0xc6 rejection (the ChunkedWrite pending does not carry
a timed_payload).
§Errors
Error::AclWouldLockOut if entries contains no Administer/CASE entry
covering our commissioner node id; no bytes are sent to the device in that
case. Otherwise returns an interaction error or a per-path device status.
Sourcepub async fn read_acl(&self) -> Result<Vec<AclEntry>, Error>
pub async fn read_acl(&self) -> Result<Vec<AclEntry>, Error>
Read the device’s AccessControl.Acl list (the ACL entries on this fabric).
§Errors
An interaction error if the read fails.
Sourcepub async fn open_commissioning_window(
&self,
opts: OpenWindowOpts,
) -> Result<CommissioningWindow, Error>
pub async fn open_commissioning_window( &self, opts: OpenWindowOpts, ) -> Result<CommissioningWindow, Error>
Open an enhanced commissioning window so a second admin can commission
this device onto its own fabric. Generates a fresh passcode/salt/
discriminator, computes the PAKE verifier, and returns the onboarding
payload (manual pairing code, plus QR when opts.vendor_id/product_id
are set). The AdminComm command is sent as a timed invoke.
§Errors
Returns Error::CommissioningWindowRejected if the device rejects it,
or a crypto/RNG/interaction error.
Sourcepub async fn open_basic_commissioning_window(
&self,
timeout_s: u16,
) -> Result<(), Error>
pub async fn open_basic_commissioning_window( &self, timeout_s: u16, ) -> Result<(), Error>
Open a basic commissioning window (reuses the device’s original passcode — no new onboarding payload). Timed invoke.
§Errors
Error::CommissioningWindowRejected on device rejection, else an
interaction error.
Sourcepub async fn revoke_commissioning(&self) -> Result<(), Error>
pub async fn revoke_commissioning(&self) -> Result<(), Error>
Revoke any open commissioning window. Timed invoke. Returns Ok(())
even if no window was open (the device reports WindowNotOpen, which is
surfaced as Error::CommissioningWindowRejected only on a hard IM
failure).
§Errors
Error::CommissioningWindowRejected on device rejection.
Sourcepub async fn remove_fabric(&self, fabric_index: u8) -> Result<(), Error>
pub async fn remove_fabric(&self, fabric_index: u8) -> Result<(), Error>
Remove a fabric from the device by its fabric_index.
Reads CurrentFabricIndex first and refuses to remove our OWN fabric
(that would sever this CASE session and orphan persisted state) with
Error::WouldRemoveSelf. There is intentionally no force override.
§Errors
Error::WouldRemoveSelf if fabric_index is our own;
Error::Operational if the device does not return a readable
CurrentFabricIndex — the call fails without invoking RemoveFabric in
that case (fail-closed on a destructive operation);
Error::OperationalCredentialsRejected if the device rejects it (e.g.
7 InvalidFabricIndex); else an interaction error.
Sourcepub async fn update_fabric_label(&self, label: &str) -> Result<(), Error>
pub async fn update_fabric_label(&self, label: &str) -> Result<(), Error>
Update the label of OUR fabric on the device (UpdateFabricLabel acts on
the accessing fabric; there is no index argument).
§Errors
Error::OperationalCredentialsRejected if the device rejects it
(e.g. 9 LabelConflict); else an interaction error.
Sourcepub async fn add_group(
&self,
endpoint: u16,
group_id: u16,
name: &str,
) -> Result<(), Error>
pub async fn add_group( &self, endpoint: u16, group_id: u16, name: &str, ) -> Result<(), Error>
Add the device endpoint to a group (Groups.AddGroup). The endpoint then
joins the group’s multicast address and accepts group commands.
§Errors
Error::GroupCommandRejected on a non-success status; else interaction error.
Sourcepub async fn remove_group(
&self,
endpoint: u16,
group_id: u16,
) -> Result<(), Error>
pub async fn remove_group( &self, endpoint: u16, group_id: u16, ) -> Result<(), Error>
Remove the device endpoint from a group (Groups.RemoveGroup).
§Errors
Error::GroupCommandRejected on a non-success status; else interaction error.
Sourcepub async fn write_group_key_set(&self, set: &GroupKeySet) -> Result<(), Error>
pub async fn write_group_key_set(&self, set: &GroupKeySet) -> Result<(), Error>
Provision a group key set on the device via KeySetWrite
(GroupKeyManagement cluster, endpoint 0). The epoch key is the
group’s symmetric key material. Returns Ok(()) on a bare
Success status from the device.
KeySetWrite is NOT a timed command — the plain invoke path is used.
§Errors
Error::GroupCommandRejected if the device returns a non-success IM
status (e.g. ResourceExhausted). An interaction or transport error is
surfaced as its corresponding Error variant.
Sourcepub async fn write_group_key_map(
&self,
entries: &[GroupKeyMapEntry],
) -> Result<Vec<(AttributePath, ImStatus)>, Error>
pub async fn write_group_key_map( &self, entries: &[GroupKeyMapEntry], ) -> Result<Vec<(AttributePath, ImStatus)>, Error>
Write the device’s GroupKeyMap list (binds group ids to key sets).
Small lists go in one WriteRequestMessage (byte-identical to a normal
write); larger lists are chunked (ReplaceAll+AppendItem) without ever
sending an empty ReplaceAll. There is no lockout guard — GroupKeyMap
has no self-lock concern unlike AccessControl.Acl.
GroupKeyMap writes are NOT timed (the spec does not require
TimedRequest); however, if the device unexpectedly rejects the write with
NEEDS_TIMED_INTERACTION the controller’s timed-auto-upgrade will
transparently retry on the single-chunk path.
§Errors
Returns an interaction error or a per-path device status from the device.
Sourcepub async fn subscribe(
&self,
attrs: &[ReadPath],
events: &[EventPath],
min_interval: u16,
max_interval: u16,
) -> Result<Subscription, Error>
pub async fn subscribe( &self, attrs: &[ReadPath], events: &[EventPath], min_interval: u16, max_interval: u16, ) -> Result<Subscription, Error>
Subscribe to attribute reports for attrs and/or event reports for
events (concrete or wildcard paths) on a single subscription. The
device sends the priming values/events, then steady-state changes within
[min_interval, max_interval] seconds. Await
SubscriptionEvents — both
Report (attributes) and Event (events) — via
Subscription::next.
Pass an empty slice for either to subscribe to only the other. The subscription auto-resubscribes transparently on staleness/session loss, re-requesting the same attribute and event paths.
§Errors
Error::ControllerStopped if the owning task stopped, or any
connect / transport / interaction-model error while establishing the
subscription.