Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,13 @@ public void TestDeviceBirthMessageNamespaceB()
public void TestNodeBirthMessageNamespaceB()
{
var dateTime = DateTimeOffset.UtcNow;
var timestamp = (ulong)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
var message = this.messageGenerator.GetSparkplugNodeBirthMessage(SparkplugNamespace.VersionB, "group1", "edge1", this.metricsB, 0, 1, dateTime);
var payloadVersionB = PayloadHelper.Deserialize<VersionBProtoBufPayload>(message.Payload);

Assert.AreEqual("spBv1.0/group1/NBIRTH/edge1", message.Topic);
Assert.IsNotNull(payloadVersionB);
Assert.AreEqual((ulong)dateTime.ToUnixTimeMilliseconds(), payloadVersionB.Timestamp);
Assert.AreEqual(timestamp, payloadVersionB.Timestamp);
Assert.AreEqual(2, payloadVersionB.Metrics.Count);

Assert.AreEqual(this.metricsB.First().Name, payloadVersionB.Metrics.ElementAt(0).Name);
Expand All @@ -111,6 +112,13 @@ public void TestNodeBirthMessageNamespaceB()
Assert.AreEqual(this.seqMetricB.Name, payloadVersionB.Metrics.ElementAt(1).Name);
Assert.AreEqual(Convert.ToUInt64(this.seqMetricB.Value), payloadVersionB.Metrics.ElementAt(1).LongValue);
Assert.AreEqual((uint?)this.seqMetricB.DataType, payloadVersionB.Metrics.ElementAt(1).DataType);

foreach (var metric in payloadVersionB.Metrics)
{
// [tck-id-payloads-name-birth-data-requirement]
// The timestamp MUST be included with every metric in all NBIRTH, DBIRTH, NDATA, and DDATA messages.*#
Assert.AreEqual(metric.Timestamp, timestamp);
}
}

/// <summary>
Expand Down Expand Up @@ -246,4 +254,4 @@ public void TestNodeCommandMessageNamespaceB()
Assert.AreEqual(Convert.ToUInt64(this.seqMetricB.Value), payloadVersionB.Metrics.ElementAt(1).LongValue);
Assert.AreEqual((uint?)this.seqMetricB.DataType, payloadVersionB.Metrics.ElementAt(1).DataType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,7 @@ public void TestConvertVersionBPayloadToProto()
IsTransient = true,
IsNull = false,
DataType = (uint?)VersionBProtoBuf.DataType.UInt32,
LongValue = 7
IntValue = 7
},
new()
{
Expand Down Expand Up @@ -2123,4 +2123,4 @@ public void TestConvertVersionBPayloadToProtoWithNegativeValues()
EqualityHelper.MetricEquals(convertedMetrics[count++], metric);
}
}
}
}
31 changes: 27 additions & 4 deletions src/SparkplugNet/Core/Messages/SparkplugMessageGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ private MqttApplicationMessage GetSparkplugNodeBirthB(
Seq = (ulong)sequenceNumber,
Timestamp = (ulong)dateTime.ToUnixTimeMilliseconds()
};
EnsureSparkplugBMetricTimestamps(ref payload);

var convertedPayload = VersionB.PayloadConverter.ConvertVersionBPayload(payload);
var serialized = PayloadHelper.Serialize(convertedPayload);
Expand Down Expand Up @@ -755,6 +756,7 @@ private MqttApplicationMessage GetSparkplugDeviceBirthB(
Seq = (ulong)sequenceNumber,
Timestamp = (ulong)dateTime.ToUnixTimeMilliseconds()
};
EnsureSparkplugBMetricTimestamps(ref payload);

var convertedPayload = VersionB.PayloadConverter.ConvertVersionBPayload(payload);
var serialized = PayloadHelper.Serialize(convertedPayload);
Expand Down Expand Up @@ -990,6 +992,7 @@ private MqttApplicationMessage GetSparkplugNodeDataB(
Seq = (ulong)sequenceNumber,
Timestamp = (ulong)dateTime.ToUnixTimeMilliseconds()
};
EnsureSparkplugBMetricTimestamps(ref payload);

var convertedPayload = VersionB.PayloadConverter.ConvertVersionBPayload(payload);
var serialized = PayloadHelper.Serialize(convertedPayload);
Expand Down Expand Up @@ -1074,6 +1077,7 @@ private MqttApplicationMessage GetSparkplugDeviceDataB(
Seq = (ulong)sequenceNumber,
Timestamp = (ulong)dateTime.ToUnixTimeMilliseconds()
};
EnsureSparkplugBMetricTimestamps(ref payload);

var convertedPayload = VersionB.PayloadConverter.ConvertVersionBPayload(payload);
var serialized = PayloadHelper.Serialize(convertedPayload);
Expand Down Expand Up @@ -1139,7 +1143,7 @@ private static MqttApplicationMessage GetSparkplugNodeCommandA(
/// <param name="sequenceNumber">The sequence number.</param>
/// <param name="dateTime">The date time.</param>
/// <returns>A new NCMD <see cref="MqttApplicationMessage"/>.</returns>
private static MqttApplicationMessage GetSparkplugNodeCommandB(
private MqttApplicationMessage GetSparkplugNodeCommandB(
SparkplugNamespace nameSpace,
string groupIdentifier,
string edgeNodeIdentifier,
Expand All @@ -1153,7 +1157,8 @@ private static MqttApplicationMessage GetSparkplugNodeCommandB(
Seq = (ulong)sequenceNumber,
Timestamp = (ulong)dateTime.ToUnixTimeMilliseconds()
};

EnsureSparkplugBMetricTimestamps(ref payload);

var convertedPayload = VersionB.PayloadConverter.ConvertVersionBPayload(payload);
var serialized = PayloadHelper.Serialize(convertedPayload);

Expand Down Expand Up @@ -1220,7 +1225,7 @@ private static MqttApplicationMessage GetSparkplugDeviceCommandA(
/// <param name="sequenceNumber">The sequence number.</param>
/// <param name="dateTime">The date time.</param>
/// <returns>A new DCMD <see cref="MqttApplicationMessage"/>.</returns>
private static MqttApplicationMessage GetSparkplugDeviceCommandB(
private MqttApplicationMessage GetSparkplugDeviceCommandB(
SparkplugNamespace nameSpace,
string groupIdentifier,
string edgeNodeIdentifier,
Expand All @@ -1235,6 +1240,7 @@ private static MqttApplicationMessage GetSparkplugDeviceCommandB(
Seq = (ulong)sequenceNumber,
Timestamp = (ulong)dateTime.ToUnixTimeMilliseconds()
};
EnsureSparkplugBMetricTimestamps(ref payload);

var convertedPayload = VersionB.PayloadConverter.ConvertVersionBPayload(payload);
var serialized = PayloadHelper.Serialize(convertedPayload);
Expand All @@ -1251,4 +1257,21 @@ private static MqttApplicationMessage GetSparkplugDeviceCommandB(
.WithRetainFlag(false)
.Build();
}
}

/// <summary>
/// Ensures that all metrics will contain a Timestamp if Sparkplug protol version is Version 3.0
/// Message timestamp will be added to all metrics that does not already contain timestamps
/// [tck-id-payloads-name-birth-data-requirement]
/// </summary>
/// <param name="payload">The payload to update</param>
private void EnsureSparkplugBMetricTimestamps(ref Payload payload)
{
if (this.specificationVersion == SparkplugSpecificationVersion.Version30)
{
foreach (var metric in payload.Metrics)
{
metric.Timestamp ??= payload.Timestamp;
}
}
}
}