docs(drivers): MQTT write QoS/claim backoff and Sql Postgres untyped binds (#602)
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -325,6 +325,9 @@ and this driver ships all three or none of it
|
||||
2. a matching **retained `OFFLINE` armed as the MQTT Last Will**, so a crash still reports the truth;
|
||||
3. an explicit `OFFLINE` on a clean stand-down, so edge nodes do not wait out a keep-alive timeout.
|
||||
|
||||
A claim the broker keeps refusing backs off (STAB-27): 2 s, 4 s, 8 s … capped at 30 s between attempts, one
|
||||
Warning per attempt, reset by a successful claim or a stand-down. The role is still sampled every second.
|
||||
|
||||
Set `Sparkplug.HostId` and `Sparkplug.ActAsPrimaryHost: true`. A blank host id is **refused** with a
|
||||
warning — the driver does not publish to `spBv1.0/STATE/`, which is a legal topic reaching nobody.
|
||||
|
||||
@@ -460,8 +463,12 @@ every MQTT node materialized read-only regardless of what the operator authored.
|
||||
| **Plain** | the tag's `writeTopic` | the value as UTF-8 text (`Raw`/`Scalar`) or a bare JSON literal (`Json`) |
|
||||
| **Sparkplug B** | `spBv1.0/{group}/DCMD/{node}/{device}` for a device metric, `spBv1.0/{group}/NCMD/{node}` for an edge-node metric | a Sparkplug `Payload` carrying the metric **by name**, with an explicit `Datatype` and no `seq` |
|
||||
|
||||
Both publish at **QoS 0, `retain: false`**. Retain is the one that matters and is deliberately not
|
||||
configurable: a retained command would be replayed by the broker to the device on *every* future
|
||||
Both publish with `retain: false`. A **Plain** write goes at **QoS 1** (STAB-26): the publish completes only
|
||||
once the broker PUBACKs it, so `Good` means "the broker accepted it", and a broker refusal or a connection
|
||||
that died under the send is `Bad`. **Sparkplug commands stay at QoS 0** — a redelivered NCMD/DCMD would be
|
||||
re-applied. A Sparkplug metric the tag did not give a `dataType` is commanded with the type its live birth
|
||||
certificate declared (STAB-25), the same authored-beats-birth precedence reads use. Retain is the one that
|
||||
matters and is deliberately not configurable: a retained command would be replayed by the broker to the device on *every* future
|
||||
subscribe — including the device's own reconnect — so one stale write would be re-applied forever.
|
||||
|
||||
### `writeTopic` is separate from `topic`, and its absence is meaningful
|
||||
|
||||
+4
-1
@@ -92,7 +92,10 @@ Both value-bearing fields — `whereValue` here and `keyValue` on the `KeyValue`
|
||||
authored as a JSON string, number or boolean, and are captured as text. They are **bound as
|
||||
parameters** either way, and matched back as text (the key cell is stringified), so a key column
|
||||
that holds an INTEGER station id can be authored either `"7"` or `7`. A JSON object, array or `null`
|
||||
is not a value and is refused. (They were read asymmetrically until 2026-08-10, so a numerically
|
||||
is not a value and is refused. On **PostgreSQL** a string bind is sent untyped (`NpgsqlDbType.Unknown`,
|
||||
`PostgresDialect.ConfigureParameter`, STAB-24) so the server infers its type from the compared column;
|
||||
bound as `text`, a `"7"` against an `integer` key fails with `operator does not exist: integer = text`.
|
||||
(They were read asymmetrically until 2026-08-10, so a numerically
|
||||
authored `keyValue` refused the tag while the identically-bound `whereValue` was served — and the
|
||||
deploy gate reported the key as *missing* when it was right there in the blob.)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user