diff --git a/src/SparkplugNet.Tests/Payloads/SparkplugPayloadConverterTestVersionB.cs b/src/SparkplugNet.Tests/Payloads/SparkplugPayloadConverterTestVersionB.cs index 0bb3fef..7bcf7b0 100644 --- a/src/SparkplugNet.Tests/Payloads/SparkplugPayloadConverterTestVersionB.cs +++ b/src/SparkplugNet.Tests/Payloads/SparkplugPayloadConverterTestVersionB.cs @@ -186,7 +186,7 @@ public void TestConvertVersionBPayloadFromProto() IsTransient = true, IsNull = false, DataType = (uint?)VersionBData.DataType.DateTime, - LongValue = 1546300800000 + LongValue = 1546300800000 }, new() { @@ -541,8 +541,8 @@ public void TestConvertVersionBPayloadFromProto() IsNull = false, DataType = (uint?)VersionBData.DataType.DateTimeArray, BytesValue = [0x00, 0xE8, 0x66, 0x5E, 0x6F, 0x01, 0x00, 0x00, - 0x00, 0x9C, 0xEF, 0x12, 0x7E, 0x01, 0x00, 0x00, - 0x00, 0xC8, 0xA0, 0x6A, 0x85, 0x01, 0x00, 0x00, + 0x00, 0x9C, 0xEF, 0x12, 0x7E, 0x01, 0x00, 0x00, + 0x00, 0xC8, 0xA0, 0x6A, 0x85, 0x01, 0x00, 0x00, 0x00, 0xF4, 0x51, 0xC2, 0x8C, 0x01, 0x00, 0x00] }, new() @@ -778,7 +778,7 @@ public void TestConvertVersionBPayloadFromProto() IsTransient = true }, new("Test22", VersionBData.DataType.String, "Test22",timestamp) - { + { Properties = new VersionBData.PropertySet { Keys = ["Test1", "Test2"], @@ -929,6 +929,60 @@ public void TestConvertVersionBPayloadFromProto() } } + /// + /// Tests the Sparkplug payload converter for converting a version B payload from Proto with a null metric value. + /// + [TestMethod] + public void TestConvertVersionBPayloadFromProtoIsNull() + { + var timestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero); + var bodyData = new byte[] { 1, 2, 3, 4 }; + var metrics = new List + { + new() + { + Name = "Test1", + Timestamp = (ulong)timestamp.ToUnixTimeMilliseconds(), + Alias = 1, + IsHistorical = true, + IsTransient = true, + IsNull = true, + DataType = (uint?)VersionBData.DataType.Int8, + } + }; + var convertedMetrics = new List + { + new("Test1", VersionBData.DataType.Int8, null, timestamp) + { + Alias = 1, + IsHistorical = true, + IsTransient = true + } + }; + var oldPayload = new VersionBProtoBufPayload + { + Body = bodyData, + Timestamp = (ulong)timestamp.ToUnixTimeMilliseconds(), + Seq = 1, + Uuid = "477a41e5-f0ba-4b98-9522-95d44861d993", + Metrics = metrics + }; + var payload = VersionBMain.PayloadConverter.ConvertVersionBPayload(oldPayload); + Assert.IsNotNull(payload); + CollectionAssert.AreEqual(bodyData, payload.Body); + Assert.AreEqual((ulong)timestamp.ToUnixTimeMilliseconds(), payload.Timestamp); + Assert.AreEqual((ulong)1, payload.Seq); + Assert.AreEqual("477a41e5-f0ba-4b98-9522-95d44861d993", payload.Uuid); + Assert.AreEqual(convertedMetrics.Count, payload.Metrics.Count); + + var count = 0; + + foreach (var metric in payload.Metrics) + { + EqualityHelper.MetricEquals(convertedMetrics[count++], metric); + } + } + /// /// Tests the Sparkplug payload converter for converting a version B payload to Proto. /// @@ -1149,7 +1203,7 @@ public void TestConvertVersionBPayloadToProto() IsTransient = true }, new("Test22", VersionBData.DataType.String,"Test22",timestamp) - { + { Properties = new VersionBData.PropertySet { Keys = ["Test1", "Test2"], @@ -1353,7 +1407,7 @@ public void TestConvertVersionBPayloadToProto() IsTransient = true, IsNull = false, DataType = (uint?)VersionBProtoBuf.DataType.UInt32, - LongValue = 7 + IntValue = 7 }, new() { @@ -1774,8 +1828,8 @@ public void TestConvertVersionBPayloadToProto() IsNull = false, DataType = (uint?)VersionBProtoBuf.DataType.DateTimeArray, BytesValue = [0x00, 0xE8, 0x66, 0x5E, 0x6F, 0x01, 0x00, 0x00, - 0x00, 0x9C, 0xEF, 0x12, 0x7E, 0x01, 0x00, 0x00, - 0x00, 0xC8, 0xA0, 0x6A, 0x85, 0x01, 0x00, 0x00, + 0x00, 0x9C, 0xEF, 0x12, 0x7E, 0x01, 0x00, 0x00, + 0x00, 0xC8, 0xA0, 0x6A, 0x85, 0x01, 0x00, 0x00, 0x00, 0xF4, 0x51, 0xC2, 0x8C, 0x01, 0x00, 0x00] }, new() @@ -1845,6 +1899,76 @@ public void TestConvertVersionBPayloadToProto() } } + /// + /// Tests the Sparkplug payload converter for converting a version B payload to Proto with null metric values. + /// + [TestMethod] + public void TestConvertVersionBPayloadToProtoIsNull() + { + var timestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero); + var bodyData = new byte[] { 1, 2, 3, 4 }; + var metrics = new List + { + new("Test10", VersionBData.DataType.Double, null, timestamp) + { + Alias = 10, + IsHistorical = true, + IsTransient = true + }, + new("Test12", VersionBData.DataType.String, null, timestamp) + { + Alias = 12, + IsHistorical = true, + IsTransient = true + }, + }; + var convertedMetrics = new List + { + new() + { + Name = "Test10", + Timestamp = (ulong)timestamp.ToUnixTimeMilliseconds(), + Alias = 10, + IsHistorical = true, + IsTransient = true, + IsNull = true, + DataType = (uint?)VersionBProtoBuf.DataType.Double, + }, + new() + { + Name = "Test12", + Timestamp = (ulong)timestamp.ToUnixTimeMilliseconds(), + Alias = 12, + IsHistorical = true, + IsTransient = true, + IsNull = true, + DataType = (uint?)VersionBProtoBuf.DataType.String, + }, + }; + var oldPayload = new VersionBData.Payload + { + Body = bodyData, + Timestamp = (ulong)timestamp.ToUnixTimeMilliseconds(), + Seq = 1, + Uuid = "477a41e5-f0ba-4b98-9522-95d44861d993", + Metrics = metrics + }; + var payload = VersionBMain.PayloadConverter.ConvertVersionBPayload(oldPayload); + Assert.IsNotNull(payload); + CollectionAssert.AreEqual(bodyData, payload.Body); + Assert.AreEqual((ulong)timestamp.ToUnixTimeMilliseconds(), payload.Timestamp); + Assert.AreEqual((ulong)1, payload.Seq); + Assert.AreEqual("477a41e5-f0ba-4b98-9522-95d44861d993", payload.Uuid); + Assert.AreEqual(convertedMetrics.Count, payload.Metrics.Count); + + var count = 0; + + foreach (var metric in payload.Metrics) + { + EqualityHelper.MetricEquals(convertedMetrics[count++], metric); + } + } + /// /// Tests the conversion of a VersionB payload to a ProtoBuf payload and vice versa with a property set metric. /// diff --git a/src/SparkplugNet.lutconfig b/src/SparkplugNet.lutconfig new file mode 100644 index 0000000..ff7fdf3 --- /dev/null +++ b/src/SparkplugNet.lutconfig @@ -0,0 +1,6 @@ + + ..\ + true + true + 180000 + \ No newline at end of file diff --git a/src/SparkplugNet/VersionB/PayloadConverter.cs b/src/SparkplugNet/VersionB/PayloadConverter.cs index 7f859f5..d5f0915 100644 --- a/src/SparkplugNet/VersionB/PayloadConverter.cs +++ b/src/SparkplugNet/VersionB/PayloadConverter.cs @@ -64,6 +64,12 @@ public static Metric ConvertVersionBMetric(VersionBProtoBuf.ProtoBufPayload.Metr var dataType = ConvertVersionBDataType((VersionBProtoBuf.DataType?)protoMetric.DataType); + if (protoMetric.IsNull != null && protoMetric.IsNull.Value) + { + metric.SetValue(dataType, null); + return metric; + } + switch (dataType) { case VersionBDataTypeEnum.Int8: @@ -139,7 +145,7 @@ public static Metric ConvertVersionBMetric(VersionBProtoBuf.ProtoBufPayload.Metr metric.SetValue(VersionBDataTypeEnum.Int32Array, int32Array); break; case VersionBDataTypeEnum.Int64Array: - var int64Array = PayloadHelper.GetArrayOfTFromBytes(protoMetric.BytesValue, BinaryPrimitives.ReadInt64LittleEndian); + var int64Array = PayloadHelper.GetArrayOfTFromBytes(protoMetric.BytesValue, BinaryPrimitives.ReadInt64LittleEndian); metric.SetValue(VersionBDataTypeEnum.Int64Array, int64Array); break; case VersionBDataTypeEnum.UInt8Array: @@ -177,7 +183,7 @@ public static Metric ConvertVersionBMetric(VersionBProtoBuf.ProtoBufPayload.Metr var dateTimeArray = PayloadHelper.GetArrayOfTFromBytes(protoMetric.BytesValue, BinaryPrimitives.ReadUInt64LittleEndian); metric.SetValue(VersionBDataTypeEnum.DateTimeArray, dateTimeArray.Select(x => DateTimeOffset.FromUnixTimeMilliseconds((long)x)).ToArray()); break; - // Todo: What to do here? + // Todo: What to do here? case VersionBDataTypeEnum.PropertySetList: case VersionBDataTypeEnum.Unknown: default: @@ -625,7 +631,7 @@ public static bool[] ConvertBooleanByteArray(byte[] metricValue) if (numberOfBytes + 4 < metricValue.Length) { throw new ArgumentOutOfRangeException("The array length is invalid."); - }; + } bytes = new Span(metricValue, 4, numberOfBytes); @@ -642,7 +648,7 @@ public static bool[] ConvertBooleanByteArray(byte[] metricValue) { result[i] = false; } - }; + } return result; } @@ -667,7 +673,7 @@ public static byte[] ConvertBooleanByteArray(object? metricValue) { result[4 + byteNumber] |= (byte)(1 << bitNumber); } - }; + } return result; }