Protobuf Support

"Protobuf" refers to "protocol buffers". This is a Google® specification for messages that contain serialized, structured data. It is used by several 3rd party tools including Sparkplug B®

 

The format of the data is typically predetermined and shared prior to the data itself, and can form the basis of protocols. A Protobuf specification consists of one or more messages, which contain fields. There are various field types available (string, double, float, various signed/unsigned integer types). See the proto2 language guide for further details.

Message naming

Where a function takes a Protobuf message name, this is the full name, including the package name. For nested messages this also includes all parent messages. For example, in this Protobuf specification:

syntax = "proto2";
package com.trihedral.protobuf.example;
message Data {
  message SubData {
    required string name = 1;
  }
  required double  double_val  = 1;
  required SubData sub_message = 2;
}

The SubData message would be referred to as com.trihedral.protobuf.example.Data.SubData.

Groups

Decoding and encoding of Protobuf 2 (proto2) groups is not supported.

oneof

Protobuf has a concept, oneof, which defines a set of values where only one is present. If more than one of the values is set when encoding, then the value that is selected to be encoded is undefined.

 

Decoding of values from a oneof field requires drilling down into the individual field metric component.

Example: For Sparkplug B, the metric message has a oneof field called value consisting of various options such as int_value, boolean_value, string_value, etc. Thus for the following decode statement:

DecodedData = ProtobufDecode(Handle, Msg, EncodedData);

If the returned value is of integer format, then to extract the value, the proper call is DecodedData.int_value, not DecodedData.value. Similarly for encoding, the encoded value needs to be placed into the lower level element of int_value, not the higher level value.

Mapping of Protobuf types to VTScada types

Many data types have a straightforward equivalent. For example float / double in Protobuf is converted to or from a double (#VTypeDouble) and Protobuf byte/string are converted to/from VTScada strings (#VTypeString).

Protobuf repeated fields are converted to or from VTScada arrays, Protobuf maps are converted to or from VTScada dictionaries, and messages are converted to or from VTScada structures. When encoding, any value that can be cast to the target type will be converted.

Performance considerations

Repeatedly parsing a Protobuf specification is a computationally expensive task. If messages of a type are repeatedly encoded and decoded, reusing the handle value from ProtobufParse is recommended. An example of this would be a driver handling Protobuf encoded data.

VTScada's Protobuf API