From 740c1c2201178d53f1d90da6a2d3fafc85a1c2bb Mon Sep 17 00:00:00 2001 From: wes-johnson Date: Mon, 3 Mar 2025 16:05:28 -0800 Subject: [PATCH] [#62] Modified Sparkplug to support signed integer types --- .../chapters/Sparkplug_2_Principles.adoc | 2 +- .../Sparkplug_5_Operational_Behavior.adoc | 8 ++ .../chapters/Sparkplug_6_Payloads.adoc | 85 +++++++++++-------- 3 files changed, 59 insertions(+), 36 deletions(-) diff --git a/specification/src/main/asciidoc/chapters/Sparkplug_2_Principles.adoc b/specification/src/main/asciidoc/chapters/Sparkplug_2_Principles.adoc index 4e26d932..c150d284 100644 --- a/specification/src/main/asciidoc/chapters/Sparkplug_2_Principles.adoc +++ b/specification/src/main/asciidoc/chapters/Sparkplug_2_Principles.adoc @@ -86,7 +86,7 @@ timer. === Birth and Death Certificates Birth and Death Certificates are used by both Edge Nodes and Host Applications. Death Certificates -for both, are always registered in the MQTT CONNECT packet as the MQTT Will Message. By using the +for both are always registered in the MQTT CONNECT packet as the MQTT Will Message. By using the MQTT Will message, the Death Certificates will be delivered to subscribers even if the MQTT client connection is lost ungracefully. For Edge Nodes, the Death Certificate uses the NDEATH Sparkplug verb in the topic. For Host Applications, the spBv1.0/STATE/sparkplug_host_id topic is used. More diff --git a/specification/src/main/asciidoc/chapters/Sparkplug_5_Operational_Behavior.adoc b/specification/src/main/asciidoc/chapters/Sparkplug_5_Operational_Behavior.adoc index a8c037eb..55a61d8a 100644 --- a/specification/src/main/asciidoc/chapters/Sparkplug_5_Operational_Behavior.adoc +++ b/specification/src/main/asciidoc/chapters/Sparkplug_5_Operational_Behavior.adoc @@ -898,6 +898,10 @@ long as they have different timestamps. * [tck-testable tck-id-operational-behavior-data-publish-nbirth-order]#[yellow-background]*[tck-id-operational-behavior-data-publish-nbirth-order] For all metrics where is_historical=false, NBIRTH and NDATA messages MUST keep metric values in chronological order in the list of metrics in the payload.*# +* [tck-testable tck-id-operational-behavior-data-publish-node-metric-datatype]#[yellow-background]*[tck-id-operational-behavior-data-publish-node-metric-datatype] For +all metrics in an NBIRTH, the datatype and corresponding protobuf datatype MUST NOT change in +subsequent NDATA messages. If it does, the Host Application MUST send a rebirth request to the +offending Edge Node.*# Rules for Device data (DBIRTH and DDATA) messages: @@ -920,6 +924,10 @@ long as they have different timestamps. * [tck-testable tck-id-operational-behavior-data-publish-dbirth-order]#[yellow-background]*[tck-id-operational-behavior-data-publish-dbirth-order] For all metrics where is_historical=false, DBIRTH and DDATA messages MUST keep metric values in chronological order in the list of metrics in the payload.*# +* [tck-testable tck-id-operational-behavior-data-publish-device-metric-datatype]#[yellow-background]*[tck-id-operational-behavior-data-publish-device-metric-datatype] For +all metrics in an DBIRTH, the datatype and corresponding protobuf datatype MUST NOT change in +subsequent DDATA messages. If it does, the Host Application MUST send a rebirth request to the +offending Edge Node.*# [[operational_behavior_commands]] === Commands diff --git a/specification/src/main/asciidoc/chapters/Sparkplug_6_Payloads.adoc b/specification/src/main/asciidoc/chapters/Sparkplug_6_Payloads.adoc index 6b747e20..6a2a8bf7 100644 --- a/specification/src/main/asciidoc/chapters/Sparkplug_6_Payloads.adoc +++ b/specification/src/main/asciidoc/chapters/Sparkplug_6_Payloads.adoc @@ -189,13 +189,17 @@ message Payload { optional uint32 type = 2; oneof value { - uint32 int_value = 3; - uint64 long_value = 4; - float float_value = 5; - double double_value = 6; - bool boolean_value = 7; - string string_value = 8; - ParameterValueExtension extension_value = 9; + int32 int32_value = 3; + int64 int64_value = 4; + uint32 uint32_value = 5; + uint64 uint64_value = 6; + float float_value = 7; + double double_value = 8; + bool boolean_value = 9; + string string_value = 10; + bytes bytes_value = 11; + + ParameterValueExtension extension_value = 12; } message ParameterValueExtension { @@ -238,15 +242,19 @@ message Payload { optional bool is_null = 2; oneof value { - uint32 int_value = 3; - uint64 long_value = 4; - float float_value = 5; - double double_value = 6; - bool boolean_value = 7; - string string_value = 8; - PropertySet propertyset_value = 9; - PropertySetList propertysets_value = 10; // List of Property Values - PropertyValueExtension extension_value = 11; + int32 int32_value = 3; + int64 int64_value = 4; + uint32 uint32_value = 5; + uint64 uint64_value = 6; + float float_value = 7; + double double_value = 8; + bool boolean_value = 9; + string string_value = 10; + bytes bytes_value = 11; // Bytes, File + DataSet dataset_value = 12; + PropertySet propertyset_value = 13; + PropertySetList propertysets_value = 14; // List of Property Values + PropertyValueExtension extension_value = 15; } message PropertyValueExtension { @@ -284,7 +292,7 @@ message Payload { optional string engUnit = 9; // Engineering units // Future expansion - extensions 9 to max; + extensions 10 to max; } message Metric { @@ -297,20 +305,22 @@ message Payload { optional bool is_historical = 6; // If this is historical data and should not update real time tag optional bool is_transient = 7; // Tells consuming clients such as MQTT Engine to not store this as a tag optional bool is_null = 8; // If this is null - explicitly say so rather than using -1, false, etc for some datatypes. - optional MetaData metadata = 9; // Metadata for the payload - optional PropertySet properties = 10; + optional MetaData metadata = 9; // Metadata for the Metric + optional PropertySet properties = 10; // Properties of the Metric 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; + int32 int32_value = 11; + int64 int64_value = 12; + uint32 uint32_value = 13; + uint64 uint64_value = 14; + float float_value = 15; + double double_value = 16; + bool boolean_value = 17; + string string_value = 18; + bytes bytes_value = 19; // Bytes, File + DataSet dataset_value = 20; + Template template_value = 21; + MetricValueExtension extension_value = 22; } message MetricValueExtension { @@ -632,12 +642,17 @@ B’s mechanism of explicitly denoting a property’s value is actually null. supplied with a metric MUST be one of the following types. Note if the metrics is_null flag is set to true the value can be omitted altogether. More information on the Google Protocol Buffer types can be found here: https://developers.google.com/protocol-buffers/docs/proto#scalar +*** Google Protocol Buffer Type: _int32_ +*** Google Protocol Buffer Type: _int64_ *** Google Protocol Buffer Type: _uint32_ *** Google Protocol Buffer Type: _uint64_ *** Google Protocol Buffer Type: _float_ *** Google Protocol Buffer Type: _double_ *** Google Protocol Buffer Type: _bool_ *** Google Protocol Buffer Type: _string_ +*** Google Protocol Buffer Type: _bytes_ +*** Sparkplug _DataSet_ +**** Defined link:#payloads_b_dataset[here]. *** Sparkplug _PropertySet_ **** Defined link:#payloads_b_propertyset[here]. *** Sparkplug _PropertySetList_ @@ -832,8 +847,8 @@ MUST be included in Template Parameter Definitions in NBIRTH and DBIRTH messages * *value* ** The value of a template parameter utilizes the ‘oneof’ mechanism of Google Protocol Buffers. ** [tck-testable tck-id-payloads-template-parameter-value]#[yellow-background]*[tck-id-payloads-template-parameter-value] The -value supplied MUST be one of the following Google Protocol Buffer types: _uint32_, _uint64_, -_float_, _double_, _bool_, or _string_.*# +value supplied MUST be one of the following Google Protocol Buffer types: _int32_, int64_, _uint32_, +_uint64_, _float_, _double_, _bool_, _string_, or _bytes_.*# *** More information on these types can be found here: https://developers.google.com/protocol-buffers/docs/proto#scalar ** For a template definition, this is the default value of the parameter. For a template instance, @@ -906,19 +921,19 @@ enum DataType { *** Sparkplug enum value: 0 ** _Int8_ *** Signed 8-bit integer -*** Google Protocol Buffer Type: uint32 +*** Google Protocol Buffer Type: int32 *** Sparkplug enum value: 1 ** _Int16_ *** Signed 16-bit integer -*** Google Protocol Buffer Type: uint32 +*** Google Protocol Buffer Type: int32 *** Sparkplug enum value: 2 ** _Int32_ *** Signed 32-bit integer -*** Google Protocol Buffer Type: uint32 +*** Google Protocol Buffer Type: int32 *** Sparkplug enum value: 3 ** _Int64_ *** Signed 64-bit integer -*** Google Protocol Buffer Type: uint64 +*** Google Protocol Buffer Type: int64 *** Sparkplug enum value: 4 ** _UInt8_ *** Unsigned 8-bit integer