fix(mqtt): birth-typed Sparkplug writes and QoS 1 for Plain writes (#602 STAB-25/26)
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -350,6 +350,55 @@ public sealed class MqttWriteEncoderTests
|
||||
Payload.Parser.ParseFrom(encoded.Payload).Metrics[0].Name.ShouldBe("Node Control/Rebirth");
|
||||
}
|
||||
|
||||
// ---- STAB-25 / STAB-26 (#602) ---------------------------------------------------------------------
|
||||
|
||||
[Fact]
|
||||
public void A_plain_write_publishes_at_QoS1_so_Good_means_the_broker_accepted_it()
|
||||
{
|
||||
MqttWriteEncoder.TryEncode(MqttMode.Plain, Plain("oven/set"), 42.5, out var encoded)
|
||||
.ShouldBe(MqttWriteEncodeError.None);
|
||||
|
||||
encoded.Qos.ShouldBe(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_sparkplug_command_stays_at_QoS0()
|
||||
{
|
||||
// Pinned beside the Plain case so the two cannot be "unified" by accident: an NCMD/DCMD retry from
|
||||
// QoS 1 redelivery would re-apply a command the device already took.
|
||||
MqttWriteEncoder.TryEncode(MqttMode.SparkplugB, Sparkplug("Filler1"), 1.0, out var encoded)
|
||||
.ShouldBe(MqttWriteEncodeError.None);
|
||||
|
||||
encoded.Qos.ShouldBe(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void An_unauthored_sparkplug_type_is_commanded_with_the_birth_declared_type()
|
||||
{
|
||||
// DataTypeAuthored=false: the record's Float64 is only a default. The birth said Int32, so the DCMD
|
||||
// must carry Int32 — a Double-typed command to an Int32 metric is the silent-drop shape.
|
||||
var def = Sparkplug("Filler1") with { DataTypeAuthored = false };
|
||||
|
||||
MqttWriteEncoder.TryEncode(MqttMode.SparkplugB, def, 7, out var encoded, DriverDataType.Int32)
|
||||
.ShouldBe(MqttWriteEncodeError.None);
|
||||
|
||||
var metric = Payload.Parser.ParseFrom(encoded.Payload).Metrics[0];
|
||||
metric.Datatype.ShouldBe((uint)TahuDataType.Int32);
|
||||
metric.IntValue.ShouldBe(7u);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void An_authored_sparkplug_type_wins_over_the_birth_type()
|
||||
{
|
||||
// Same precedence as the ingest path: authored beats birth.
|
||||
var def = Sparkplug("Filler1", DriverDataType.Float64) with { DataTypeAuthored = true };
|
||||
|
||||
MqttWriteEncoder.TryEncode(MqttMode.SparkplugB, def, 7, out var encoded, DriverDataType.Int32)
|
||||
.ShouldBe(MqttWriteEncodeError.None);
|
||||
|
||||
Payload.Parser.ParseFrom(encoded.Payload).Metrics[0].Datatype.ShouldBe((uint)TahuDataType.Double);
|
||||
}
|
||||
|
||||
private static string EncodeTopic(MqttMode mode, MqttTagDefinition def)
|
||||
{
|
||||
MqttWriteEncoder.TryEncode(mode, def, 1.0, out var encoded).ShouldBe(MqttWriteEncodeError.None);
|
||||
|
||||
Reference in New Issue
Block a user