diff --git a/databroker-proto/build.rs b/databroker-proto/build.rs index d02a006d..60e40af6 100644 --- a/databroker-proto/build.rs +++ b/databroker-proto/build.rs @@ -23,6 +23,8 @@ fn main() -> Result<(), Box> { "proto/sdv/databroker/v1/collector.proto", "proto/kuksa/val/v1/val.proto", "proto/kuksa/val/v1/types.proto", + "proto/kuksa/val/v2/types.proto", + "proto/kuksa/val/v2/val.proto", ], &["proto"], )?; diff --git a/proto/kuksa/val/v2/types.proto b/proto/kuksa/val/v2/types.proto new file mode 100644 index 00000000..9adc6053 --- /dev/null +++ b/proto/kuksa/val/v2/types.proto @@ -0,0 +1,239 @@ +/******************************************************************************** + * Copyright (c) 2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License 2.0 which is available at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +syntax = "proto3"; + +package kuksa.val.v2; +import "google/protobuf/timestamp.proto"; + +option go_package = "kuksa/val/v2"; + +message Datapoint { + google.protobuf.Timestamp timestamp = 1; + + oneof value_state { + ValueFailure failure = 2; + Value value = 3; + } +} + +message Value { + oneof typed_value { + string string = 11; + bool bool = 12; + sint32 int32 = 13; + sint64 int64 = 14; + uint32 uint32 = 15; + uint64 uint64 = 16; + float float = 17; + double double = 18; + StringArray string_array = 21; + BoolArray bool_array = 22; + Int32Array int32_array = 23; + Int64Array int64_array = 24; + Uint32Array uint32_array = 25; + Uint64Array uint64_array = 26; + FloatArray float_array = 27; + DoubleArray double_array = 28; + } +} + +message SignalID { + oneof signal { + int32 id = 1; + string path = 2; + } +} + +message Error { + ErrorCode code = 1; + string message = 2; +} + +enum ErrorCode { + OK = 0; + INVALID_ARGUMENT = 1; + NOT_FOUND = 2; + PERMISSION_DENIED = 3; +} + +message Metadata { + // ID field + int32 id = 10; // Unique identifier for the metadata entry + + // Data type + // The VSS data type of the entry (i.e. the value, min, max etc). + // + // NOTE: protobuf doesn't have int8, int16, uint8 or uint16 which means + // that these values must be serialized as int32 and uint32 respectively. + DataType data_type = 11; // [field: FIELD_METADATA_DATA_TYPE] + + // Entry type + EntryType entry_type = 12; // [field: FIELD_METADATA_ENTRY_TYPE] + + // Description + // Describes the meaning and content of the entry. + optional string description = 13; // [field: FIELD_METADATA_DESCRIPTION] + + // Comment [optional] + // A comment can be used to provide additional informal information + // on a entry. + optional string comment = 14; // [field: FIELD_METADATA_COMMENT] + + // Deprecation [optional] + // Whether this entry is deprecated. Can contain recommendations of what + // to use instead. + optional string deprecation = 15; // [field: FIELD_METADATA_DEPRECATION] + + // Unit [optional] + // The unit of measurement + optional string unit = 16; // [field: FIELD_METADATA_UNIT] + + // Value restrictions [optional] + // Restrict which values are allowed. + // Only restrictions matching the DataType {datatype} above are valid. + ValueRestriction value_restriction = 17; // [field: FIELD_METADATA_VALUE_RESTRICTION] +} + +// Value restriction +// +// One ValueRestriction{type} for each type, since +// they don't make sense unless the types match +// +message ValueRestriction { + oneof type { + ValueRestrictionString string = 21; + // For signed VSS integers + ValueRestrictionInt signed = 22; + // For unsigned VSS integers + ValueRestrictionUint unsigned = 23; + // For floating point VSS values (float and double) + ValueRestrictionFloat floating_point = 24; + } +} + +message ValueRestrictionInt { + optional sint64 min = 1; + optional sint64 max = 2; + repeated sint64 allowed_values = 3; +} + +message ValueRestrictionUint { + optional uint64 min = 1; + optional uint64 max = 2; + repeated uint64 allowed_values = 3; +} + +message ValueRestrictionFloat { + optional double min = 1; + optional double max = 2; + + // allowed for doubles/floats not recommended + repeated double allowed_values = 3; +} + +// min, max doesn't make much sense for a string +message ValueRestrictionString { + repeated string allowed_values = 1; +} + +enum ValueFailure { + // Unspecified value failure, reserved for gRPC backwards compatibility + // (see https://protobuf.dev/programming-guides/dos-donts/#unspecified-enum) + UNSPECIFIED = 0; + // The signal is known and provided, but doesn't have a valid value + INVALID_VALUE = 1; + // The signal is known, but no value is provided currently + NOT_PROVIDED = 2; + // The referred signal is unknown on the system + UNKNOWN_SIGNAL = 3; + // The client does not have the necessary access rights to the signal + ACCESS_DENIED = 4; + // Unexpected internal error + INTERNAL_ERROR = 5; +} + +// VSS Data type of a signal +// +// Protobuf doesn't support int8, int16, uint8 or uint16. +// These are mapped to int32 and uint32 respectively. +// +enum DataType { + DATA_TYPE_UNSPECIFIED = 0; + DATA_TYPE_STRING = 1; + DATA_TYPE_BOOLEAN = 2; + DATA_TYPE_INT8 = 3; + DATA_TYPE_INT16 = 4; + DATA_TYPE_INT32 = 5; + DATA_TYPE_INT64 = 6; + DATA_TYPE_UINT8 = 7; + DATA_TYPE_UINT16 = 8; + DATA_TYPE_UINT32 = 9; + DATA_TYPE_UINT64 = 10; + DATA_TYPE_FLOAT = 11; + DATA_TYPE_DOUBLE = 12; + DATA_TYPE_TIMESTAMP = 13; + DATA_TYPE_STRING_ARRAY = 20; + DATA_TYPE_BOOLEAN_ARRAY = 21; + DATA_TYPE_INT8_ARRAY = 22; + DATA_TYPE_INT16_ARRAY = 23; + DATA_TYPE_INT32_ARRAY = 24; + DATA_TYPE_INT64_ARRAY = 25; + DATA_TYPE_UINT8_ARRAY = 26; + DATA_TYPE_UINT16_ARRAY = 27; + DATA_TYPE_UINT32_ARRAY = 28; + DATA_TYPE_UINT64_ARRAY = 29; + DATA_TYPE_FLOAT_ARRAY = 30; + DATA_TYPE_DOUBLE_ARRAY = 31; + DATA_TYPE_TIMESTAMP_ARRAY = 32; +} + +// Entry type +enum EntryType { + ENTRY_TYPE_UNSPECIFIED = 0; + ENTRY_TYPE_ATTRIBUTE = 1; + ENTRY_TYPE_SENSOR = 2; + ENTRY_TYPE_ACTUATOR = 3; +} + +message StringArray { + repeated string values = 1; +} + +message BoolArray { + repeated bool values = 1; +} + +message Int32Array { + repeated sint32 values = 1; +} + +message Int64Array { + repeated sint64 values = 1; +} + +message Uint32Array { + repeated uint32 values = 1; +} + +message Uint64Array { + repeated uint64 values = 1; +} + +message FloatArray { + repeated float values = 1; +} + +message DoubleArray { + repeated double values = 1; +} diff --git a/proto/kuksa/val/v2/val.proto b/proto/kuksa/val/v2/val.proto new file mode 100644 index 00000000..67d1a86f --- /dev/null +++ b/proto/kuksa/val/v2/val.proto @@ -0,0 +1,246 @@ +/******************************************************************************** + * Copyright (c) 2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License 2.0 which is available at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +syntax = "proto3"; + +package kuksa.val.v2; + +option go_package = "kuksa/val/v2"; + +import "kuksa/val/v2/types.proto"; + +service VAL { + // Get the latest value of a signal + // + // Returns (GRPC error code): + // NOT_FOUND if the requested signal doesn't exist + // PERMISSION_DENIED if access is denied + rpc GetValue(GetValueRequest) returns (GetValueResponse); + + // Get the latest values of a set of signals. + // The returned list of data points has the same order as the list of the request. + // + // Returns (GRPC error code): + // NOT_FOUND if any of the requested signals doesn't exist. + // PERMISSION_DENIED if access is denied for any of the requested signals. + rpc GetValues(GetValuesRequest) returns (GetValuesResponse); + + // List values of signals matching the request. + // + // Returns a list of signal values. Only values of signals that the user + // is allowed to read are included (everything else is ignored). + // + // Returns (GRPC error code): + // NOT_FOUND if the specified root branch does not exist. + rpc ListValues(ListValuesRequest) returns (ListValuesResponse); + + // Subscribe to a set of signals using string path parameters + // Returns (GRPC error code): + // NOT_FOUND if any of the signals are non-existant. + // PERMISSION_DENIED if access is denied for any of the signals. + rpc Subscribe(SubscribeRequest) returns (stream SubscribeResponse); + + // Subscribe to a set of signals using i32 id parameters + // Returns (GRPC error code): + // NOT_FOUND if any of the signals are non-existant. + // PERMISSION_DENIED if access is denied for any of the signals. + rpc SubscribeId(SubscribeRequestId) returns (stream SubscribeResponseId); + + // Actuate a single actuator + // + // Returns (GRPC error code): + // NOT_FOUND if the actuator does not exist. + // PERMISSION_DENIED if access is denied for of the actuator. + // UNAVAILABLE if there is no provider currently providing the actuator + // INVALID_ARGUMENT + // - if the data type used in the request does not match + // the data type of the addressed signal + // - if the requested value is not accepted, + // e.g. if sending an unsupported enum value + rpc Actuate(ActuateRequest) returns (ActuateResponse); + + // Actuate simultaneously multiple actuators. + // If any error occurs, the entire operation will be aborted + // and no single actuator value will be forwarded to the provider. + // + // Returns (GRPC error code): + // NOT_FOUND if any of the actuators are non-existant. + // PERMISSION_DENIED if access is denied for any of the actuators. + // UNAVAILABLE if there is no provider currently providing an actuator + // INVALID_ARGUMENT + // - if the data type used in the request does not match + // the data type of the addressed signal + // - if the requested value is not accepted, + // e.g. if sending an unsupported enum value + rpc BatchActuate(BatchActuateRequest) returns (BatchActuateResponse); + + // List metadata of signals matching the request. + // + // Returns (GRPC error code): + // NOT_FOUND if the specified root branch does not exist. + rpc ListMetadata(ListMetadataRequest) returns (ListMetadataResponse); + + // Publish a signal value. Used for low frequency signals (e.g. attributes). + // + // Returns (GRPC error code): + // NOT_FOUND if any of the signals are non-existant. + // PERMISSION_DENIED + // - if access is denied for any of the signals. + // - if the signal is already provided by another provider. + // INVALID_ARGUMENT + // - if the data type used in the request does not match + // the data type of the addressed signal + // - if the published value is not accepted, + // e.g. if sending an unsupported enum value + rpc PublishValue(PublishValueRequest) returns (PublishValueResponse); + + // Open a stream used to provide actuation and/or publishing values using + // a streaming interface. Used to provide actuators and to enable high frequency + // updates of values. + // + // The open stream is used for request / response type communication between the + // provider and server (where the initiator of a request can vary). + // Errors are communicated as messages in the stream. + rpc OpenProviderStream(stream OpenProviderStreamRequest) returns (stream OpenProviderStreamResponse); + + // Get server information + rpc GetServerInfo(GetServerInfoRequest) returns (GetServerInfoResponse); +} + +message GetValueRequest { + SignalID signal_id = 1; +} + +message GetValueResponse { + Datapoint data_point = 1; +} + +message GetValuesRequest { + repeated SignalID signal_ids = 1; +} + +message GetValuesResponse { + repeated Datapoint datapoints = 1; +} + +message ListValuesRequest { + repeated SignalID signal_ids = 1; +} + +message ListValuesResponse { + repeated Datapoint datapoints = 1; +} + +message SubscribeRequest { + repeated string signal_paths = 1; +} + +message SubscribeResponse { + map entries = 1; +} + +message SubscribeRequestId { + repeated int32 signal_ids = 1; +} + +message SubscribeResponseId { + map entries = 1; +} + +message ActuateRequest { + SignalID signal_id = 1; + Value value = 2; +} + +message ActuateResponse { +} + +message BatchActuateRequest { + repeated ActuateRequest actuate_requests = 1; +} + +message BatchActuateResponse { +} + +message ListMetadataRequest { + string root = 1; + string filter = 2; +} + +message ListMetadataResponse { + repeated Metadata metadata = 1; +} + +message PublishValueRequest { + SignalID signal_id = 1; + Datapoint data_point = 2; +} + +message PublishValueResponse { +} + +message PublishValuesRequest { + int32 request_id = 1; /// Unique request id for the stream that can be used to identify the response. + map datapoints = 2; +} + +message PublishValuesResponse { + int32 request_id = 1; + map status = 2; +} + +message ProvidedActuation { + repeated SignalID actuator_identifiers = 1; +} + +message ProvideActuatorResponse { +} + +message BatchActuateStreamRequest { + repeated ActuateRequest actuate_requests = 1; +} + +message BatchActuateStreamResponse { +} + +message OpenProviderStreamRequest { + oneof action { + // Inform server of an actuator this provider provides. + ProvidedActuation provided_actuation = 1; + // Publish a value. + PublishValuesRequest publish_values_request = 2; + // Sent to acknowledge the acceptance of a batch actuate + // request. + BatchActuateStreamResponse batch_actuate_stream_response = 3; + } +} + +message OpenProviderStreamResponse { + oneof action { + // Response to a provide actuator request. + ProvideActuatorResponse provide_actuator_response = 1; + // Acknowledgement that a published value was received. + PublishValuesResponse publish_values_response = 2; + // Send a batch actuate request to a provider. + BatchActuateStreamRequest batch_actuate_stream_request = 3; + } +} + +message GetServerInfoRequest { + // Nothing yet +} + +message GetServerInfoResponse { + string name = 1; + string version = 2; +}