Skip to content

Releases: otfabric/go-sparkplugb

go-sparkplugb v0.3.3

Choose a tag to compare

@github-actions github-actions released this 01 Nov 19:23
97e1809

Date: 2026-11-01
Previous release: v0.3.2

Fixed

  • host and app keep an update stamped in the millisecond of the NBIRTH that follows it. Delivered before that NBIRTH, it was wiped with the state of the old session, and the value stayed stale until the next rebirth. Seen against srad on NanoMQ with delayed NBIRTHs.
  • edge no longer publishes an NBIRTH after its NDEATH. Disconnect kept the node online while it published the NDEATH, so a rebirth requested at that moment followed it and a host kept the node online. Seen with a Tahu host on EMQX. The session now ends first, and a message on its way goes out before the NDEATH; a publish after that returns ErrNotConnected. The state changes to Disconnected before the NDEATH is published.

Tests

  • A message in the millisecond of the next NBIRTH, for host and app; a rebirth during Disconnect, for edge.

go-sparkplugb v0.3.2

Choose a tag to compare

@github-actions github-actions released this 01 Nov 17:34
c9ee975

Date: 2026-11-01
Previous release: v0.3.1

Fixed

  • An NBIRTH delivered just after the NDEATH of the same bdSeq no longer brings a dead edge node back online. MQTT orders messages per topic only, so a will can overtake a rebirth that was in flight when the edge node died; host and app then showed the node online for good. For 250 ms after an NDEATH, an NBIRTH with its bdSeq is dropped, and a rebirth is requested 2 seconds later. A node whose NDEATH had a bdSeq ahead of the known session goes offline on that NBIRTH. A DBIRTH on an offline node no longer puts the device online.

Changed

  • An edge node that restarts within 250 ms with the bdSeq of its NDEATH comes online only on the rebirth that follows, about 2 seconds later. srad and SparkplugNet start again at bdSeq 0, and SparkplugNet does not answer that rebirth.

Tests

  • host and app: late NBIRTHs after an NDEATH, a will before its NBIRTH, a restart with the same bdSeq, and the limits of the 250 ms.

go-sparkplugb v0.3.1

Choose a tag to compare

@github-actions github-actions released this 01 Nov 15:37
18d9cb8

Date: 2026-11-01
Previous release: v0.3.0

Fixed

  • host and app keep the sessions of an edge node apart when a broker reorders messages across topics. MQTT orders messages per topic only, and data messages carry no session number; with rebirths overlapping, as a reordering broker causes, the host took messages of one session for another. Three outcomes, all seen against srad on NanoMQ and reproduced with a unit test each: devices missing after the births until the next rebirth; a device with the values of an earlier session after a restart; and the state frozen, because held data of the ended session carried seq past the edge node's, after which every message was behind and held, and no rebirth was requested. Now a message held or arriving out of sequence that is older than the current NBIRTH is dropped, the newest of a seq held twice is the one applied, and messages of the new session that were applied to the old one before its NBIRTH arrived are applied again after it.
  • A message behind the expected seq requests a rebirth when no NBIRTH follows within 2 seconds. It used to wait for that NBIRTH for ever. A duplicate delivered late now costs one rebirth.

Tests

  • A simulated broker that keeps the order per topic only, and an edge node with overlapping rebirths, against host and app: 400 seeds each. Before the fix about 11 in 100 ended without the edge node's state.

go-sparkplugb v0.3.0

Choose a tag to compare

@github-actions github-actions released this 01 Nov 13:14
cd5281b

Date: 2026-11-01
Previous release: v0.2.3

Changed

  • GetDataSetValues and GetTemplateParameterValue return the Go type of the datatype, an API change. An Int8 cell or parameter is an int8, not the raw uint32; Int64 an int64, not a uint64; the rest as GetValue returns them. A DateTime cell is a time.Time, not a uint64. Code with type assertions on uint32 or uint64 for those datatypes has to change. It compiles unchanged, and fails at run time.
  • Every integer out of its datatype's range is rejected, a behaviour change. Metrics (GetValue), DataSet cells, template parameters and properties return ErrTypeMismatch for a UInt8 above 255, a UInt16 above 65535, a UInt32 or Int32 that does not fit in long_value, a DateTime above math.MaxInt64 milliseconds and an Int8 or Int16 in neither wire form, and for an integer metric whose value is of another kind. Until now they were truncated, or read as 0. A peer that sends such values now gets an error from GetValue. Valid values decode as before.
  • NewDataSet and NewTemplateParameter take the Go type of the datatype (int8(-8) for an Int8). The raw uint32 and uint64 still work, but they have to be values of the datatype, which fails for a value out of range that was written before, and they go out in the canonical form: a width-sized Int8 is sign-extended.
  • SetValue refuses a time.Time before 1970 for DateTime and DateTimeArray, which wrapped around to a date far in the future. ErrTypeMismatch.
  • GetDataSetValues returns ErrColumnMismatch for a row with more cells than the DataSet has types.
  • GetQuality reads the property as an Int32 and returns false for a value that is not one.

Added

  • NewPropertyValue and GetPropertyValue, with the same rules, for a metric's PropertySet.
  • DateTime in DataSet columns and template parameters, which NewDataSet and NewTemplateParameter refused.

Interoperability

  • The interop suite pins sparkplugb-interop v0.3.0, which it had at v0.1.0. It runs the third update of scalars and the new composite fixture: DataSets, templates and properties against Tahu, tahu-js and SparkplugNet edges and Tahu, SparkplugNet and sparkplughost hosts, with the form of each Int8 and Int16 checked on the wire. Exclusions and the two SparkplugNet findings are in INTEROPERABILITY.md.

