feat(mqtt): write-through (IWritable) — Sparkplug NCMD/DCMD + plain publish (design P3) #508

Open
opened 2026-07-27 13:49:45 -04:00 by dohertj2 · 0 comments
Owner

MqttDriver ships read/subscribe/discover only, so every MQTT node materializes read-only. This was
deferred by design (see the plan's Deferred / out of scope section and design §3.7 / §10 P3), not missed —
this issue tracks it.

Shape, from the design:

  • Plain mode — publish to a configured write topic (distinct from the read topic; a tag may legitimately
    read .../state and write .../set).
  • Sparkplug mode — encode an NCMD (edge-node metric) or DCMD (device metric). The encoder already
    exists: SparkplugCodec encodes today for the rebirth NCMD path, so the write leg reuses it rather than
    adding a second encoder.
  • Optimistic-Good + self-correct on echo — MQTT gives no write acknowledgement, so the pattern mirrors
    Galaxy's fire-and-forget: assume Good, and let the broker's echoed value correct the node. Note this
    interacts with write-outcome self-correction (#5): Galaxy can never surface a write failure for the same
    reason, and MQTT will inherit that property.
  • WriteIdempotent default-off — a Sparkplug command is not necessarily idempotent, so the resilience
    pipeline must not retry it by default.

Do not skip: MqttDriver currently does not implement IWritable at all, which is what makes the nodes
read-only. Adding the interface without the topic config would make nodes appear writable and silently
no-op — worse than the current honest read-only.

Acceptance. Write via both NodeIds (raw + UNS — v3 routes either to the same driver ref under the same
realm-qualified WriteOperate gate), verified live against the Mosquitto fixture for Plain and against the
C# edge-node simulator for NCMD/DCMD.

`MqttDriver` ships read/subscribe/discover only, so **every MQTT node materializes read-only**. This was deferred by design (see the plan's *Deferred / out of scope* section and design §3.7 / §10 P3), not missed — this issue tracks it. **Shape, from the design:** - **Plain mode** — publish to a configured write topic (distinct from the read topic; a tag may legitimately read `.../state` and write `.../set`). - **Sparkplug mode** — encode an **NCMD** (edge-node metric) or **DCMD** (device metric). The encoder already exists: `SparkplugCodec` encodes today for the rebirth NCMD path, so the write leg reuses it rather than adding a second encoder. - **Optimistic-Good + self-correct on echo** — MQTT gives no write acknowledgement, so the pattern mirrors Galaxy's fire-and-forget: assume Good, and let the broker's echoed value correct the node. Note this interacts with write-outcome self-correction (#5): Galaxy can never surface a write failure for the same reason, and MQTT will inherit that property. - **`WriteIdempotent` default-off** — a Sparkplug command is not necessarily idempotent, so the resilience pipeline must not retry it by default. **Do not skip:** `MqttDriver` currently does not implement `IWritable` at all, which is what makes the nodes read-only. Adding the interface without the topic config would make nodes appear writable and silently no-op — worse than the current honest read-only. **Acceptance.** Write via **both** NodeIds (raw + UNS — v3 routes either to the same driver ref under the same realm-qualified `WriteOperate` gate), verified live against the Mosquitto fixture for Plain and against the C# edge-node simulator for NCMD/DCMD.
dohertj2 added the driver/mqtt label 2026-07-27 13:49:45 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#508