Configuration
17 min
every setting can be supplied as an environment variable or as a field in a json file environment variables override file values key by key the marketplace application exposes the settings most deployments need as form parameters, and applies the defaults below to the rest settings it does not expose are set in the configuration file, or as an environment variable on a container you manage yourself multiple brokers, publish filters, client id and timeout overrides, and buffer file rotation limits the node reads config/config json under its configuration path, which is /le sparkplug/data unless config path says otherwise a missing file is not an error — the node then runs on environment values and defaults alone only edge api token has no default configuration is read once at startup there is no reload — restart the container to apply a change litmus edge connection environment variable config json field default effect edge api token edge api token none, required authenticates to the litmus edge rest and graphql apis edge external edge external false true when the node runs outside litmus edge edge hostname edge hostname the detected docker gateway address of the litmus edge instance required when edge external=true edge docker gateway ip edge docker gateway ip read from the container's default route docker gateway used to reach litmus edge from inside the device edge access account api key edge access account api key none api account key in external mode the node builds tls\ //admin \<key>@\<edge hostname> 4222 from it nats url nats url generated explicit nats broker url overrides the generated one config path config path /le sparkplug/data base path for the configuration file and persistent state sparkplug identity environment variable config json field default effect group id group id le sparkplug sparkplug group id node id node id the container hostname sparkplug node id, unique within the group / , + , # , and whitespace in either value are replaced with , because those characters are reserved in mqtt topics mqtt broker these fields describe a single broker and are ignored when mqtt servers is set for the certificate workflow, see deployment # environment variable config json field default effect mqtt url mqtt servers\[] url tcp\ //mqtt 1883 broker url schemes tcp , ssl , mqtt , mqtts mqtt username or mqtt user mqtt servers\[] user empty broker username mqtt password mqtt servers\[] password empty broker password mqtt ca cert mqtt servers\[] ca cert empty base64 encoded ca certificate mqtt client cert mqtt servers\[] client cert empty base64 encoded client certificate mqtt client key mqtt servers\[] client key empty base64 encoded client private key mqtt skip cert verify mqtt servers\[] skip cert verify false accepts any broker certificate mqtt client and failover environment variable config json field default effect mqtt servers mqtt servers unset json array of broker objects replaces the single broker fields, and enables failover across brokers mqtt client id mqtt client id \<group id> \<node id> mqtt client identifier mqtt client id suffix mqtt client id suffix empty appended to the client id after mqtt connect timeout mqtt connect timeout 30s time allowed for a connection attempt mqtt write timeout mqtt write timeout 3s time allowed for a publish to complete mqtt keepalive mqtt keepalive 30 seconds of inactivity before a keepalive packet diagnostics environment variable config json field default effect obs enabled obs enabled true serves /metrics and /healthz obs addr obs addr 9090 bind address for those endpoints le logging level le logging level info one of debug , info , warn , error invalid values most invalid values are logged and replaced with the default, so the node still starts timeouts, keepalive, log level, and the store and forward numbers all behave that way these, by contrast, stop startup condition message edge api token missing or blank \[edge api token] is undefined edge external not a boolean \[edge external] is invalid primary host support not a boolean \[primary host support] is invalid le store and forward not a boolean \[le store and forward] is invalid obs enabled not a boolean \[obs enabled] is invalid dh enabled or dt enabled not a boolean \[dh enabled] is invalid , \[dt enabled] is invalid a filter pattern is not a valid glob \[dh devices include] … , and the equivalent for the other three mqtt servers is not valid json \[invalid json array \[mqtt servers]] mqtt servers contains an entry without a url \[mqtt servers] contains no valid server urls edge hostname missing in external mode \[edge hostname] is undefined for external mode edge access account api key missing in external mode with no nats url \[edge access account api key] is undefined for external mode when \[nats url] is unset configuration file { "edge api token" "\<litmus edge api token>", "group id" "plant1", "node id" "line1", "mqtt" { "servers" \[ { "url" "ssl //broker a example com 8883", "user" "sparkplug", "password" "\<password>", "ca cert" "\<base64 ca certificate>" }, { "url" "tcp\ //broker b example com 1883" } ], "client id suffix" "line1", "connect timeout" "30s", "write timeout" "3s", "keepalive" 30 }, "primary host support" true, "primary host id" "scada host", "le store and forward" true, "le ttl duration" 24, "devicehub" { "enabled" true, "exclude" \["test "] }, "digital twins" { "enabled" true }, "obs enabled" true, "le logging level" "info" } primary host application a sparkplug host application publishes its own state to the broker so edge nodes know whether anyone is listening with primary host support enabled, the node publishes nothing until that host reports online, and stops the moment it reports offline use it when a single host application owns the data; leave it off when several applications consume the node independently environment variable config json field default effect primary host support primary host support false waits for the host application before publishing primary host id primary host id le spb when support is enabled host application id in the state topic must match exactly what the host publishes the node subscribes to spbv1 0/state/\<primary host id> and reads a json payload {"online"\ true,"timestamp" 1778750000000} flowchart td sub\[subscribe to state topic] > wait\[wait] wait > on{online?} on true > birth\[publish nbirth and dbirth, start data, drain buffer] on false > end\[publish ndeath, disconnect, move to next broker] on online , the node subscribes to litmus edge events, publishes the full birth set, starts streaming data, and drains any store and forward backlog on offline , it ends its mqtt session and moves to the next broker in its list, as the sparkplug specification requires — this is how a sparkplug node follows a host application that has failed over with one broker configured it reconnects to the same one and waits again meanwhile no nbirth , dbirth , or ddata is published, /healthz returns 503 unavailable , and device data is buffered when store and forward is enabled and dropped otherwise state messages are accepted only if their timestamp is newer than the last one seen; an older one is ignored and logged as pha state timestamp conflict; ignoring this protects against retained state arriving out of order after a reconnect a fresh online message with a newer timestamp from an already online host counts as a new host session, and the node republishes the whole birth set to confirm the handshake, look for primary host application online in the logs, le sparkplug pha state at 1 , and /healthz returning 200 store and forward when the node cannot publish, device data is dropped by default store and forward writes it to disk instead and republishes it once publishing resumes, marked so host applications do not mistake it for live values environment variable config json field default effect le store and forward le store and forward false buffers device data on disk while publishing is blocked le ttl duration le ttl duration 12 hours a buffered message stays valid expired messages are removed by the database, so a long outage discards the oldest data first le max size mb le max size mb 1000 size in mb of each on disk buffer file before the database rotates to a new one le max num entries le max num entries 1000000 entries in each buffer file before the database rotates to a new one buffering starts whenever the node cannot publish — no connected mqtt session, or host application gating enabled with the host not online flowchart lr tag\[tag update] > can{can publish?} can yes > pub\[publish ddata] can no > sf{store and forward on?} sf yes > disk\[write to disk] sf no > drop\[drop] disk > drain\[replay when publishing resumes] only data messages are buffered birth and death certificates are session state, rebuilt on reconnect rather than replayed the buffer lives at \<group> \<node> db/ under /le sparkplug/data , which must be on the persistent volume described in deployment # replay a drain runs when the host application comes online, and every 5 minutes while a backlog exists messages leave disk in batches of 256 so a large backlog does not block live data each one is rewritten before it goes out its metrics are marked historical, so host applications record history without moving their live values its datatype fields are stripped, matching the sparkplug rule for data messages it receives the next sequence number of the current session, not the one it had when captured a drain stops early if the connection drops again or the host application goes offline; whatever is left stays on disk for the next attempt a message is deleted from disk only after the broker acknowledges it, so a node that stops between the publish and the delete republishes that message on the next drain host applications must tolerate a duplicate, which the historical flag makes straightforward the node also drops stored messages it can no longer publish honestly if a device has no birth certificate in the current session — removed in litmus edge, or excluded by a publish filter — its buffered messages are deleted rather than replayed, because data before birth breaks the sparkplug contract those drops are counted by le sparkplug sf dropped total{reason="unbirthed device"} to watch a cycle end to end, set le logging level=debug and stop the broker buffered writes log stored from the forward component and le sparkplug sf backlog size climbs start the broker again and the node logs draining stored ddata with a count field as the gauge falls to 0 publish filters by default the node publishes every devicehub device and every enabled digital twin instance it finds filters narrow that set, keeping test equipment out of production namespaces they apply to whole devices and instances, not to individual tags or attributes environment variable config json field default effect dh enabled devicehub enabled true publishes devicehub devices false stops devicehub discovery entirely dh devices include devicehub include empty glob patterns of device names to publish dh devices exclude devicehub exclude empty glob patterns of device names to skip dt enabled digital twins enabled true publishes digital twin instances false stops digital twin discovery entirely dt instances include digital twins include empty glob patterns of instance names to publish dt instances exclude digital twins exclude empty glob patterns of instance names to skip patterns match the devicehub device name or the digital twin instance name as environment variables they are comma separated; in a configuration file they are json lists they support for any sequence of characters, ? for a single character, and \[abc] for a character class regular expressions are not supported, and a pattern that is not a valid glob stops startup the node applies them in this order an exclude match drops the device exclude always wins over include an empty include list admits everything that survived the excludes a non empty include list admits only names matching one of its patterns goal setting publish only production lines dh devices include=line1 ,line2 publish everything except test rigs dh devices exclude=test , sandbox publish one named device dh devices include=press 002 publish devicehub devices but no twins dt enabled=false publish twins for one model's instances dt instances include=hydraulic press a filtered device is absent, not marked offline the node never publishes a dbirth for it, so host applications never learn it exists buffered data for a device you have just filtered out is discarded rather than replayed, for the reason given under store and forward above filters are evaluated on every metadata refresh, so a device that starts matching an exclude pattern disappears from the next birth set — but because configuration is read only at startup, changing a filter takes a restart le sparkplug devicehub devices filtered total and le sparkplug digital twins instances filtered total count each drop with its reason, and the logs name each filtered device at debug level a mismatched `primary host id` looks exactly like a broken deployment the node connects to the broker, logs `waiting for primary host application`, and never publishes a birth certificate check the id first, then clear any retained `state` message left from earlier testing by publishing an empty retained message to the same topic `le max size mb` and `le max num entries` size the buffer's individual files; they are not a total cap on disk use the practical bound on the backlog is `le ttl duration` together with the free space on the volume size that volume for your worst expected outage, and shorten the ttl if the data loses value quickly replay order is not capture order messages are keyed by a random identifier, so the backlog drains in arbitrary order each message still carries its original timestamps, which is what a historian records