Sparkplug: How to deal with negative signed integers?

On the sparkplug protocol there are the following “Basic types” defined:

    // Basic Types
    Int8            = 1;
    Int16           = 2;
    Int32           = 3;
    Int64           = 4;
    UInt8           = 5;
    UInt16          = 6;
    UInt32          = 7;
    UInt64          = 8;
    Float           = 9;
    Double          = 10;
    Boolean         = 11;
    String          = 12;
    DateTime        = 13;
    Text            = 14;

However, inside the message Metric definition, the (signed) integers are ignored and only the unsigned integer from GoogleProtobuf are used for dealing with int_value and long_value inside the “oneof value” part:

message Metric {
    # Other defs removed for clearness
    oneof value {
        uint32   int_value                      = 10;
        uint64   long_value                     = 11;
        float    float_value                    = 12;
        double   double_value                   = 13;
        bool     boolean_value                  = 14;
        string   string_value                   = 15;
        bytes    bytes_value                    = 16;       // Bytes, File
        DataSet  dataset_value                  = 17;
        Template template_value                 = 18;
        MetricValueExtension extension_value    = 19;
    }
}

On Protocol Buffers - Scalar Value Types the .proto Type “uint32/64” is equivalent to “uint32/64” of C++, this means that I’m not able to use C++ signed integers (int32/64) directly on Sparkplug.

What “oneof value” should I use for transferring negative signed integers (C++type = int32/64) on Sparkplug?

I’m now able to transfer negative numbers on my payload.

Here what I’ve done

  1. Set the metric.datatype correctly, e.g. INT32
  2. Cast the INT32 Value, for example “-32” to UINT32, e.g. “4294967264”
  3. Add the converted value as metric.int_value
  4. Send via MQTT
  5. On MQTTFx the Sparkplug Decoder shows the “-32”:
    {"timestamp":1607590027225,"metrics":[{"name":"MyINT32","timestamp":1607590027225,"dataType":"Int32","value":-32}],"seq":0}

Is this the way to go?

Would it not be better to have the following Message Metric definition?

message Metric {
    # Other defs removed for clearness
    oneof value {
        sint32   sint_value                      = 10;
        sint64   slong_value                     = 11;
        uint32   uint_value                      = 12;
        uint64   ulong_value                     = 13;
        float    float_value                     = 14;
        double   double_value                    = 15;
        bool     boolean_value                   = 16;
        string   string_value                    = 17;
        bytes    bytes_value                     = 18;       // Bytes, File
        DataSet  dataset_value                   = 19;
        Template template_value                  = 20;
        MetricValueExtension extension_value     = 21;
    }
}
2 Likes

Hello nhosko

Thanks for reaching out. Nice to see that you’re taking interest in Sparkplug.

Your solution to transfer negative numbers looks good.

Thanks & Regards,
Sheetal from the HiveMQ Team