The extensions channel: health, geo and logs.
Extensions are optional capabilities a device offers and the platform turns
on. The device joins the extensions topic with what it can do and the
versions it speaks, and the join reply names the subset the platform wants
attached — a device may support an extension the product has switched off.
join payload #{<<"health">> => <<"0.0.1">>, ...} device -> server
join reply [<<"health">>, <<"geo">>] server -> device
Every event on this topic is prefixed with the extension it belongs to, so
health:check is check for health. Splitting on the first colon is the
whole of the routing — the rest of the event name may contain colons of its
own, as geo:location:request does.
nh_agent.
state() = #{enabled := [binary()], attached := [binary()]}
| attach/2 | Record the attach list from the join reply, and confirm it. |
| attached/1 | |
| available/1 | The join payload: what this device offers, and at which version. |
| enabled/1 | |
| handle_event/3 | Route an event to its extension. |
| is_attached/2 | |
| new/1 | Build the registry from configuration. |
| scope/1 | Split a scoped event into its extension and the event within it. |
Record the attach list from the join reply, and confirm it.
Anything the platform did not name stays detached, and anything named that this device does not actually offer is ignored rather than trusted.
The confirmations are the point. NervesHub does not start an extension when it puts it in the attach list — it waits for the device to answer<key>:attached, and only then runs the extension's own attach, which
is what asks for the first health report and the first location. A device
that attaches silently is a device the platform never speaks to again, and
nothing about that looks like an error from either end.
attached(X1::state()) -> [binary()]
available(X1::state()) -> map()
The join payload: what this device offers, and at which version.
enabled(X1::state()) -> [binary()]
Route an event to its extension.
Returns actions rather than performing them:{push, ScopedEvent, Payload}
to answer immediately, {resolve_location} for the one that needs the
network. An event for an extension that is not attached is dropped — the
platform asking for something it never turned on is not something to answer.
is_attached(Name::binary(), X2::state()) -> boolean()
new(Config::map()) -> state()
Build the registry from configuration.
extensions => [health, geo, logging], or all. Nothing is enabled by
default: each one costs traffic a device may not want to spend.
scope(Scoped::binary()) -> {binary(), binary()} | error
Split a scoped event into its extension and the event within it.
Generated by EDoc