Documentation

  • INTEROPERABILITY.md, section Integers: what the specification states, and what is this library's reading.

Tests

  • FuzzIntegerPaths holds the metric, DataSet cell, template parameter and PropertyValue paths to one statement of the rule. Table tests per path.

go-sparkplugb v0.2.3

Choose a tag to compare

@github-actions github-actions released this 01 Nov 00:50
019ce25

Date: 2026-10-31
Previous release: v0.2.2

Changed

  • payload.GetValue rejects an Int8 or Int16 that is not a valid wire value, a behaviour change. It used to truncate every value to the width, so 0x100 read as Int8 0 and 0xFFFFFF7F as 127. It now accepts the width-sized form and the sign-extended one, which the specification leaves open, and returns ErrTypeMismatch for anything else. Valid values decode as before. Negative Int8 and Int16 are still encoded sign-extended to 32 bits, as Eclipse Tahu does: nothing changes on the wire.

Documentation

  • The Int8 and Int16 encoding is recorded as a specification ambiguity, not a defect of any stack (INTEROPERABILITY.md, LIMITATIONS.md, docs/CONFORMANCE.md).

Tests

  • FuzzDecodeSignedInt. The interop suite checks which form each reference edge node has on the wire.

go-sparkplugb v0.2.2

Choose a tag to compare

@github-actions github-actions released this 31 Oct 15:08

Date: 2026-10-31
Previous release: v0.2.1

Fixed

  • PahoTransport Publish and Subscribe now honour ctx, fail at once when the connection ends, and stay within PublishTimeout. paho could block for 30s in the call on a connection that had just dropped, and ctx was ignored.

go-sparkplugb v0.2.1

Choose a tag to compare

@github-actions github-actions released this 31 Oct 11:28

Date: 2026-10-31
Previous release: v0.2.0

Changed

  • Policy 1.2: build output in bin/ and release/, a per-package coverage floor, and more tests and CI. No change in behaviour.

go-sparkplugb v0.2.0

Choose a tag to compare

@github-actions github-actions released this 30 Oct 17:30
faaab4c

Date: 2026-10-30
Previous release: v0.1.3

Summary

Broker logins without a custom transport, aliases that are checked to be unique, and string limits that are enforced.

Changes

Added

  • Username and Password in Config of edge, host and app, passed to ConnectOpts, so a broker that requires a login no longer needs a custom mqtt.Transport. They are never logged. New refuses a Password without a Username.
  • payload.ErrStringTooLarge.

Fixed

  • edge: an alias that is not unique across the edge node is refused with ErrDuplicateID by PublishBirth and PublishDeviceBirth; a later metric used to overwrite the earlier one without a word. A device repeating its birth keeps its aliases.
  • payload.GetValue enforces its limits: a string or StringArray element above MaxStringBytes returns ErrStringTooLarge, and a StringArray above MaxArrayElements returns ErrArrayTooLarge. MaxStringBytes was exported and unused.

Deprecated

  • edge.ErrInvalidState: never returned. It stays for source compatibility.

Documentation

  • MQTT versions: the Paho adapter asks for 3.1.1 and falls back to 3.1, with no MQTT 5. docs/LICENSING.md no longer lists paho.golang, which is not a dependency, and lists the indirect ones.
  • New: API.md, ARCHITECTURE.md, OBSERVABILITY.md, TESTING.md, docs/FEATURE-STATUS.md.

Build

  • make e2e, make bench.

Dependencies

  • golang.org/x/net → v0.62.0 (govulncheck).

go-sparkplugb v0.1.3

Choose a tag to compare

@github-actions github-actions released this 27 Oct 15:08

Date: 2026-10-27
Previous release: v0.1.2

Summary

A restarted edge node's DBIRTH delivered before its NBIRTH is no longer
lost; current dependencies and Go releases; and a README that compares
go-sparkplugb with the other Sparkplug B stacks it is tested against.

Changes

Fixed

  • host and app: a message behind the expected seq is held for the node's next session and applied after its NBIRTH. When a node restarted, NanoMQ and HiveMQ CE sometimes delivered the new session's DBIRTH (seq 1) before its NBIRTH; the host took it for a gap in the old session and dropped it, so the device stayed offline unless a rebirth came. Found by the interop tests against pysparkplug on NanoMQ.

Changed

  • Requires Go 1.26 or later (was 1.24): golang.org/x/net v0.61.0 and golang.org/x/sync v0.24.0, their latest releases, need it. CI tests Go 1.26 and 1.27, the releases the Go project supports.

Documentation

  • README: a comparison with Eclipse Tahu, pysparkplug, SparkplugNet, srad and sparkplughost, from their source at the tested versions; the compatibility matrix by reference stack and broker; the configuration tables list every field (BdSeqStore, RetryPolicy, Logger, Metrics, OnDeviceCmd) and no longer a UseAliases field that does not exist.

go-sparkplugb v0.1.2

Choose a tag to compare

@github-actions github-actions released this 27 Oct 12:08

Date: 2026-10-27
Previous release: v0.1.1

Summary

The host and the application no longer flood an edge node with rebirth
requests when a broker delivers its messages out of order. Found by the
interop tests against srad on HiveMQ CE.

Changes

Fixed

  • host and app: at most one rebirth request per edge node every 2 seconds, for a seq gap and a reorder timeout as already for a node without a birth. A broker that reorders messages across topics (HiveMQ CE, NanoMQ) made several messages in a row look out of sequence, each answered with its own rebirth request, so the node published one NBIRTH per request and the host was still applying them after the node's NDEATH.

Changed

  • Interop tests: the reference roles get a 60 s MQTT connect timeout instead of the contract's 10 s: Eclipse Tahu on a busy runner sometimes did not reach a HiveMQ that had just started in time.