Tracks active Matter subscriptions for a session.
Pure functional module — caller threads state through.
Each subscription monitors a set of attribute paths with min/max
reporting intervals. The due_reports/2 function checks which
subscriptions need a periodic report based on elapsed time.
Example
mgr = SubscriptionManager.new()
{sub_id, mgr} = SubscriptionManager.subscribe(mgr,
[%{endpoint: 1, cluster: 6, attribute: 0}],
0, # min_interval (seconds)
60 # max_interval (seconds)
)
# Later, check for due reports
due = SubscriptionManager.due_reports(mgr, System.monotonic_time(:second))
Summary
Functions
Check if any subscriptions are active.
Check which subscriptions are due for a report check.
Get a subscription by ID.
Create a new empty SubscriptionManager.
Record that a report was checked for a subscription.
Record that a report was actually sent for a subscription.
Register a subscription for the given attribute paths.
List all active subscriptions.
Check if a subscription is throttled by min_interval.
Remove a subscription by ID.
Remove all subscriptions. Used for session cleanup.
Types
@type subscription() :: %{ id: non_neg_integer(), paths: [map()], min_interval: non_neg_integer(), max_interval: non_neg_integer(), last_report_at: integer(), last_sent_at: integer() | nil, last_values: map() }
@type t() :: %MatterEx.IM.SubscriptionManager{ next_id: non_neg_integer(), subscriptions: %{required(non_neg_integer()) => subscription()} }
Functions
Check if any subscriptions are active.
@spec due_reports(t(), integer()) :: [{non_neg_integer(), [map()]}]
Check which subscriptions are due for a report check.
Returns a list of {sub_id, paths} tuples when either the minimum
reporting interval allows change detection or the maximum interval has
elapsed. The caller decides whether to send a report after comparing values.
@spec get(t(), non_neg_integer()) :: subscription() | nil
Get a subscription by ID.
@spec new() :: t()
Create a new empty SubscriptionManager.
@spec record_report(t(), non_neg_integer(), map(), integer()) :: t()
Record that a report was checked for a subscription.
Updates last_report_at and last_values for change detection.
Does NOT update last_sent_at — use record_sent/3 for that.
@spec record_sent(t(), non_neg_integer(), map(), integer()) :: t()
Record that a report was actually sent for a subscription.
Updates last_sent_at, last_report_at, and last_values.
@spec subscribe(t(), [map()], non_neg_integer(), non_neg_integer()) :: {non_neg_integer(), t()}
Register a subscription for the given attribute paths.
Returns {subscription_id, updated_state}.
@spec subscriptions(t()) :: [subscription()]
List all active subscriptions.
@spec throttled?(t(), non_neg_integer(), integer()) :: boolean()
Check if a subscription is throttled by min_interval.
Returns true when the time since the last sent report is less than
min_interval, meaning a change-triggered report should be suppressed.
@spec unsubscribe(t(), non_neg_integer()) :: t()
Remove a subscription by ID.
Remove all subscriptions. Used for session cleanup.