Reference — Configuration
Every configuration option. For why these exist, see explanation.md; for tasks, the how-to guides; for the envelope/topic surface, see messaging-interface.md; for complete worked configs, see sample-configurations.md.
Config source
Section titled “Config source”On HOST the bridge reads one JSON document. That same file feeds two things: the edgecommons runtime
loads it as the standard -c FILE config (and its top-level messaging section is the --transport MQTT
payload — the device bus), and the bridge reads its own component.instances[] from it (the site
broker). On GREENGRASS the config comes from the deployment’s GG_CONFIG (-c GG_CONFIG) and the device
bus is Nucleus IPC, so no messaging section is needed. The file is validated against the canonical
edgecommons config schema at startup, and config.schema.json at the repo root
models this bridge’s own component.instances[] shape for edgecommons component validate.
The bridge uses the standard edgecommons CLI (no synthesis): --platform <P> --transport <T> … -c <SOURCE> … -t <thing>. On HOST: --platform HOST --transport MQTT <config> -c FILE <config> -t <thing>.
On GREENGRASS: --platform GREENGRASS --transport IPC -c GG_CONFIG -t <thing>. -c/--config takes a source
keyword first (FILE, GG_CONFIG, …), not a bare path.
Top-level sections
Section titled “Top-level sections”| Section | Required | Purpose |
|---|---|---|
messaging |
HOST only | The device-local MQTT bus the runtime connects to on HOST (via --transport MQTT <path>); the relay shares that same connection. Also the request-deadline knob. Not needed on GREENGRASS (the device bus is IPC). |
component |
yes | Carries instances[]; the entry with a siteBroker declares the site broker and all relay knobs. |
hierarchy |
optional | UNS enterprise-hierarchy level names; the last level is the device. Absent ⇒ ["device"]. |
identity |
optional | Values for every hierarchy level except the last (the resolved thing name). Together with hierarchy these set the bridge’s own identity, its real state topic, and the private site LWT topic derived from it. |
heartbeat |
optional | The bridge’s own state keepalive ({enabled, intervalSecs}; on by default, 5 s). |
metricEmission |
optional | Routes the relay counters (target: messaging publishes them on the UNS metric class — the sample setting). |
logging |
optional | Standard edgecommons logging (console info by default). |
topic |
optional | includeRoot (default false); insert the site level after ecv1 on a multi-site broker (effective only for a multi-level hierarchy). |
The top level tolerates other standard edgecommons sections (tags, etc.); unknown sections in the bridge’s
own parse are ignored (forward compatibility).
There is deliberately no
component.namein config. The canonical schema allows onlyglobal/instancesundercomponent; the component’s full name (com.mbreissi.edgecommons.UnsBridge) is supplied by the runtime builder, never by config. (The Greengrassrecipe.yamldefault config does setcomponent.name, but that value is not what names the component.)
messaging (the HOST device bus)
Section titled “messaging (the HOST device bus)”The standard edgecommons messaging section, used on HOST (on GREENGRASS the device bus is IPC and this
section is not needed). Only the fields the bridge relies on are called out here.
| Key | Type | Default | Definition |
|---|---|---|---|
local |
object | required on HOST | The device broker: host, port, clientId (+ credentials/TLS as any edgecommons broker). The runtime connects with the configured clientId; the relay shares that same connection. |
requestTimeoutSeconds |
number | 30 |
The framework request-deadline. Paired with reply.ttlSecs — see below. |
component.instances[] — the site entry
Section titled “component.instances[] — the site entry”The bridge scans component.instances[] for its site entry: the entry with id: "site", or — when none
carries that id — the single entry that declares a siteBroker. Two entries with a siteBroker and none
named "site" is an error (ambiguous); no site entry at all is an error.
| Key | Type | Default | Definition |
|---|---|---|---|
id |
string | required | Instance id; "site" selects this entry explicitly. |
siteBroker |
object | required | The site broker endpoint — the library mqttBroker shape (below). Maps onto the reused provider’s local slot; there is deliberately no northbound broker on the site link. |
uplink |
object | see §uplink | Per-class uplink policy: enables, rate caps, and the evt replay buffer. |
reply |
object | see §reply | The reply correlation-map knobs. |
maxHops |
number | 4 |
Hop-tag cap (loop protection). |
queue |
object | see §queue | Per-class subscription queue depths. |
siteBroker
Section titled “siteBroker”The library mqttBroker shape (identical to any edgecommons broker config).
| Key | Type | Definition |
|---|---|---|
host |
string | Site broker host. |
port |
number | Site broker port (e.g. 1883 plaintext, 8883 TLS). |
clientId |
string | MQTT client id on the site broker — unique per bridge. |
credentials |
object | mTLS: { certPath, keyPath, caPath }. Omit for a plaintext/anonymous broker (dev only). |
The site Last-Will is not a configuration object. The bridge derives it from its own resolved state topic and
registers a protobuf EdgeCommons state envelope with status:"UNREACHABLE" and QoS 1 on the site broker. A configured
component.instances[site].lwt is rejected at startup because a typo here would break the console
reachability contract.
uplink — per-class policy
Section titled “uplink — per-class policy”uplink.classes is a map keyed by class token. Every knob is optional; the defaults below are applied by the
policy engine, not by config. Unknown members inside a class are tolerated (forward compatibility).
| Key (per class) | Type | Default | Definition |
|---|---|---|---|
enabled |
bool | true for the six consumer classes, false for app |
Whether the class is relayed. A disabled class’s messages drop + count (dropped_disabled); a disabled app also means its filter is never subscribed. |
maxRatePerSec |
number | — (unlimited) | Token-bucket refill rate (messages/second). Over-cap traffic drops + counts (dropped_rate). 0 forwards only the initial burst, then drops forever (prefer enabled: false). |
burst |
number | 2 × maxRatePerSec |
Token-bucket capacity; the bucket starts full, so an initial burst of up to burst passes immediately. |
bufferWhileDisconnected |
object | see below | The evt disconnect replay buffer. Honored for evt only — on any other class it is ignored with a warning. |
bufferWhileDisconnected:
| Key | Type | Default | Definition |
|---|---|---|---|
enabled |
bool | true |
Whether evt buffers (rather than drops) while the site link is down. |
maxMessages |
number | 1000 |
Buffer bound; overflow drops the oldest (evt_buffer_dropped). 0 disables buffering. |
Class tokens accepted by uplink.classes: state, cfg, evt, metric, data, log, app. (cmd is
never uplinked and has no policy slot.)
logdefault nuance: the design recommends shippinglogoff, and the sample config sets"log": { "enabled": false }— but the code default forlogis on (matching the pre-policy relay behavior). Set it explicitly if you care.
reply — the correlation map
Section titled “reply — the correlation map”| Key | Type | Default | Definition |
|---|---|---|---|
ttlSecs |
number | 60 |
Correlation-entry TTL. Paired knob: 60 = 2 × messaging.requestTimeoutSeconds (30). If you raise requestTimeoutSeconds, raise this in step. |
maxPending |
number | 1024 |
In-flight entry bound; overflow evicts the oldest (counted as expired). 0 is treated as 1. |
The TTL sweep runs every min(ttlSecs/4, 5 s), floored at 100 ms.
queue — per-class subscription depths
Section titled “queue — per-class subscription depths”| Key | Type | Default | Definition |
|---|---|---|---|
data |
number | 512 |
Queue depth for the data class subscription (deep — bursty telemetry). |
default |
number | 64 |
Queue depth for every other subscription (shallow), including the downlink cmd. |
Overflow drops at the provider (with a warning). Per-reply device-bus subscriptions use a fixed depth of 1 (first-reply-wins).
Identity, the state topic, and the derived site LWT
Section titled “Identity, the state topic, and the derived site LWT”hierarchy.levels names the UNS enterprise tree, deepest (the device) last; identity supplies every level’s
value except the last (which is the resolved thing name from -t/--thing). These determine the bridge’s
own identity element and its real state topic:
"hierarchy": { "levels": ["site", "device"] },"identity": { "site": "dallas" }// with -t gw-01 → state topic ecv1/gw-01/uns-bridge/main/stateAt startup the bridge derives that exact topic (gg.uns().topic(State)) and registers the site Last-Will on
it. There is no separate LWT topic to configure or cross-check.
Precedence & defaults summary
Section titled “Precedence & defaults summary”- Site entry selection:
id == "site"▸ the solesiteBrokerentry ▸ error. - Class enable:
uplink.classes.<class>.enabled▸ built-in (truefor the six,falseforapp). - Rate cap: absent ⇒ unlimited;
burstabsent ⇒ 2×rate. evtbuffer: absent ⇒ on/1000; on a non-evtclass ⇒ ignored + warn.maxHopsabsent ⇒ 4;reply.ttlSecsabsent ⇒ 60,reply.maxPendingabsent ⇒ 1024;queue.dataabsent ⇒ 512,queue.defaultabsent ⇒ 64.
Complete example
Section titled “Complete example”The bundled test-configs/config.json — device broker :1883, site broker
:1884 (the dual-EMQX dev layout):
{ "hierarchy": { "levels": ["site", "device"] }, "identity": { "site": "dallas" },
"messaging": { "local": { "host": "localhost", "port": 1883, "clientId": "uns-bridge-local" }, "requestTimeoutSeconds": 30 },
"heartbeat": { "enabled": true, "intervalSecs": 5 }, "metricEmission": { "target": "messaging" },
"component": { "instances": [ { "id": "site", "siteBroker": { "host": "localhost", "port": 1884, "clientId": "uns-bridge-site" }, "uplink": { "classes": { "state": { "enabled": true }, "cfg": { "enabled": true }, "evt": { "enabled": true, "bufferWhileDisconnected": { "maxMessages": 1000 } }, "metric": { "enabled": true, "maxRatePerSec": 50 }, "data": { "enabled": true, "maxRatePerSec": 200, "burst": 400 }, "log": { "enabled": false }, "app": { "enabled": false } } }, "reply": { "ttlSecs": 60, "maxPending": 1024 }, "maxHops": 4, "queue": { "data": 512, "default": 64 } } ] }}Current limits
Section titled “Current limits”- The device-bus transport follows the platform. HOST uses MQTT (the default
standalonefeature); GREENGRASS uses Nucleus IPC (thegreengrassfeature, a Linux-only C-FFI build layered onstandalonefor the site MQTT provider). The relay shares whichever provider the runtime resolved. - The CLI is the standard edgecommons CLI.
-c/--configrequires a source keyword (FILE,GG_CONFIG, …); a bare path is not accepted. - The site LWT is private and derived.
component.instances[site].lwtis rejected; configure only the site broker endpoint and relay policy.