SparkplugNet
SparkplugNet copied to clipboard
Negative integer set value
Hey there, while testing the NuGet 1.3.8 update, I noticed that I'm no longer receiving messages with negative integers in the MQTT broker side.
Here's an example:
Metric metric = new()
{
Name = "Test",
Timestamp = timestamp_var
};
Int32 negativeInt = -1;
metric.SetValue(DataType.Int32, negativeInt);
In previous versions of the NuGet, I had a workaround where I casted the data to Float, but now I'm still not getting anything. Is this a known issue? Any possible solutions?
Thanks in advance for all the efforts you put into improving this fantastic NuGet.
I guess, this can't be fixed with version 3 anymore and is a known issue within Sparkplug still: https://github.com/eclipse/tahu/issues/71, https://github.com/eclipse-sparkplug/sparkplug/issues/114 and https://github.com/eclipse-sparkplug/sparkplug/issues/62.
I have seen this issue coming since I saw version 3 of the Sparkplug spec in detail. I have not yet a good idea on how to handle this except maybe to use the byte array with custom encoding / mapping on the client side. This is stupid if you ask me...
Hi, thank you very much for addressing this issue. I'm also struggling with this right now and I'm trying to find a possible workaround.
When I try to send -1 int on version 1.3.8, I get OverflowException.
System.OverflowException: Value was either too large or too small for a UInt32.
at System.Convert.ThrowUInt32OverflowException()
at System.Int32.System.IConvertible.ToUInt32(IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType)
at SparkplugNet.Core.Extensions.DataTypeExtensions.ConvertTo[T](Object objValue)
at SparkplugNet.Core.Extensions.DataTypeExtensions.ConvertOrDefaultTo[T](Object objValue)
at SparkplugNet.VersionB.PayloadConverter.ConvertVersionBMetric(Metric metric)
at System.Linq.Enumerable.SelectListIterator`2.ToList()
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at SparkplugNet.VersionB.PayloadConverter.ConvertVersionBPayload(Payload payload)
at SparkplugNet.Core.Messages.SparkplugMessageGenerator.GetSparkplugNodeDataB(SparkplugNamespace nameSpace, String groupIdentifier, String edgeNodeIdentifier, IEnumerable`1 metrics, Int32 sequenceNumber, DateTimeOffset dateTime)
at SparkplugNet.Core.Messages.SparkplugMessageGenerator.GetSparkplugNodeDataMessage[T](SparkplugNamespace nameSpace, String groupIdentifier, String edgeNodeIdentifier, IEnumerable`1 metrics, Int32 sequenceNumber, Int64 sessionNumber, DateTimeOffset dateTime)
at SparkplugNet.VersionB.SparkplugNode.PublishMessage(IEnumerable`1 metrics)
at SparkplugNet.Core.Node.SparkplugNodeBase`1.PublishMetrics(IEnumerable`1 metrics)
As far as I can tell, the correct approach for sending negative values with the current sparkplug specification is the following:
- Set correct Metric.datatype field e.g. Int32
- Cast the INT32 Value, for example “-32” to UINT32, e.g. “4294967264”
- Add the converted value as metric.int_value
- Send via MQTT
I have seen this described here and here and have tested it using Node-RED. Looks like it is working well.
Update: I have tested this approach with AVEVA System Platform MQTT driver and it interprets 4294967264 with Int32 datatype correctly as -32.
Could this logic be part of SparkplugNet?
It seems like C# doesn't convert the types properly with Convert...
This is basically just:
int intValue = -32;
uint uintValue = unchecked((uint)intValue);
Console.WriteLine(uintValue);
I have updated the tests and nearly fixed this in https://github.com/SeppPenner/SparkplugNet/commit/d3ff29bd4c26c35c8cf963955a7105349177e0c1. However, the conversions back from https://github.com/SeppPenner/SparkplugNet/blob/d3ff29bd4c26c35c8cf963955a7105349177e0c1/src/SparkplugNet/VersionB/PayloadConverter.cs#L219 and https://github.com/SeppPenner/SparkplugNet/blob/d3ff29bd4c26c35c8cf963955a7105349177e0c1/src/SparkplugNet/VersionB/PayloadConverter.cs#L224 don't work yet properly. Feel free to share your thoughts, I don't see the issue here yet...
This code is crazy now: https://github.com/SeppPenner/SparkplugNet/blob/758b561206807f8c46ee11e6594054ce3ca75ff8/src/SparkplugNet/Core/Extensions/DataTypeExtensions.cs#L1 :D
Thank you for the changes. ❤ It is working ok for my use case and I'm able to send negative values without any issue.