diff --git a/assets/project-overview.svg b/assets/project-overview.svg index 0aec4790..9dbec8c9 100644 --- a/assets/project-overview.svg +++ b/assets/project-overview.svg @@ -1,4 +1,4 @@ -
extends
extends
Vehicle App SDK
Vehicle App SDK
Seat Adjuster Vehicle App
Seat Adjuster Vehicl...
uses
uses
uses
uses
Devcontainer
Devcontainer
KUKSA Databroker
KUKSA Databroker
Seats Service
Seats Service
install KUKSA Databroker
install KUKSA Databroker
install Seats Service
install Seats Service
Developer Manual
Developer Manual
Unit tests
Unit tests
Integration tests
Integration tests
test
test
test
test
SDV package
SDV package
Unit tests
Unit tests
Integration tests
Integration tests
test
test
test
test
uses
uses
uses
uses
GH Workflows
GH Workflows
Render Action
Render Action
Package Action
Package Action
release-documentation-action
[Repository]
release-documentation-action...
KUKSA.VAL
[Repository]
KUKSA.VAL
vehicle-app-python-template
[Repository]
vehicle-app-python-template...
sdv-vehicle-app-python-sdk
[Repository]
sdv-vehicle-app-python-sdk...
Unit tests
Unit tests
Integration tests
Integration tests
SDV package
SDV package
Unit tests
Unit tests
Integration tests
Integration tests
KUKSA Databroker
KUKSA Databroker
Render Action
Render Action
Package Action
Package Action
Developer Manual
Developer Manual
Data Feeder
Data Feeder
Text is not SVG - cannot display
+
extends
extends
Vehicle App SDK
Vehicle App SDK
Seat Adjuster Vehicle App
Seat Adjuster Vehicl...
uses
uses
uses
uses
Devcontainer
Devcontainer
KUKSA Databroker
KUKSA Databroker
Seats Service
Seats Service
install KUKSA Databroker
install KUKSA Databroker
install Seats Service
install Seats Service
Developer Manual
Developer Manual
Unit tests
Unit tests
Integration tests
Integration tests
test
test
test
test
SDV package
SDV package
Unit tests
Unit tests
Integration tests
Integration tests
test
test
test
test
uses
uses
uses
uses
GH Workflows
GH Workflows
Render Action
Render Action
Package Action
Package Action
release-documentation-action
[Repository]
release-documentation-action...
KUKSA
[Repository]
KUKSA
vehicle-app-python-template
[Repository]
vehicle-app-python-template...
sdv-vehicle-app-python-sdk
[Repository]
sdv-vehicle-app-python-sdk...
Unit tests
Unit tests
Integration tests
Integration tests
SDV package
SDV package
Unit tests
Unit tests
Integration tests
Integration tests
KUKSA Databroker
KUKSA Databroker
Render Action
Render Action
Package Action
Package Action
Developer Manual
Developer Manual
Data Feeder
Data Feeder
Text is not SVG - cannot display
diff --git a/categories/index.html b/categories/index.html index edf189ea..cb87c773 100644 --- a/categories/index.html +++ b/categories/index.html @@ -85,7 +85,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/community/_print/index.html b/community/_print/index.html index 6fc47fca..22f493a2 100644 --- a/community/_print/index.html +++ b/community/_print/index.html @@ -86,7 +86,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/community/index.html b/community/index.html index d48ec8eb..928bb737 100644 --- a/community/index.html +++ b/community/index.html @@ -86,7 +86,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/_print/index.html b/docs/_print/index.html index a6257bc6..414d579f 100644 --- a/docs/_print/index.html +++ b/docs/_print/index.html @@ -86,7 +86,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -289,6 +289,14 @@

Velocitas

+ + + +
  • 2.1.2.1: GRPC Interface Style Guide
  • + + + + @@ -804,7 +812,42 @@

    Velocitas

    -
  • 3.6: Vehicle App Deployment
  • +
  • 3.6: gRPC service generation
  • + + + + + + + + + +
  • 3.7: Vehicle App Deployment
  • @@ -924,7 +967,7 @@

    Features

  • Project lifecycle management to update Vehicle App repositories via CLI.
  • Vehicle abstraction support helps to focus on business logic by using a generated vehicle model on code level with type safety and auto-completion. The vehicle model is generated from a standardized API that hides the details of vehicle-specific signals and E/E architecture, allowing Vehicle Apps to be portable across different electronics and software architectures.
  • Microsoft Visual Studio Code integration with DevContainer helps to install everything required to start the local development immediately, while tasks and launch configurations help to launch runtime services, other apps, and tests.
  • -
  • Vehicle App skeleton and examples helps to understand easily how to write a Vehicle App using the KUKSA.VAL runtime services.
  • +
  • Vehicle App skeleton and examples helps to understand easily how to write a Vehicle App using the KUKSA runtime services.
  • Ready-to-use CI/CD workflows that build (for multi architectures), test, document and deploy a containerized Vehicle App with no dependencies to E/E architecture help saving setup time.
  • Language Support

    @@ -1271,12 +1314,9 @@

    1.2 - Repository Overview

    -kuksa.val.services +kuksa-incubation -Provides exemplary vehicle services and respective implementations that illustrates how to interact with in-vehicle components and services via an unified access that is semantically described e.g. in the - -Vehicle Service Catalog (VSC) -. +Provides exemplary vehicle services and respective implementations that illustrates how to interact with in-vehicle components and services via an unified access. @@ -1508,21 +1548,14 @@

    Semantic models

    VSS ) provides a domain taxonomy for vehicle signals and defines the vehicle data semantically, which is exchanged between Vehicle Apps and the Databroker.

    -

    The Vehicle Service Catalog ( - -VSC -) extends VSS with functional remote procedure call definitions and semantically defines the gRPC interfaces of Vehicle Services and Vehicle Apps.

    -

    As an alternative to VSS and VSC, vehicle data and services can be defined semantically in a general IoT modelling language like Digital Twin Definition Language ( - -DTDL -) or BAMM Aspect Meta Model - -BAMM - as well.

    The Velocitas SDK is using VSS - as the semantic model for the Vehicle Model.

    + as the semantic model for the Vehicle Model. +Vehicle Service models can be defined with + +Protobuf service definitions +.

    Communication Protocols

    Asynchronous communication between @@ -1682,7 +1715,7 @@

    Vehicle Model Ontology

    The Vehicle Model is a tree-based model where every branch in the tree, including the root, is derived from the Model base class provided by the SDK.

    The Vehicle Model Ontology consists of the following classes:

    Model

    -

    A model contains services, data points and other models. It corresponds to branch entries in VSS, interfaces in DTDL or namespaces in VSC.

    +

    A model contains data points (leaves) and other models (branches).

    ModelCollection

    @@ -2405,13 +2438,13 @@

    Introduction

    COVESA Vehicle Signal Specification (VSS) . The Vehicle API eliminates the need to know the source, destination, and format of signals for the vehicle system.

    -

    The Eclipse Velocitas project is using the VAL of the +

    The Eclipse Velocitas project is using the Eclipse KUKSA project -, also called KUKSA.VAL. -KUKSA.VAL does not provide a concrete VAL. That’s up to you as an OEM (vehicle manufacturer) or as a supplier. -But KUKSA.VAL provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an Vehicle App or Service.

    -

    KUKSA.VAL provides you with ready-to-use generic components for the signal-based access to the vehicle, like the KUKSA Databroker and the generic Data Providers (aka Data Feeders). +. +KUKSA does not provide a concrete VAL. That’s up to you as an OEM (vehicle manufacturer) or as a supplier. +But KUKSA provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an Vehicle App or Service.

    +

    KUKSA provides you with ready-to-use generic components for the signal-based access to the vehicle, like the KUKSA Databroker and the generic Data Providers (aka Data Feeders). It also provides you reference implementations of certain Vehicle Services, like the Seat Service and the HVAC Service.

    Architecture

    The image below shows the main components of the VAL and its relation to the @@ -2453,7 +2486,7 @@

    Vehicle Services

    It communicates with the Hardware Abstraction to execute the underlying services, but may also interact with the Databroker.

    The -KUKSA.VAL Services repository +KUKSA Incubation repository contains examples illustrating how such kind of vehicle services can be built.

    Hardware Abstraction

    Data feeders rely on hardware abstraction. Hardware abstraction is project/platform specific. @@ -2546,13 +2579,11 @@

    Source Code

    KUKSA example providers -

    Guidelines

    - +GRPC Interface Style Guide +

    @@ -2569,6 +2600,291 @@

    Guidelines

    + + + + + +
    + +

    2.1.2.1 - GRPC Interface Style Guide

    + +

    This provides a style guide for .proto files. By following these conventions, you’ll make your protocol buffer message definitions and their corresponding classes consistent and easy to read. +Unless otherwise indicated, this style guide is based on the style guide from + +google protocol-buffers style + under Apache 2.0 License & Creative Commons Attribution 4.0 License.

    +

    Note that protocol buffer style can evolve over time, so it is likely that you will see .proto files written in different conventions or styles. Please respect the existing style when you modify these files. Consistency is key. However, it is best to adopt the current best style when you are creating a new .proto file.

    +

    Standard file formatting

    + +

    File structure

    +

    Files should be named lower_snake_case.proto

    +

    All files should be ordered in the following manner:

    + +

    Directory Structure

    +

    Files should be stored in a directory structure that matches their package sub-names. All files +in a given directory should be in the same package. +Below is an example based on the + +proto files + in the kuksa.-databroker repository.

    +
    |   proto/
    +|   └── sdv
    +|       └── databroker
    +|           └── v1                  // package sdv.databroker.broker.v1
    +|               ├── broker.proto    // service Broker in sdv.databroker.broker.v1
    +|               ├── collector.proto // service Collector in sdv.databroker.broker.v1
    +|               └── types.proto     // type definition and import of  in sdv.databroker.broker.v1
    +

    The proposed structure shown above is adapted from + +Uber Protobuf Style Guide V2 + under MIT License.

    +

    Packages

    +

    Package names should be in lowercase. Package names should have unique names based on the project name, and possibly based on the path of the file containing the protocol buffer type definitions.

    +

    Message and field names

    +

    Use PascalCase (CamelCase with an initial capital) for message names – for example, SongServerRequest. Use underscore_separated_names for field names (including oneof field and extension names) – for example, song_name.

    +
    message SongServerRequest {
    +   optional string song_name = 1;
    +}
    +

    Using this naming convention for field names gives you accessors like the following:

    +

    C++:

    +
    const string& song_name() { ... }
    +void set_song_name(const string& x) { ... }
    +

    If your field name contains a number, the number should appear after the letter instead of after the underscore. For example, use song_name1 instead of song_name_1 +Repeated fields

    +

    Use pluralized names for repeated fields.

    +
    repeated string keys = 1;
    +...
    +repeated MyMessage accounts = 17;
    +

    Enums

    +

    Use PascalCase (with an initial capital) for enum type names and CAPITALS_WITH_UNDERSCORES for value names:

    +
    enum FooBar {
    +   FOO_BAR_UNSPECIFIED = 0;
    +   FOO_BAR_FIRST_VALUE = 1;
    +   FOO_BAR_SECOND_VALUE = 2;
    +}
    +

    Each enum value should end with a semicolon, not a comma. The zero value enum should have the suffix UNSPECIFIED.

    +

    Services

    +

    If your .proto defines an RPC service, you should use PascalCase (with an initial capital) for both the service name and any RPC method names:

    +
    service FooService {
    +   rpc GetSomething(GetSomethingRequest) returns (GetSomethingResponse);
    +   rpc ListSomething(ListSomethingRequest) returns (ListSomethingResponse);
    +}
    +

    GRPC Interface Versioning

    +

    All API interfaces must provide a major version number, which is encoded at the end of the protobuf package. +If an API introduces a breaking change, such as removing or renaming a field, it must increment its API version number to ensure that existing user code does not suddenly break. +Note: The use of the term “major version number” above is taken from semantic versioning. However, unlike in traditional semantic versioning, APIs must not expose minor or patch version numbers. +For example, APIs use v1, not v1.0, v1.1, or v1.4.2. From a user’s perspective, minor versions are updated in place, and users receive new functionality without migration.

    +

    A new major version of an API must not depend on a previous major version of the same API. An API may depend on other APIs, with an expectation that the caller understands the dependency and stability risk associated with those APIs. In this scenario, a stable API version must only depend on stable versions of other APIs.

    +

    Different versions of the same API should preferably be able to work at the same time within a single client application for a reasonable transition period. This time period allows the client to transition smoothly to the newer version. An older version must go through a reasonable, well-communicated deprecation period before being shut down.

    +

    For releases that have alpha or beta stability, APIs must append the stability level after the major version number in the protobuf package.

    +

    Release-based versioning

    +

    An individual release is an alpha or beta release that is expected to be available for a limited time period before its functionality is incorporated into the stable channel, after which the individual release will be shut down. +When using release-based versioning strategy, an API may have any number of individual releases at each stability level.

    +

    Alpha and beta releases must have their stability level appended to the version, followed by an incrementing release number. For example, v1beta1 or v1alpha5. APIs should document the chronological order of these versions in their documentation (such as comments). +Each alpha or beta release may be updated in place with backwards-compatible changes. For beta releases, backwards-incompatible updates should be made by incrementing the release number and publishing a new release with the change. For example, if the current version is v1beta1, then v1beta2 is released next.

    +

    Adapted from + +google release-based_versioning + under Apache 2.0 License & Creative Commons Attribution 4.0 License

    +

    Backwards compatibility

    +

    The gRPC protocol is designed to support services that change over time. Generally, additions to gRPC services and methods are non-breaking. Non-breaking changes allow existing clients to continue working without changes. Changing or deleting gRPC services are breaking changes. When gRPC services have breaking changes, clients using that service have to be updated and redeployed.

    +

    Making non-breaking changes to a service has a number of benefits:

    + +

    Non-breaking changes

    +

    These changes are non-breaking at a gRPC protocol level and binary level.

    + +

    Binary breaking changes

    +

    The following changes are non-breaking at a gRPC protocol level, but the client needs to be updated if it upgrades to the latest .proto contract. Binary compatibility is important if you plan to publish a gRPC library.

    + +

    Protocol breaking changes

    +

    The following items are protocol and binary breaking changes:

    + +

    Behavior breaking changes

    +

    When making non-breaking changes, you must also consider whether older clients can continue working with the new service behavior. For example, adding a new field to a request message:

    + +

    Behavior compatibility is determined by your app-specific code.

    +

    Adapted from + +Versioning gRPC services + under Creative Commons Attribution 4.0 License

    +

    gRPC Error Handling

    +

    In gRPC, a large set of error codes has been + +defined + +As a general rule, SDV should use relevant gRPC error codes, +as described in + +this thread +

    +
       return grpc::Status(grpc::StatusCode::NOT_FOUND, "error details here");
    +

    Available constructor:

    +
       grpc::Status::Status ( StatusCode  code,
    +      const std::string & error_message,
    +      const std::string & error_details
    +

    The framework for drafting error messages could be useful as a later improvement. This could e.g., be used to specify which unit created the error message and to assure the same structure on all messages. The latter two may e.g., depend on debug settings, e.g., error details only in debug-builds to avoid leaks of sensitive information. A global function like below or similar could handle that and also possibly convert between internal error codes and gRPC codes.

    +
       grpc::Status status = CreateStatusMessage(PERMISSION_DENIED,"DataBroker","Rule access rights violated");
    +

    SDV error handling for gRPC interfaces (e.g., VAL vehicles services)

    + +

    SDV handling of gRPC error codes

    +

    The table below gives error code guidelines for each gRPC on:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    gRPC error codeRetry Relevant?Recommended SDV usage
    OKNoMandatory error code if operation succeeded. Shall never be used if operation failed.
    CANCELLEDNoNo explicit use case on server side in SDV identified
    UNKNOWNNoTo be used in default-statements when converting errors from e.g., Broker-errors to SDV/gRPC errors
    INVALID_ARGUMENTNoE.g., Rule syntax with errors
    DEADLINE_EXCEEDEDYesOnly applicable for asynchronous services, i.e. services which wait for completion before the result is returned. The behavior if an operation cannot finish within expected time must be defined. Two options exist. One is to return this error after e.g., X seconds. Another is that the server never gives up, but rather waits for the client to cancel the operation.
    NOT_FOUNDNoLong term situation that likely not will change in the near future.
    Example: SDV can not find the specified resource (e.g., no path to get data for specified seat)
    ALREADY_EXISTSNoNo explicit use case on server side in SDV identified
    PERMISSION_DENIEDNoOperation rejected due to permission denied
    RESOURCE_EXHAUSTEDYesPossibly if e.g., malloc fails or similar errors.
    FAILED_PRECONDITIONYesCould be returned if e.g., operation is rejected due to safety reasons. (E.g., vehicle moving)
    ABORTEDYesCould e.g., be returned if service does not support concurrent requests, and there is already either a related operation ongoing or the operation is aborted due to a newer request received. Could also be used if an operation is aborted on user/driver request, e.g., physical button in vehicle pressed.
    OUT_OF_RANGENoE.g., Arguments out of range
    UNIMPLEMENTEDNoTo be used if certain use-cases of the service are not implemented, e.g., if recline cannot be adjusted
    INTERNALNoInternal errors, like exceptions, unexpected null pointers and similar
    UNAVAILABLEYesTo be used if the service is temporarily unavailable, e.g., during system startup.
    DATA_LOSSNoNo explicit use case identified on server side in SDV.
    UNAUTHENTICATEDNoNo explicit use case identified on server side in SDV.
    +

    Other references

    + + +
    + + + + + + @@ -2932,6 +3248,15 @@

    Configuration structure

    URI of the used COVESA Vehicle Signal Specification JSON export. URI may point to a local file or to a file provided by a server.  +unit_src +string +["abs_path_unit_file_1", "abs_path_unit_file_2", "uri_unit_file_3"] +An array of URI’s/absolute path’s of the used COVESA Vehicle Signal Specification unit file(s) in yaml format. URI may point to a local file or to a file provided by a server. If none is provided a default one will be used ( + +https://github.com/COVESA/vehicle_signal_specification/blob/v4.0/spec/units.yaml) +.  + + datapoints object Object containing both required and provided datapoints. @@ -3002,7 +3327,9 @@

    Example

    } } } - +

    Different VSS versions

    +

    The model generation is supported for VSS versions up to v4.0. There are some changes for some paths from v3.0 to v4.0. For example Vehicle.Cabin.Seat.Row1.Pos1.Position in v3.0 is Vehicle.Cabin.Seat.Row1.DriverSide.Position in v4.0. If you are using the mock provider you would need to take that into account when you sepcify your mock.py.

    + @@ -3092,7 +3419,11 @@

    Configuration structure

    -

    Example

    +

    Execution

    +

    velocitas init +or +velocitas exec grpc-interface-support generate-sdk

    +

    Project configuration

    {
       "type": "grpc-interface",
       "config": {
    @@ -3101,10 +3432,23 @@ 

    Example

    "methods": [ "Move", "MoveComponent" ] - } + }, + "provided": { } } } -
    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    + @@ -3758,14 +4102,12 @@

    Interaction mockup

    > 3. Which API dependencies does your project have? [x] gRPC service [ ] uProtocol service -[x] Vehicle Service Catalogue > 4. Add an API dependency (y/n)? y > 5. What type of dependency? [x] gRPC-IF -[ ] VSC-IF > 6. URI of the .proto file? https://some-url/if.proto @@ -3780,7 +4122,6 @@

    Interaction mockup

    --name MyApp \ --lang cpp \ --package grpc-service-support \ - --package vsc-support \ --require grpc-interface:https://some-url/if.proto > Project created! @@ -5451,13 +5792,13 @@

    3.2.2 - Service Integration

    Modify existing services

    For more advanced usage you can also try to modify existing services. Check out -the seat service +the seat service for example, modify it and integrate it into your Vehicle App repository.

    Create your own services

    If you want to create your own service the -KUKSA.VAL Services repository - contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to KUKSA.VAL listening to changes of a target value of some VSS data point and then do whatever you want. You can achieve this by using the KUKSA.VAL +KUKSA Incubation repository + contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to KUKSA listening to changes of a target value of some VSS data point and then do whatever you want. You can achieve this by using the KUKSA gRPC API with any programming language of your choice (learn more about @@ -7033,7 +7374,7 @@

    Add a Vehicle Service

    As example you could use the protocol buffers message definition seats.proto - provided by the KUKSA.VAL services which describes a + provided by the KUKSA services which describes a seat control service .

    @@ -7467,7 +7808,271 @@

    Next steps

    -

    3.6 - Vehicle App Deployment

    +

    3.6 - gRPC service generation

    +
    Learn how to generate and fill your own gRPC services.
    +

    This tutorial shows how to generate a basic gRPC service like a seat service. For this example the proto file under + +https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto + is taken.

    +

    All files included from services/seats are auto-generated and added to the app project as Conan dependency. +For writing a complete gRPC service you need two velocitas apps/projects. +One is implementing a client and the other one is for providing the server. +To complete the server implementation you have to fill the generated *ServiceImpl.cpp. +Have a look at the linked content beneath for a tutorial how it would be done for a SeatService leveraging + +https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto +.

    +

    To run the example you need to start the velocitas app for the server first and then the second velocitas app for the client.

    + +
    + + + + + + + + + + + + + + + + + + + +
    + +

    3.6.1 - Create a client

    +
    Learn how to create a client for a service definition.
    +

    App configuration

    +
    {
    +  "type": "grpc-interface",
    +  "config": {
    +      "src": "https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto",
    +      // "required" indicates you are trying to write a client for the service
    +      "required": {
    +        "methods": [
    +          "Move", "CurrentPosition"
    +        ]
    +      },
    +  }
    +}
    +

    Project configuration

    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    +

    Example code

    +

    To create a client we use the generated SeatsServiceClientFactory.h and seats.grpc.pb.h. These define request and response types and the operations that are available. An example implementation for the SeatService follows:

    +

    main.cpp

    +
    #include <sdk/middleware/Middleware.h>
    +#include <services/seats/SeatsServiceClientFactory.h>
    +#include <services/seats/seats.grpc.pb.h>
    +
    +#include <iostream>
    +
    +using namespace velocitas;
    +
    +int main(int argc, char** argv) {
    +    auto serviceClient = SeatsServiceClientFactory::create(Middleware::getInstance());
    +
    +    ::grpc::ClientContext                        context;
    +    ::sdv::edge::comfort::seats::v1::MoveRequest request;
    +    ::sdv::edge::comfort::seats::v1::MoveReply   response;
    +
    +    ::sdv::edge::comfort::seats::v1::Seat seat;
    +
    +    ::sdv::edge::comfort::seats::v1::SeatLocation seat_location;
    +    seat_location.set_row(1);
    +    seat_location.set_index(1);
    +
    +    ::sdv::edge::comfort::seats::v1::Position seat_position;
    +    // we only set base here to keep the example simple
    +    // extend here if yu want to set lumbar etc.
    +    seat_position.set_base(1000);
    +
    +    seat.set_allocated_location(&seat_location);
    +    seat.set_allocated_position(&seat_position);
    +
    +    request.set_allocated_seat(&seat);
    +
    +    auto status = serviceClient->Move(&context, request, &response);
    +
    +    std::cout << "gRPC Server returned code: " << status.error_code() << std::endl;
    +    std::cout << "gRPC error message: " << status.error_message().c_str() << std::endl;
    +
    +    if (status.error_code() == ::grpc::StatusCode::UNIMPLEMENTED) {
    +        return 1;
    +    } else {
    +        ::grpc::ClientContext                                   context;
    +        ::sdv::edge::comfort::seats::v1::CurrentPositionRequest request;
    +        ::sdv::edge::comfort::seats::v1::CurrentPositionReply   response;
    +
    +        request.set_row(1);
    +        request.set_index(1);
    +
    +        auto status_curr_pos = seatService->CurrentPosition(&context, request, &response);
    +        std::cout << "current Position:" << response.seat().position().base() << std::endl;
    +        std::cout << "gRPC Server returned code: " << status_curr_pos.error_code() << std::endl;
    +        std::cout << "gRPC error message: " << status_curr_pos.error_message().c_str() << std::endl;
    +        return 0;
    +    }
    +}
    +
    +
    + + + + + + + + + + + +
    + +

    3.6.2 - Create a server

    +
    Learn how to create a server for a service definition.
    +

    App configuration

    +
    {
    +  "type": "grpc-interface",
    +  "config": {
    +      "src": "https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto",
    +      // "provided" indicates you want to implement the server business logic for the service
    +      "provided": { }
    +  }
    +}
    +

    Project configuration

    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    +

    To create a server that is providing the gRPC service we are leveraging the generated SeatsServiceImpl.h and SeatsServiceServerFactory.h. The SeatsServiceImpl.cpp needs to be filled with the actual implementation of the service. A quick example for a SeatService is described in the following:

    +

    main.cpp

    +
    #include <sdk/middleware/Middleware.h>
    +#include <services/seats/SeatsServiceServerFactory.h>
    +#include "SeatsServiceImpl.h"
    +
    +#include <memory>
    +
    +using namespace velocitas;
    +
    +int main(int argc, char** argv) {
    +    auto seatsImpl = std::make_shared<SeatsService>();
    +
    +    velocitas::VehicleModelContext::getInstance().setVdbc(
    +        velocitas::IVehicleDataBrokerClient::createInstance("vehicledatabroker"));
    +    auto seatServer =
    +        SeatsServiceServerFactory::create(Middleware::getInstance(), seatsImpl);
    +
    +    seatServer->Wait();
    +    return 0;
    +}
    +

    SeatsServiceImpl.cpp

    +
    #include "SeatsServiceImpl.h"
    +#include <sdk/VehicleApp.h>
    +#include <sdk/VehicleModelContext.h>
    +#include <sdk/vdb/IVehicleDataBrokerClient.h>
    +#include <vehicle/Vehicle.hpp>
    +#include <grpc/grpc.h>
    +#include <services/seats/seats.grpc.pb.h>
    +
    +namespace velocitas {
    +
    +::grpc::Status SeatsService::Move(::grpc::ServerContext*                              context,
    +                                  const ::sdv::edge::comfort::seats::v1::MoveRequest* request,
    +                                  ::sdv::edge::comfort::seats::v1::MoveReply*         response) {
    +    (void)context;
    +    (void)response;
    +    vehicle::Vehicle Vehicle;
    +
    +    auto seat     = request->seat();
    +    auto location = seat.location();
    +    auto row      = location.row();
    +    auto pos      = location.index();
    +
    +    // you would need to extend this to add support for lumbar etc.
    +    // Vehicle.Cabin.Seat.Row(row).Pos(pos).Position.set(seat->position()->xxxxxx())->await();
    +    auto status = Vehicle.Cabin.Seat.Row1.DriverSide.Position.set(seat.position().base())->await();
    +    if (status.ok()) {
    +        return ::grpc::Status(::grpc::StatusCode::OK, "");
    +    } else {
    +        return ::grpc::Status(::grpc::StatusCode::CANCELLED, status.errorMessage());
    +    }
    +}
    +
    +::grpc::Status
    +SeatsService::MoveComponent(::grpc::ServerContext*                                       context,
    +                            const ::sdv::edge::comfort::seats::v1::MoveComponentRequest* request,
    +                            ::sdv::edge::comfort::seats::v1::MoveComponentReply*         response) {
    +    (void)context;
    +    (void)request;
    +    (void)response;
    +    return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    +}
    +
    +::grpc::Status SeatsService::CurrentPosition(
    +    ::grpc::ServerContext*                                         context,
    +    const ::sdv::edge::comfort::seats::v1::CurrentPositionRequest* request,
    +    ::sdv::edge::comfort::seats::v1::CurrentPositionReply*         response) {
    +    (void)context;
    +    (void)request;
    +    vehicle::Vehicle Vehicle;
    +
    +    auto             seat          = response->mutable_seat();
    +    auto             seat_position = seat->mutable_position();
    +
    +    auto seatPos = Vehicle.Cabin.Seat.Row1.DriverSide.Position.get()->await().value();
    +
    +    // we only set base here to keep the example simple
    +    // extend here if yu want to set lumbar etc.
    +    seat_position->set_base(seatPos);
    +    return ::grpc::Status(::grpc::StatusCode::OK, "");
    +}
    +
    +} // namespace velocitas
    +
    +
    + + + + + + + + + + + + + + + +
    + +

    3.7 - Vehicle App Deployment

    Learn how to deploy the Vehicle App to currently supported infrastructure targets.

    See the diff --git a/docs/about/_print/index.html b/docs/about/_print/index.html index fb2978ef..1a064766 100644 --- a/docs/about/_print/index.html +++ b/docs/about/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -267,7 +267,7 @@

    Features

  • Project lifecycle management to update Vehicle App repositories via CLI.
  • Vehicle abstraction support helps to focus on business logic by using a generated vehicle model on code level with type safety and auto-completion. The vehicle model is generated from a standardized API that hides the details of vehicle-specific signals and E/E architecture, allowing Vehicle Apps to be portable across different electronics and software architectures.
  • Microsoft Visual Studio Code integration with DevContainer helps to install everything required to start the local development immediately, while tasks and launch configurations help to launch runtime services, other apps, and tests.
  • -
  • Vehicle App skeleton and examples helps to understand easily how to write a Vehicle App using the KUKSA.VAL runtime services.
  • +
  • Vehicle App skeleton and examples helps to understand easily how to write a Vehicle App using the KUKSA runtime services.
  • Ready-to-use CI/CD workflows that build (for multi architectures), test, document and deploy a containerized Vehicle App with no dependencies to E/E architecture help saving setup time.
  • Language Support

    @@ -612,12 +612,9 @@

    2 - Repository Overview

    -kuksa.val.services +kuksa-incubation -Provides exemplary vehicle services and respective implementations that illustrates how to interact with in-vehicle components and services via an unified access that is semantically described e.g. in the - -Vehicle Service Catalog (VSC) -. +Provides exemplary vehicle services and respective implementations that illustrates how to interact with in-vehicle components and services via an unified access. diff --git a/docs/about/index.html b/docs/about/index.html index c76e4c57..2398a97f 100644 --- a/docs/about/index.html +++ b/docs/about/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -543,7 +565,7 @@

    Features

  • Project lifecycle management to update Vehicle App repositories via CLI.
  • Vehicle abstraction support helps to focus on business logic by using a generated vehicle model on code level with type safety and auto-completion. The vehicle model is generated from a standardized API that hides the details of vehicle-specific signals and E/E architecture, allowing Vehicle Apps to be portable across different electronics and software architectures.
  • Microsoft Visual Studio Code integration with DevContainer helps to install everything required to start the local development immediately, while tasks and launch configurations help to launch runtime services, other apps, and tests.
  • -
  • Vehicle App skeleton and examples helps to understand easily how to write a Vehicle App using the KUKSA.VAL runtime services.
  • +
  • Vehicle App skeleton and examples helps to understand easily how to write a Vehicle App using the KUKSA runtime services.
  • Ready-to-use CI/CD workflows that build (for multi architectures), test, document and deploy a containerized Vehicle App with no dependencies to E/E architecture help saving setup time.
  • Language Support

    @@ -642,7 +664,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/about/index.xml b/docs/about/index.xml index 1ed5f20a..382478c7 100644 --- a/docs/about/index.xml +++ b/docs/about/index.xml @@ -134,12 +134,9 @@ <tr> <td> -<a href="https://github.com/eclipse/kuksa.val.services" target="_blank" rel="noopener">kuksa.val.services</a> +<a href="https://github.com/eclipse-kuksa/kuksa-incubation" target="_blank" rel="noopener">kuksa-incubation</a> </td> -<td>Provides exemplary vehicle services and respective implementations that illustrates how to interact with in-vehicle components and services via an unified access that is semantically described e.g. in the - -<a href="https://github.com/COVESA/vehicle_service_catalog" target="_blank" rel="noopener">Vehicle Service Catalog (VSC)</a> -.</td> +<td>Provides exemplary vehicle services and respective implementations that illustrates how to interact with in-vehicle components and services via an unified access.</td> </tr> <tr> <td> diff --git a/docs/about/repository-overview/_print/index.html b/docs/about/repository-overview/_print/index.html index a883821a..680f6382 100644 --- a/docs/about/repository-overview/_print/index.html +++ b/docs/about/repository-overview/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -229,12 +229,9 @@

    Repository Overview

    -kuksa.val.services +kuksa-incubation -Provides exemplary vehicle services and respective implementations that illustrates how to interact with in-vehicle components and services via an unified access that is semantically described e.g. in the - -Vehicle Service Catalog (VSC) -. +Provides exemplary vehicle services and respective implementations that illustrates how to interact with in-vehicle components and services via an unified access. diff --git a/docs/about/repository-overview/index.html b/docs/about/repository-overview/index.html index 02dc05b7..baf9c242 100644 --- a/docs/about/repository-overview/index.html +++ b/docs/about/repository-overview/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -583,12 +605,9 @@

    Repository Overview

    -kuksa.val.services +kuksa-incubation -Provides exemplary vehicle services and respective implementations that illustrates how to interact with in-vehicle components and services via an unified access that is semantically described e.g. in the - -Vehicle Service Catalog (VSC) -. +Provides exemplary vehicle services and respective implementations that illustrates how to interact with in-vehicle components and services via an unified access. @@ -710,7 +729,7 @@

    Package Repositories

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/about/repository-overview/project-overview.drawio.svg b/docs/about/repository-overview/project-overview.drawio.svg index e1d6afdb..d8347c54 100644 --- a/docs/about/repository-overview/project-overview.drawio.svg +++ b/docs/about/repository-overview/project-overview.drawio.svg @@ -1 +1 @@ -
    devenv-runtimes
    (e.g. local runtime)
    [Repository]
    devenv-runtimes...
    extends
    extends
    VehicleApp SDK
    VehicleApp SDK
    Seat Adjuster VehicleApp
    Seat Adjuster Vehicl...
    uses
    uses
    uses
    uses
    feeds
    feeds
    Seats Service
    Seats Service
    test
    test
    test
    test
    GH Workflows
    GH Workflows
    KUKSA.VAL
    KUKSA.VAL
    vehicle-app-*-template
    [Repository]
    vehicle-app-*-template...
    vehicle-app-*-sdk
    [Repository]
    vehicle-app-*-sdk...
    Unit tests
    Unit tests
    Integration tests
    Integration tests
    SDV package
    SDV package
    Unit tests
    Unit tests
    Integration tests
    Integration tests
    KUKSA Databroker
    KUKSA Databroker
    Developer Manual
    Developer Manual
    Data Feeder
    Data Feeder
    .velocitas.json
    .velocitas.json
    devenv-*
    [Repository]
    devenv-*...
    uses content
    uses content
    DevContainer
    DevContainer
    manages sync
    manages sync
    installs
    installs
    references
    references
    test
    test
    Velocitas CLI
    [Repository]
    Velocitas CLI...
    test
    test
    Velocitas CLI
    [tool]
    Velocitas CLI...
    creates
    creates
    reads
    reads
    runs with
    devcontainer-base-image
    [Repository]
    runs with...
    Render Action
    Render Action
    devenv-github-workflows
    [Repository]
    devenv-github-workflows[Repository]
    GH Workflows
    GH Workflows
    sync
    sync
    release-documentation-action
    [Repository]
    release-documentation-action...
    Render Action
    Render Action
    Package Action
    Package Acti...
    uses
    uses
    Text is not SVG - cannot display
    +
    devenv-runtimes
    (e.g. local runtime)
    [Repository]
    devenv-runtimes...
    extends
    extends
    VehicleApp SDK
    VehicleApp SDK
    Seat Adjuster VehicleApp
    Seat Adjuster Vehicl...
    uses
    uses
    uses
    uses
    feeds
    feeds
    Seats Service
    Seats Service
    test
    test
    test
    test
    GH Workflows
    GH Workflows
    KUKSA
    KUKSA
    vehicle-app-*-template
    [Repository]
    vehicle-app-*-template...
    vehicle-app-*-sdk
    [Repository]
    vehicle-app-*-sdk...
    Unit tests
    Unit tests
    Integration tests
    Integration tests
    SDV package
    SDV package
    Unit tests
    Unit tests
    Integration tests
    Integration tests
    KUKSA Databroker
    KUKSA Databroker
    Developer Manual
    Developer Manual
    Data Feeder
    Data Feeder
    .velocitas.json
    .velocitas.json
    devenv-*
    [Repository]
    devenv-*...
    uses content
    uses content
    DevContainer
    DevContainer
    manages sync
    manages sync
    installs
    installs
    references
    references
    test
    test
    Velocitas CLI
    [Repository]
    Velocitas CLI...
    test
    test
    Velocitas CLI
    [tool]
    Velocitas CLI...
    creates
    creates
    reads
    reads
    runs with
    devcontainer-base-image
    [Repository]
    runs with...
    Render Action
    Render Action
    devenv-github-workflows
    [Repository]
    devenv-github-workflows[Repository]
    GH Workflows
    GH Workflows
    sync
    sync
    release-documentation-action
    [Repository]
    release-documentation-action...
    Render Action
    Render Action
    Package Action
    Package Acti...
    uses
    uses
    Text is not SVG - cannot display
    diff --git a/docs/about/use_cases/_print/index.html b/docs/about/use_cases/_print/index.html index cd68e172..e2d381f4 100644 --- a/docs/about/use_cases/_print/index.html +++ b/docs/about/use_cases/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/about/use_cases/dog_mode/_print/index.html b/docs/about/use_cases/dog_mode/_print/index.html index 33bada6f..0976aa4f 100644 --- a/docs/about/use_cases/dog_mode/_print/index.html +++ b/docs/about/use_cases/dog_mode/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/about/use_cases/dog_mode/index.html b/docs/about/use_cases/dog_mode/index.html index 8d1e8551..7712e837 100644 --- a/docs/about/use_cases/dog_mode/index.html +++ b/docs/about/use_cases/dog_mode/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -521,7 +543,7 @@

    Example Code

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/about/use_cases/index.html b/docs/about/use_cases/index.html index 3daec95c..2de3db14 100644 --- a/docs/about/use_cases/index.html +++ b/docs/about/use_cases/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -530,7 +552,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/about/use_cases/seat_adjuster/_print/index.html b/docs/about/use_cases/seat_adjuster/_print/index.html index 8815acc7..ca7e9cb9 100644 --- a/docs/about/use_cases/seat_adjuster/_print/index.html +++ b/docs/about/use_cases/seat_adjuster/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/about/use_cases/seat_adjuster/index.html b/docs/about/use_cases/seat_adjuster/index.html index 8140f459..9faf06af 100644 --- a/docs/about/use_cases/seat_adjuster/index.html +++ b/docs/about/use_cases/seat_adjuster/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -570,7 +592,7 @@

    Example Code

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/_print/index.html b/docs/concepts/_print/index.html index 1c9455e4..4b2b5867 100644 --- a/docs/concepts/_print/index.html +++ b/docs/concepts/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -183,6 +183,14 @@

    Concepts

    + + + +
  • 1.2.1: GRPC Interface Style Guide
  • + + + + @@ -500,21 +508,14 @@

    Semantic models

    VSS ) provides a domain taxonomy for vehicle signals and defines the vehicle data semantically, which is exchanged between Vehicle Apps and the Databroker.

    -

    The Vehicle Service Catalog ( - -VSC -) extends VSS with functional remote procedure call definitions and semantically defines the gRPC interfaces of Vehicle Services and Vehicle Apps.

    -

    As an alternative to VSS and VSC, vehicle data and services can be defined semantically in a general IoT modelling language like Digital Twin Definition Language ( - -DTDL -) or BAMM Aspect Meta Model - -BAMM - as well.

    The Velocitas SDK is using VSS - as the semantic model for the Vehicle Model.

    + as the semantic model for the Vehicle Model. +Vehicle Service models can be defined with + +Protobuf service definitions +.

    Communication Protocols

    Asynchronous communication between @@ -674,7 +675,7 @@

    Vehicle Model Ontology

    The Vehicle Model is a tree-based model where every branch in the tree, including the root, is derived from the Model base class provided by the SDK.

    The Vehicle Model Ontology consists of the following classes:

    Model

    -

    A model contains services, data points and other models. It corresponds to branch entries in VSS, interfaces in DTDL or namespaces in VSC.

    +

    A model contains data points (leaves) and other models (branches).

    ModelCollection

    @@ -1397,13 +1398,13 @@

    Introduction

    COVESA Vehicle Signal Specification (VSS) . The Vehicle API eliminates the need to know the source, destination, and format of signals for the vehicle system.

    -

    The Eclipse Velocitas project is using the VAL of the +

    The Eclipse Velocitas project is using the Eclipse KUKSA project -, also called KUKSA.VAL. -KUKSA.VAL does not provide a concrete VAL. That’s up to you as an OEM (vehicle manufacturer) or as a supplier. -But KUKSA.VAL provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an Vehicle App or Service.

    -

    KUKSA.VAL provides you with ready-to-use generic components for the signal-based access to the vehicle, like the KUKSA Databroker and the generic Data Providers (aka Data Feeders). +. +KUKSA does not provide a concrete VAL. That’s up to you as an OEM (vehicle manufacturer) or as a supplier. +But KUKSA provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an Vehicle App or Service.

    +

    KUKSA provides you with ready-to-use generic components for the signal-based access to the vehicle, like the KUKSA Databroker and the generic Data Providers (aka Data Feeders). It also provides you reference implementations of certain Vehicle Services, like the Seat Service and the HVAC Service.

    Architecture

    The image below shows the main components of the VAL and its relation to the @@ -1445,7 +1446,7 @@

    Vehicle Services

    It communicates with the Hardware Abstraction to execute the underlying services, but may also interact with the Databroker.

    The -KUKSA.VAL Services repository +KUKSA Incubation repository contains examples illustrating how such kind of vehicle services can be built.

    Hardware Abstraction

    Data feeders rely on hardware abstraction. Hardware abstraction is project/platform specific. @@ -1538,13 +1539,11 @@

    Source Code

    KUKSA example providers -

    Guidelines

    - +GRPC Interface Style Guide +

    @@ -1561,6 +1560,291 @@

    Guidelines

    + + + + + +
    + +

    1.2.1 - GRPC Interface Style Guide

    + +

    This provides a style guide for .proto files. By following these conventions, you’ll make your protocol buffer message definitions and their corresponding classes consistent and easy to read. +Unless otherwise indicated, this style guide is based on the style guide from + +google protocol-buffers style + under Apache 2.0 License & Creative Commons Attribution 4.0 License.

    +

    Note that protocol buffer style can evolve over time, so it is likely that you will see .proto files written in different conventions or styles. Please respect the existing style when you modify these files. Consistency is key. However, it is best to adopt the current best style when you are creating a new .proto file.

    +

    Standard file formatting

    +
      +
    • Keep the line length to 80 characters.
    • +
    • Use an indent of 2 spaces.
    • +
    • Prefer the use of double quotes for strings.
    • +
    +

    File structure

    +

    Files should be named lower_snake_case.proto

    +

    All files should be ordered in the following manner:

    +
      +
    • License header
    • +
    • File overview
    • +
    • Syntax
    • +
    • Package
    • +
    • Imports (sorted)
    • +
    • File options
    • +
    • Everything else
    • +
    +

    Directory Structure

    +

    Files should be stored in a directory structure that matches their package sub-names. All files +in a given directory should be in the same package. +Below is an example based on the + +proto files + in the kuksa.-databroker repository.

    +
    |   proto/
    +|   └── sdv
    +|       └── databroker
    +|           └── v1                  // package sdv.databroker.broker.v1
    +|               ├── broker.proto    // service Broker in sdv.databroker.broker.v1
    +|               ├── collector.proto // service Collector in sdv.databroker.broker.v1
    +|               └── types.proto     // type definition and import of  in sdv.databroker.broker.v1
    +

    The proposed structure shown above is adapted from + +Uber Protobuf Style Guide V2 + under MIT License.

    +

    Packages

    +

    Package names should be in lowercase. Package names should have unique names based on the project name, and possibly based on the path of the file containing the protocol buffer type definitions.

    +

    Message and field names

    +

    Use PascalCase (CamelCase with an initial capital) for message names – for example, SongServerRequest. Use underscore_separated_names for field names (including oneof field and extension names) – for example, song_name.

    +
    message SongServerRequest {
    +   optional string song_name = 1;
    +}
    +

    Using this naming convention for field names gives you accessors like the following:

    +

    C++:

    +
    const string& song_name() { ... }
    +void set_song_name(const string& x) { ... }
    +

    If your field name contains a number, the number should appear after the letter instead of after the underscore. For example, use song_name1 instead of song_name_1 +Repeated fields

    +

    Use pluralized names for repeated fields.

    +
    repeated string keys = 1;
    +...
    +repeated MyMessage accounts = 17;
    +

    Enums

    +

    Use PascalCase (with an initial capital) for enum type names and CAPITALS_WITH_UNDERSCORES for value names:

    +
    enum FooBar {
    +   FOO_BAR_UNSPECIFIED = 0;
    +   FOO_BAR_FIRST_VALUE = 1;
    +   FOO_BAR_SECOND_VALUE = 2;
    +}
    +

    Each enum value should end with a semicolon, not a comma. The zero value enum should have the suffix UNSPECIFIED.

    +

    Services

    +

    If your .proto defines an RPC service, you should use PascalCase (with an initial capital) for both the service name and any RPC method names:

    +
    service FooService {
    +   rpc GetSomething(GetSomethingRequest) returns (GetSomethingResponse);
    +   rpc ListSomething(ListSomethingRequest) returns (ListSomethingResponse);
    +}
    +

    GRPC Interface Versioning

    +

    All API interfaces must provide a major version number, which is encoded at the end of the protobuf package. +If an API introduces a breaking change, such as removing or renaming a field, it must increment its API version number to ensure that existing user code does not suddenly break. +Note: The use of the term “major version number” above is taken from semantic versioning. However, unlike in traditional semantic versioning, APIs must not expose minor or patch version numbers. +For example, APIs use v1, not v1.0, v1.1, or v1.4.2. From a user’s perspective, minor versions are updated in place, and users receive new functionality without migration.

    +

    A new major version of an API must not depend on a previous major version of the same API. An API may depend on other APIs, with an expectation that the caller understands the dependency and stability risk associated with those APIs. In this scenario, a stable API version must only depend on stable versions of other APIs.

    +

    Different versions of the same API should preferably be able to work at the same time within a single client application for a reasonable transition period. This time period allows the client to transition smoothly to the newer version. An older version must go through a reasonable, well-communicated deprecation period before being shut down.

    +

    For releases that have alpha or beta stability, APIs must append the stability level after the major version number in the protobuf package.

    +

    Release-based versioning

    +

    An individual release is an alpha or beta release that is expected to be available for a limited time period before its functionality is incorporated into the stable channel, after which the individual release will be shut down. +When using release-based versioning strategy, an API may have any number of individual releases at each stability level.

    +

    Alpha and beta releases must have their stability level appended to the version, followed by an incrementing release number. For example, v1beta1 or v1alpha5. APIs should document the chronological order of these versions in their documentation (such as comments). +Each alpha or beta release may be updated in place with backwards-compatible changes. For beta releases, backwards-incompatible updates should be made by incrementing the release number and publishing a new release with the change. For example, if the current version is v1beta1, then v1beta2 is released next.

    +

    Adapted from + +google release-based_versioning + under Apache 2.0 License & Creative Commons Attribution 4.0 License

    +

    Backwards compatibility

    +

    The gRPC protocol is designed to support services that change over time. Generally, additions to gRPC services and methods are non-breaking. Non-breaking changes allow existing clients to continue working without changes. Changing or deleting gRPC services are breaking changes. When gRPC services have breaking changes, clients using that service have to be updated and redeployed.

    +

    Making non-breaking changes to a service has a number of benefits:

    +
      +
    • Existing clients continue to run.
    • +
    • Avoids work involved with notifying clients of breaking changes, and updating them.
    • +
    • Only one version of the service needs to be documented and maintained.
    • +
    +

    Non-breaking changes

    +

    These changes are non-breaking at a gRPC protocol level and binary level.

    +
      +
    • Adding a new service
    • +
    • Adding a new method to a service
    • +
    • Adding a field to a request message - Fields added to a request message are deserialized with the default value on the server when not set. To be a non-breaking change, the service must succeed when the new field isn’t set by older clients.
    • +
    • Adding a field to a response message - Fields added to a response message are deserialized into the message’s unknown fields collection on the client.
    • +
    • Adding a value to an enum - Enums are serialized as a numeric value. New enum values are deserialized on the client to the enum value without an enum name. To be a non-breaking change, older clients must run correctly when receiving the new enum value.
    • +
    +

    Binary breaking changes

    +

    The following changes are non-breaking at a gRPC protocol level, but the client needs to be updated if it upgrades to the latest .proto contract. Binary compatibility is important if you plan to publish a gRPC library.

    +
      +
    • Removing a field - Values from a removed field are deserialized to a message’s unknown fields. This isn’t a gRPC protocol breaking change, but the client needs to be updated if it upgrades to the latest contract. It’s important that a removed field number isn’t accidentally reused in the future. To ensure this doesn’t happen, specify deleted field numbers and names on the message using Protobuf’s reserved keyword.
    • +
    • Renaming a message - Message names aren’t typically sent on the network, so this isn’t a gRPC protocol breaking change. The client will need to be updated if it upgrades to the latest contract. One situation where message names are sent on the network is with Any fields, when the message name is used to identify the message type.
    • +
    • Nesting or unnesting a message - Message types can be nested. Nesting or unnesting a message changes its message name. Changing how a message type is nested has the same impact on compatibility as renaming.
    • +
    +

    Protocol breaking changes

    +

    The following items are protocol and binary breaking changes:

    +
      +
    • Renaming a field - With Protobuf content, the field names are only used in generated code. The field number is used to identify fields on the network. Renaming a field isn’t a protocol breaking change for Protobuf. However, if a server is using JSON content, then renaming a field is a breaking change.
    • +
    • Changing a field data type - Changing a field’s data type to an incompatible type will cause errors when deserializing the message. Even if the new data type is compatible, it’s likely the client needs to be updated to support the new type if it upgrades to the latest contract.
    • +
    • Changing a field number - With Protobuf payloads, the field number is used to identify fields on the network.
    • +
    • Renaming a package, service or method - gRPC uses the package name, service name, and method name to build the URL. The client gets an UNIMPLEMENTED status from the server.
    • +
    • Removing a service or method - The client gets an UNIMPLEMENTED status from the server when calling the removed method.
    • +
    +

    Behavior breaking changes

    +

    When making non-breaking changes, you must also consider whether older clients can continue working with the new service behavior. For example, adding a new field to a request message:

    +
      +
    • Isn’t a protocol breaking change.
    • +
    • Returning an error status on the server if the new field isn’t set makes it a breaking change for old clients.
    • +
    +

    Behavior compatibility is determined by your app-specific code.

    +

    Adapted from + +Versioning gRPC services + under Creative Commons Attribution 4.0 License

    +

    gRPC Error Handling

    +

    In gRPC, a large set of error codes has been + +defined + +As a general rule, SDV should use relevant gRPC error codes, +as described in + +this thread +

    +
       return grpc::Status(grpc::StatusCode::NOT_FOUND, "error details here");
    +

    Available constructor:

    +
       grpc::Status::Status ( StatusCode  code,
    +      const std::string & error_message,
    +      const std::string & error_details
    +

    The framework for drafting error messages could be useful as a later improvement. This could e.g., be used to specify which unit created the error message and to assure the same structure on all messages. The latter two may e.g., depend on debug settings, e.g., error details only in debug-builds to avoid leaks of sensitive information. A global function like below or similar could handle that and also possibly convert between internal error codes and gRPC codes.

    +
       grpc::Status status = CreateStatusMessage(PERMISSION_DENIED,"DataBroker","Rule access rights violated");
    +

    SDV error handling for gRPC interfaces (e.g., VAL vehicles services)

    +
      +
    • Use gRPC error codes as base
    • +
    • Document in proto files (as comments) which error codes that the service implementation can emit and the meaning of them. (Errors that only are emitted by the gRPC framework do not need to be listed.)
    • +
    • Do not - unless there are special reasons - add explicit error/status fields to rpc return messages.
    • +
    • Additional error information can be given by free text fields in gRPC error codes. Note, however, that sensitive information like Given password ABCD does not match expected password EFGH should not be passed in an unprotected/unencrypted manner.
    • +
    +

    SDV handling of gRPC error codes

    +

    The table below gives error code guidelines for each gRPC on:

    +
      +
    • If it is relevant for a client to retry the call or not when receiving the error code. Retry is only relevant if the error is of a temporary nature.
    • +
    • When to use the error code when implementing a service.
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    gRPC error codeRetry Relevant?Recommended SDV usage
    OKNoMandatory error code if operation succeeded. Shall never be used if operation failed.
    CANCELLEDNoNo explicit use case on server side in SDV identified
    UNKNOWNNoTo be used in default-statements when converting errors from e.g., Broker-errors to SDV/gRPC errors
    INVALID_ARGUMENTNoE.g., Rule syntax with errors
    DEADLINE_EXCEEDEDYesOnly applicable for asynchronous services, i.e. services which wait for completion before the result is returned. The behavior if an operation cannot finish within expected time must be defined. Two options exist. One is to return this error after e.g., X seconds. Another is that the server never gives up, but rather waits for the client to cancel the operation.
    NOT_FOUNDNoLong term situation that likely not will change in the near future.
    Example: SDV can not find the specified resource (e.g., no path to get data for specified seat)
    ALREADY_EXISTSNoNo explicit use case on server side in SDV identified
    PERMISSION_DENIEDNoOperation rejected due to permission denied
    RESOURCE_EXHAUSTEDYesPossibly if e.g., malloc fails or similar errors.
    FAILED_PRECONDITIONYesCould be returned if e.g., operation is rejected due to safety reasons. (E.g., vehicle moving)
    ABORTEDYesCould e.g., be returned if service does not support concurrent requests, and there is already either a related operation ongoing or the operation is aborted due to a newer request received. Could also be used if an operation is aborted on user/driver request, e.g., physical button in vehicle pressed.
    OUT_OF_RANGENoE.g., Arguments out of range
    UNIMPLEMENTEDNoTo be used if certain use-cases of the service are not implemented, e.g., if recline cannot be adjusted
    INTERNALNoInternal errors, like exceptions, unexpected null pointers and similar
    UNAVAILABLEYesTo be used if the service is temporarily unavailable, e.g., during system startup.
    DATA_LOSSNoNo explicit use case identified on server side in SDV.
    UNAUTHENTICATEDNoNo explicit use case identified on server side in SDV.
    +

    Other references

    + + +
    + + + + + + @@ -1924,6 +2208,15 @@

    Configuration structure

    URI of the used COVESA Vehicle Signal Specification JSON export. URI may point to a local file or to a file provided by a server.  +unit_src +string +["abs_path_unit_file_1", "abs_path_unit_file_2", "uri_unit_file_3"] +An array of URI’s/absolute path’s of the used COVESA Vehicle Signal Specification unit file(s) in yaml format. URI may point to a local file or to a file provided by a server. If none is provided a default one will be used ( + +https://github.com/COVESA/vehicle_signal_specification/blob/v4.0/spec/units.yaml) +.  + + datapoints object Object containing both required and provided datapoints. @@ -1994,7 +2287,9 @@

    Example

    } } } - +

    Different VSS versions

    +

    The model generation is supported for VSS versions up to v4.0. There are some changes for some paths from v3.0 to v4.0. For example Vehicle.Cabin.Seat.Row1.Pos1.Position in v3.0 is Vehicle.Cabin.Seat.Row1.DriverSide.Position in v4.0. If you are using the mock provider you would need to take that into account when you sepcify your mock.py.

    + @@ -2084,7 +2379,11 @@

    Configuration structure

    -

    Example

    +

    Execution

    +

    velocitas init +or +velocitas exec grpc-interface-support generate-sdk

    +

    Project configuration

    {
       "type": "grpc-interface",
       "config": {
    @@ -2093,10 +2392,23 @@ 

    Example

    "methods": [ "Move", "MoveComponent" ] - } + }, + "provided": { } } } -
    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    + @@ -2750,14 +3062,12 @@

    Interaction mockup

    > 3. Which API dependencies does your project have? [x] gRPC service [ ] uProtocol service -[x] Vehicle Service Catalogue > 4. Add an API dependency (y/n)? y > 5. What type of dependency? [x] gRPC-IF -[ ] VSC-IF > 6. URI of the .proto file? https://some-url/if.proto @@ -2772,7 +3082,6 @@

    Interaction mockup

    --name MyApp \ --lang cpp \ --package grpc-service-support \ - --package vsc-support \ --require grpc-interface:https://some-url/if.proto > Project created! diff --git a/docs/concepts/deployment_model/_print/index.html b/docs/concepts/deployment_model/_print/index.html index e65fb16e..2691886d 100644 --- a/docs/concepts/deployment_model/_print/index.html +++ b/docs/concepts/deployment_model/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/concepts/deployment_model/index.html b/docs/concepts/deployment_model/index.html index c340dff9..1b170be4 100644 --- a/docs/concepts/deployment_model/index.html +++ b/docs/concepts/deployment_model/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -541,7 +563,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/deployment_model/vehicle_app_releases/_print/index.html b/docs/concepts/deployment_model/vehicle_app_releases/_print/index.html index e7b3730f..a9dc3b10 100644 --- a/docs/concepts/deployment_model/vehicle_app_releases/_print/index.html +++ b/docs/concepts/deployment_model/vehicle_app_releases/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/concepts/deployment_model/vehicle_app_releases/index.html b/docs/concepts/deployment_model/vehicle_app_releases/index.html index 67939cf1..b196260a 100644 --- a/docs/concepts/deployment_model/vehicle_app_releases/index.html +++ b/docs/concepts/deployment_model/vehicle_app_releases/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -604,7 +626,7 @@

    Further information

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/development_model/_print/index.html b/docs/concepts/development_model/_print/index.html index a98ce37b..6c72cb49 100644 --- a/docs/concepts/development_model/_print/index.html +++ b/docs/concepts/development_model/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -168,6 +168,14 @@

    Development Model

    + + + +
  • 2.1: GRPC Interface Style Guide
  • + + + + @@ -307,21 +315,14 @@

    Semantic models

    VSS ) provides a domain taxonomy for vehicle signals and defines the vehicle data semantically, which is exchanged between Vehicle Apps and the Databroker.

    -

    The Vehicle Service Catalog ( - -VSC -) extends VSS with functional remote procedure call definitions and semantically defines the gRPC interfaces of Vehicle Services and Vehicle Apps.

    -

    As an alternative to VSS and VSC, vehicle data and services can be defined semantically in a general IoT modelling language like Digital Twin Definition Language ( - -DTDL -) or BAMM Aspect Meta Model - -BAMM - as well.

    The Velocitas SDK is using VSS - as the semantic model for the Vehicle Model.

    + as the semantic model for the Vehicle Model. +Vehicle Service models can be defined with + +Protobuf service definitions +.

    Communication Protocols

    Asynchronous communication between @@ -479,7 +480,7 @@

    Vehicle Model Ontology

    The Vehicle Model is a tree-based model where every branch in the tree, including the root, is derived from the Model base class provided by the SDK.

    The Vehicle Model Ontology consists of the following classes:

    Model

    -

    A model contains services, data points and other models. It corresponds to branch entries in VSS, interfaces in DTDL or namespaces in VSC.

    +

    A model contains data points (leaves) and other models (branches).

    ModelCollection

    @@ -1202,13 +1203,13 @@

    Introduction

    COVESA Vehicle Signal Specification (VSS) . The Vehicle API eliminates the need to know the source, destination, and format of signals for the vehicle system.

    -

    The Eclipse Velocitas project is using the VAL of the +

    The Eclipse Velocitas project is using the Eclipse KUKSA project -, also called KUKSA.VAL. -KUKSA.VAL does not provide a concrete VAL. That’s up to you as an OEM (vehicle manufacturer) or as a supplier. -But KUKSA.VAL provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an Vehicle App or Service.

    -

    KUKSA.VAL provides you with ready-to-use generic components for the signal-based access to the vehicle, like the KUKSA Databroker and the generic Data Providers (aka Data Feeders). +. +KUKSA does not provide a concrete VAL. That’s up to you as an OEM (vehicle manufacturer) or as a supplier. +But KUKSA provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an Vehicle App or Service.

    +

    KUKSA provides you with ready-to-use generic components for the signal-based access to the vehicle, like the KUKSA Databroker and the generic Data Providers (aka Data Feeders). It also provides you reference implementations of certain Vehicle Services, like the Seat Service and the HVAC Service.

    Architecture

    The image below shows the main components of the VAL and its relation to the @@ -1250,7 +1251,7 @@

    Vehicle Services

    It communicates with the Hardware Abstraction to execute the underlying services, but may also interact with the Databroker.

    The -KUKSA.VAL Services repository +KUKSA Incubation repository contains examples illustrating how such kind of vehicle services can be built.

    Hardware Abstraction

    Data feeders rely on hardware abstraction. Hardware abstraction is project/platform specific. @@ -1343,13 +1344,11 @@

    Source Code

    KUKSA example providers -

    Guidelines

    - +GRPC Interface Style Guide +

    @@ -1366,6 +1365,291 @@

    Guidelines

    + + + + + +
    + +

    2.1 - GRPC Interface Style Guide

    + +

    This provides a style guide for .proto files. By following these conventions, you’ll make your protocol buffer message definitions and their corresponding classes consistent and easy to read. +Unless otherwise indicated, this style guide is based on the style guide from + +google protocol-buffers style + under Apache 2.0 License & Creative Commons Attribution 4.0 License.

    +

    Note that protocol buffer style can evolve over time, so it is likely that you will see .proto files written in different conventions or styles. Please respect the existing style when you modify these files. Consistency is key. However, it is best to adopt the current best style when you are creating a new .proto file.

    +

    Standard file formatting

    +
      +
    • Keep the line length to 80 characters.
    • +
    • Use an indent of 2 spaces.
    • +
    • Prefer the use of double quotes for strings.
    • +
    +

    File structure

    +

    Files should be named lower_snake_case.proto

    +

    All files should be ordered in the following manner:

    +
      +
    • License header
    • +
    • File overview
    • +
    • Syntax
    • +
    • Package
    • +
    • Imports (sorted)
    • +
    • File options
    • +
    • Everything else
    • +
    +

    Directory Structure

    +

    Files should be stored in a directory structure that matches their package sub-names. All files +in a given directory should be in the same package. +Below is an example based on the + +proto files + in the kuksa.-databroker repository.

    +
    |   proto/
    +|   └── sdv
    +|       └── databroker
    +|           └── v1                  // package sdv.databroker.broker.v1
    +|               ├── broker.proto    // service Broker in sdv.databroker.broker.v1
    +|               ├── collector.proto // service Collector in sdv.databroker.broker.v1
    +|               └── types.proto     // type definition and import of  in sdv.databroker.broker.v1
    +

    The proposed structure shown above is adapted from + +Uber Protobuf Style Guide V2 + under MIT License.

    +

    Packages

    +

    Package names should be in lowercase. Package names should have unique names based on the project name, and possibly based on the path of the file containing the protocol buffer type definitions.

    +

    Message and field names

    +

    Use PascalCase (CamelCase with an initial capital) for message names – for example, SongServerRequest. Use underscore_separated_names for field names (including oneof field and extension names) – for example, song_name.

    +
    message SongServerRequest {
    +   optional string song_name = 1;
    +}
    +

    Using this naming convention for field names gives you accessors like the following:

    +

    C++:

    +
    const string& song_name() { ... }
    +void set_song_name(const string& x) { ... }
    +

    If your field name contains a number, the number should appear after the letter instead of after the underscore. For example, use song_name1 instead of song_name_1 +Repeated fields

    +

    Use pluralized names for repeated fields.

    +
    repeated string keys = 1;
    +...
    +repeated MyMessage accounts = 17;
    +

    Enums

    +

    Use PascalCase (with an initial capital) for enum type names and CAPITALS_WITH_UNDERSCORES for value names:

    +
    enum FooBar {
    +   FOO_BAR_UNSPECIFIED = 0;
    +   FOO_BAR_FIRST_VALUE = 1;
    +   FOO_BAR_SECOND_VALUE = 2;
    +}
    +

    Each enum value should end with a semicolon, not a comma. The zero value enum should have the suffix UNSPECIFIED.

    +

    Services

    +

    If your .proto defines an RPC service, you should use PascalCase (with an initial capital) for both the service name and any RPC method names:

    +
    service FooService {
    +   rpc GetSomething(GetSomethingRequest) returns (GetSomethingResponse);
    +   rpc ListSomething(ListSomethingRequest) returns (ListSomethingResponse);
    +}
    +

    GRPC Interface Versioning

    +

    All API interfaces must provide a major version number, which is encoded at the end of the protobuf package. +If an API introduces a breaking change, such as removing or renaming a field, it must increment its API version number to ensure that existing user code does not suddenly break. +Note: The use of the term “major version number” above is taken from semantic versioning. However, unlike in traditional semantic versioning, APIs must not expose minor or patch version numbers. +For example, APIs use v1, not v1.0, v1.1, or v1.4.2. From a user’s perspective, minor versions are updated in place, and users receive new functionality without migration.

    +

    A new major version of an API must not depend on a previous major version of the same API. An API may depend on other APIs, with an expectation that the caller understands the dependency and stability risk associated with those APIs. In this scenario, a stable API version must only depend on stable versions of other APIs.

    +

    Different versions of the same API should preferably be able to work at the same time within a single client application for a reasonable transition period. This time period allows the client to transition smoothly to the newer version. An older version must go through a reasonable, well-communicated deprecation period before being shut down.

    +

    For releases that have alpha or beta stability, APIs must append the stability level after the major version number in the protobuf package.

    +

    Release-based versioning

    +

    An individual release is an alpha or beta release that is expected to be available for a limited time period before its functionality is incorporated into the stable channel, after which the individual release will be shut down. +When using release-based versioning strategy, an API may have any number of individual releases at each stability level.

    +

    Alpha and beta releases must have their stability level appended to the version, followed by an incrementing release number. For example, v1beta1 or v1alpha5. APIs should document the chronological order of these versions in their documentation (such as comments). +Each alpha or beta release may be updated in place with backwards-compatible changes. For beta releases, backwards-incompatible updates should be made by incrementing the release number and publishing a new release with the change. For example, if the current version is v1beta1, then v1beta2 is released next.

    +

    Adapted from + +google release-based_versioning + under Apache 2.0 License & Creative Commons Attribution 4.0 License

    +

    Backwards compatibility

    +

    The gRPC protocol is designed to support services that change over time. Generally, additions to gRPC services and methods are non-breaking. Non-breaking changes allow existing clients to continue working without changes. Changing or deleting gRPC services are breaking changes. When gRPC services have breaking changes, clients using that service have to be updated and redeployed.

    +

    Making non-breaking changes to a service has a number of benefits:

    +
      +
    • Existing clients continue to run.
    • +
    • Avoids work involved with notifying clients of breaking changes, and updating them.
    • +
    • Only one version of the service needs to be documented and maintained.
    • +
    +

    Non-breaking changes

    +

    These changes are non-breaking at a gRPC protocol level and binary level.

    +
      +
    • Adding a new service
    • +
    • Adding a new method to a service
    • +
    • Adding a field to a request message - Fields added to a request message are deserialized with the default value on the server when not set. To be a non-breaking change, the service must succeed when the new field isn’t set by older clients.
    • +
    • Adding a field to a response message - Fields added to a response message are deserialized into the message’s unknown fields collection on the client.
    • +
    • Adding a value to an enum - Enums are serialized as a numeric value. New enum values are deserialized on the client to the enum value without an enum name. To be a non-breaking change, older clients must run correctly when receiving the new enum value.
    • +
    +

    Binary breaking changes

    +

    The following changes are non-breaking at a gRPC protocol level, but the client needs to be updated if it upgrades to the latest .proto contract. Binary compatibility is important if you plan to publish a gRPC library.

    +
      +
    • Removing a field - Values from a removed field are deserialized to a message’s unknown fields. This isn’t a gRPC protocol breaking change, but the client needs to be updated if it upgrades to the latest contract. It’s important that a removed field number isn’t accidentally reused in the future. To ensure this doesn’t happen, specify deleted field numbers and names on the message using Protobuf’s reserved keyword.
    • +
    • Renaming a message - Message names aren’t typically sent on the network, so this isn’t a gRPC protocol breaking change. The client will need to be updated if it upgrades to the latest contract. One situation where message names are sent on the network is with Any fields, when the message name is used to identify the message type.
    • +
    • Nesting or unnesting a message - Message types can be nested. Nesting or unnesting a message changes its message name. Changing how a message type is nested has the same impact on compatibility as renaming.
    • +
    +

    Protocol breaking changes

    +

    The following items are protocol and binary breaking changes:

    +
      +
    • Renaming a field - With Protobuf content, the field names are only used in generated code. The field number is used to identify fields on the network. Renaming a field isn’t a protocol breaking change for Protobuf. However, if a server is using JSON content, then renaming a field is a breaking change.
    • +
    • Changing a field data type - Changing a field’s data type to an incompatible type will cause errors when deserializing the message. Even if the new data type is compatible, it’s likely the client needs to be updated to support the new type if it upgrades to the latest contract.
    • +
    • Changing a field number - With Protobuf payloads, the field number is used to identify fields on the network.
    • +
    • Renaming a package, service or method - gRPC uses the package name, service name, and method name to build the URL. The client gets an UNIMPLEMENTED status from the server.
    • +
    • Removing a service or method - The client gets an UNIMPLEMENTED status from the server when calling the removed method.
    • +
    +

    Behavior breaking changes

    +

    When making non-breaking changes, you must also consider whether older clients can continue working with the new service behavior. For example, adding a new field to a request message:

    +
      +
    • Isn’t a protocol breaking change.
    • +
    • Returning an error status on the server if the new field isn’t set makes it a breaking change for old clients.
    • +
    +

    Behavior compatibility is determined by your app-specific code.

    +

    Adapted from + +Versioning gRPC services + under Creative Commons Attribution 4.0 License

    +

    gRPC Error Handling

    +

    In gRPC, a large set of error codes has been + +defined + +As a general rule, SDV should use relevant gRPC error codes, +as described in + +this thread +

    +
       return grpc::Status(grpc::StatusCode::NOT_FOUND, "error details here");
    +

    Available constructor:

    +
       grpc::Status::Status ( StatusCode  code,
    +      const std::string & error_message,
    +      const std::string & error_details
    +

    The framework for drafting error messages could be useful as a later improvement. This could e.g., be used to specify which unit created the error message and to assure the same structure on all messages. The latter two may e.g., depend on debug settings, e.g., error details only in debug-builds to avoid leaks of sensitive information. A global function like below or similar could handle that and also possibly convert between internal error codes and gRPC codes.

    +
       grpc::Status status = CreateStatusMessage(PERMISSION_DENIED,"DataBroker","Rule access rights violated");
    +

    SDV error handling for gRPC interfaces (e.g., VAL vehicles services)

    +
      +
    • Use gRPC error codes as base
    • +
    • Document in proto files (as comments) which error codes that the service implementation can emit and the meaning of them. (Errors that only are emitted by the gRPC framework do not need to be listed.)
    • +
    • Do not - unless there are special reasons - add explicit error/status fields to rpc return messages.
    • +
    • Additional error information can be given by free text fields in gRPC error codes. Note, however, that sensitive information like Given password ABCD does not match expected password EFGH should not be passed in an unprotected/unencrypted manner.
    • +
    +

    SDV handling of gRPC error codes

    +

    The table below gives error code guidelines for each gRPC on:

    +
      +
    • If it is relevant for a client to retry the call or not when receiving the error code. Retry is only relevant if the error is of a temporary nature.
    • +
    • When to use the error code when implementing a service.
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    gRPC error codeRetry Relevant?Recommended SDV usage
    OKNoMandatory error code if operation succeeded. Shall never be used if operation failed.
    CANCELLEDNoNo explicit use case on server side in SDV identified
    UNKNOWNNoTo be used in default-statements when converting errors from e.g., Broker-errors to SDV/gRPC errors
    INVALID_ARGUMENTNoE.g., Rule syntax with errors
    DEADLINE_EXCEEDEDYesOnly applicable for asynchronous services, i.e. services which wait for completion before the result is returned. The behavior if an operation cannot finish within expected time must be defined. Two options exist. One is to return this error after e.g., X seconds. Another is that the server never gives up, but rather waits for the client to cancel the operation.
    NOT_FOUNDNoLong term situation that likely not will change in the near future.
    Example: SDV can not find the specified resource (e.g., no path to get data for specified seat)
    ALREADY_EXISTSNoNo explicit use case on server side in SDV identified
    PERMISSION_DENIEDNoOperation rejected due to permission denied
    RESOURCE_EXHAUSTEDYesPossibly if e.g., malloc fails or similar errors.
    FAILED_PRECONDITIONYesCould be returned if e.g., operation is rejected due to safety reasons. (E.g., vehicle moving)
    ABORTEDYesCould e.g., be returned if service does not support concurrent requests, and there is already either a related operation ongoing or the operation is aborted due to a newer request received. Could also be used if an operation is aborted on user/driver request, e.g., physical button in vehicle pressed.
    OUT_OF_RANGENoE.g., Arguments out of range
    UNIMPLEMENTEDNoTo be used if certain use-cases of the service are not implemented, e.g., if recline cannot be adjusted
    INTERNALNoInternal errors, like exceptions, unexpected null pointers and similar
    UNAVAILABLEYesTo be used if the service is temporarily unavailable, e.g., during system startup.
    DATA_LOSSNoNo explicit use case identified on server side in SDV.
    UNAUTHENTICATEDNoNo explicit use case identified on server side in SDV.
    +

    Other references

    + + +
    + + + + + + @@ -1729,6 +2013,15 @@

    Configuration structure

    URI of the used COVESA Vehicle Signal Specification JSON export. URI may point to a local file or to a file provided by a server.  +unit_src +string +["abs_path_unit_file_1", "abs_path_unit_file_2", "uri_unit_file_3"] +An array of URI’s/absolute path’s of the used COVESA Vehicle Signal Specification unit file(s) in yaml format. URI may point to a local file or to a file provided by a server. If none is provided a default one will be used ( + +https://github.com/COVESA/vehicle_signal_specification/blob/v4.0/spec/units.yaml) +.  + + datapoints object Object containing both required and provided datapoints. @@ -1799,7 +2092,9 @@

    Example

    } } } - +

    Different VSS versions

    +

    The model generation is supported for VSS versions up to v4.0. There are some changes for some paths from v3.0 to v4.0. For example Vehicle.Cabin.Seat.Row1.Pos1.Position in v3.0 is Vehicle.Cabin.Seat.Row1.DriverSide.Position in v4.0. If you are using the mock provider you would need to take that into account when you sepcify your mock.py.

    + @@ -1889,7 +2184,11 @@

    Configuration structure

    -

    Example

    +

    Execution

    +

    velocitas init +or +velocitas exec grpc-interface-support generate-sdk

    +

    Project configuration

    {
       "type": "grpc-interface",
       "config": {
    @@ -1898,10 +2197,23 @@ 

    Example

    "methods": [ "Move", "MoveComponent" ] - } + }, + "provided": { } } } -
    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    + diff --git a/docs/concepts/development_model/index.html b/docs/concepts/development_model/index.html index 2b7b8151..31cd24f5 100644 --- a/docs/concepts/development_model/index.html +++ b/docs/concepts/development_model/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -572,21 +594,14 @@

    Semantic models

    VSS ) provides a domain taxonomy for vehicle signals and defines the vehicle data semantically, which is exchanged between Vehicle Apps and the Databroker.

    -

    The Vehicle Service Catalog ( - -VSC -) extends VSS with functional remote procedure call definitions and semantically defines the gRPC interfaces of Vehicle Services and Vehicle Apps.

    -

    As an alternative to VSS and VSC, vehicle data and services can be defined semantically in a general IoT modelling language like Digital Twin Definition Language ( - -DTDL -) or BAMM Aspect Meta Model - -BAMM - as well.

    The Velocitas SDK is using VSS - as the semantic model for the Vehicle Model.

    + as the semantic model for the Vehicle Model. +Vehicle Service models can be defined with + +Protobuf service definitions +.

    Communication Protocols

    Asynchronous communication between @@ -726,7 +741,7 @@

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/development_model/index.xml b/docs/concepts/development_model/index.xml index 2030d49e..d82d3c4e 100644 --- a/docs/concepts/development_model/index.xml +++ b/docs/concepts/development_model/index.xml @@ -64,7 +64,7 @@ <p>The Vehicle Model is a tree-based model where every branch in the tree, including the root, is derived from the <code>Model</code> base class provided by the SDK.</p> <p>The Vehicle Model Ontology consists of the following classes:</p> <h3 id="model">Model</h3> -<p>A model contains services, data points and other models. It corresponds to branch entries in VSS, interfaces in DTDL or namespaces in VSC.</p> +<p>A model contains data points (leaves) and other models (branches).</p> <h3 id="modelcollection">ModelCollection</h3> @@ -768,13 +768,13 @@ The gRPC stubs are wrapped by a <strong>convenience layer</strong> c <a href="https://covesa.github.io/vehicle_signal_specification/" target="_blank" rel="noopener">COVESA Vehicle Signal Specification (VSS)</a> . The <em>Vehicle API</em> eliminates the need to know the source, destination, and format of signals for the vehicle system.</p> -<p>The Eclipse Velocitas project is using the VAL of the +<p>The Eclipse Velocitas project is using the <a href="https://github.com/eclipse-kuksa" target="_blank" rel="noopener"><em>Eclipse KUKSA project</em></a> -, also called <em>KUKSA.VAL</em>. -KUKSA.VAL does not provide a concrete VAL. That&rsquo;s up to you as an OEM (vehicle manufacturer) or as a supplier. -But KUKSA.VAL provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an <em>Vehicle App</em> or Service.</p> -<p>KUKSA.VAL provides you with ready-to-use generic components for the signal-based access to the vehicle, like the <em>KUKSA Databroker</em> and the generic <em>Data Providers</em> (aka <em>Data Feeders</em>). +. +KUKSA does not provide a concrete VAL. That&rsquo;s up to you as an OEM (vehicle manufacturer) or as a supplier. +But KUKSA provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an <em>Vehicle App</em> or Service.</p> +<p>KUKSA provides you with ready-to-use generic components for the signal-based access to the vehicle, like the <em>KUKSA Databroker</em> and the generic <em>Data Providers</em> (aka <em>Data Feeders</em>). It also provides you reference implementations of certain <em>Vehicle Services</em>, like the <em>Seat Service</em> and the <em>HVAC Service</em>.</p> <h2 id="architecture">Architecture</h2> <p>The image below shows the main components of the VAL and its relation to the @@ -816,7 +816,7 @@ It can provide service interfaces to control actuators or to trigger (complex) a It communicates with the Hardware Abstraction to execute the underlying services, but may also interact with the Databroker.</p> <p>The -<a href="https://github.com/eclipse/kuksa.val.services/" target="_blank" rel="noopener">KUKSA.VAL Services repository</a> +<a href="https://github.com/eclipse-kuksa/kuksa-incubation" target="_blank" rel="noopener">KUKSA Incubation repository</a> contains examples illustrating how such kind of vehicle services can be built.</p> <h3 id="hardware-abstraction">Hardware Abstraction</h3> <p>Data feeders rely on hardware abstraction. Hardware abstraction is project/platform specific. @@ -909,13 +909,11 @@ Service implementations may also interact as feeders with the Databroker.</p& <a href="https://github.com/eclipse-kuksa#providers-exchanging-data-with-databrokerserver" target="_blank" rel="noopener">KUKSA example providers</a> </li> </ul> -<h2 id="guidelines">Guidelines</h2> -<ul> -<li>Guidelines for best practices on how to specify a gRPC-based service interface and on how to implement a vehicle service can be found in the +<h2 id="grpc-interface-style-guide">GRPC Interface Style Guide</h2> +<p>A style guide is available in the -<a href="https://github.com/eclipse/kuksa.val.services/tree/main/docs" target="_blank" rel="noopener">kuksa.val.services repository</a> -.</li> -</ul> +<a href="grpc_style_guide.md">GRPC Interface Style Guide</a> +</p> diff --git a/docs/concepts/development_model/val/_print/index.html b/docs/concepts/development_model/val/_print/index.html index bf15589d..06bddff3 100644 --- a/docs/concepts/development_model/val/_print/index.html +++ b/docs/concepts/development_model/val/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -137,6 +137,14 @@

    Vehicle Abstraction Layer (VAL)

    + + + +
  • 1: GRPC Interface Style Guide
  • + + + + @@ -148,13 +156,13 @@

    Introduction

    COVESA Vehicle Signal Specification (VSS) . The Vehicle API eliminates the need to know the source, destination, and format of signals for the vehicle system.

    -

    The Eclipse Velocitas project is using the VAL of the +

    The Eclipse Velocitas project is using the Eclipse KUKSA project -, also called KUKSA.VAL. -KUKSA.VAL does not provide a concrete VAL. That’s up to you as an OEM (vehicle manufacturer) or as a supplier. -But KUKSA.VAL provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an Vehicle App or Service.

    -

    KUKSA.VAL provides you with ready-to-use generic components for the signal-based access to the vehicle, like the KUKSA Databroker and the generic Data Providers (aka Data Feeders). +. +KUKSA does not provide a concrete VAL. That’s up to you as an OEM (vehicle manufacturer) or as a supplier. +But KUKSA provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an Vehicle App or Service.

    +

    KUKSA provides you with ready-to-use generic components for the signal-based access to the vehicle, like the KUKSA Databroker and the generic Data Providers (aka Data Feeders). It also provides you reference implementations of certain Vehicle Services, like the Seat Service and the HVAC Service.

    Architecture

    The image below shows the main components of the VAL and its relation to the @@ -196,7 +204,7 @@

    Vehicle Services

    It communicates with the Hardware Abstraction to execute the underlying services, but may also interact with the Databroker.

    The -KUKSA.VAL Services repository +KUKSA Incubation repository contains examples illustrating how such kind of vehicle services can be built.

    Hardware Abstraction

    Data feeders rely on hardware abstraction. Hardware abstraction is project/platform specific. @@ -289,13 +297,11 @@

    Source Code

    KUKSA example providers -

    Guidelines

    - +GRPC Interface Style Guide +

    @@ -310,6 +316,291 @@

    Guidelines

    + + + + + +
    + +

    1 - GRPC Interface Style Guide

    + +

    This provides a style guide for .proto files. By following these conventions, you’ll make your protocol buffer message definitions and their corresponding classes consistent and easy to read. +Unless otherwise indicated, this style guide is based on the style guide from + +google protocol-buffers style + under Apache 2.0 License & Creative Commons Attribution 4.0 License.

    +

    Note that protocol buffer style can evolve over time, so it is likely that you will see .proto files written in different conventions or styles. Please respect the existing style when you modify these files. Consistency is key. However, it is best to adopt the current best style when you are creating a new .proto file.

    +

    Standard file formatting

    + +

    File structure

    +

    Files should be named lower_snake_case.proto

    +

    All files should be ordered in the following manner:

    + +

    Directory Structure

    +

    Files should be stored in a directory structure that matches their package sub-names. All files +in a given directory should be in the same package. +Below is an example based on the + +proto files + in the kuksa.-databroker repository.

    +
    |   proto/
    +|   └── sdv
    +|       └── databroker
    +|           └── v1                  // package sdv.databroker.broker.v1
    +|               ├── broker.proto    // service Broker in sdv.databroker.broker.v1
    +|               ├── collector.proto // service Collector in sdv.databroker.broker.v1
    +|               └── types.proto     // type definition and import of  in sdv.databroker.broker.v1
    +

    The proposed structure shown above is adapted from + +Uber Protobuf Style Guide V2 + under MIT License.

    +

    Packages

    +

    Package names should be in lowercase. Package names should have unique names based on the project name, and possibly based on the path of the file containing the protocol buffer type definitions.

    +

    Message and field names

    +

    Use PascalCase (CamelCase with an initial capital) for message names – for example, SongServerRequest. Use underscore_separated_names for field names (including oneof field and extension names) – for example, song_name.

    +
    message SongServerRequest {
    +   optional string song_name = 1;
    +}
    +

    Using this naming convention for field names gives you accessors like the following:

    +

    C++:

    +
    const string& song_name() { ... }
    +void set_song_name(const string& x) { ... }
    +

    If your field name contains a number, the number should appear after the letter instead of after the underscore. For example, use song_name1 instead of song_name_1 +Repeated fields

    +

    Use pluralized names for repeated fields.

    +
    repeated string keys = 1;
    +...
    +repeated MyMessage accounts = 17;
    +

    Enums

    +

    Use PascalCase (with an initial capital) for enum type names and CAPITALS_WITH_UNDERSCORES for value names:

    +
    enum FooBar {
    +   FOO_BAR_UNSPECIFIED = 0;
    +   FOO_BAR_FIRST_VALUE = 1;
    +   FOO_BAR_SECOND_VALUE = 2;
    +}
    +

    Each enum value should end with a semicolon, not a comma. The zero value enum should have the suffix UNSPECIFIED.

    +

    Services

    +

    If your .proto defines an RPC service, you should use PascalCase (with an initial capital) for both the service name and any RPC method names:

    +
    service FooService {
    +   rpc GetSomething(GetSomethingRequest) returns (GetSomethingResponse);
    +   rpc ListSomething(ListSomethingRequest) returns (ListSomethingResponse);
    +}
    +

    GRPC Interface Versioning

    +

    All API interfaces must provide a major version number, which is encoded at the end of the protobuf package. +If an API introduces a breaking change, such as removing or renaming a field, it must increment its API version number to ensure that existing user code does not suddenly break. +Note: The use of the term “major version number” above is taken from semantic versioning. However, unlike in traditional semantic versioning, APIs must not expose minor or patch version numbers. +For example, APIs use v1, not v1.0, v1.1, or v1.4.2. From a user’s perspective, minor versions are updated in place, and users receive new functionality without migration.

    +

    A new major version of an API must not depend on a previous major version of the same API. An API may depend on other APIs, with an expectation that the caller understands the dependency and stability risk associated with those APIs. In this scenario, a stable API version must only depend on stable versions of other APIs.

    +

    Different versions of the same API should preferably be able to work at the same time within a single client application for a reasonable transition period. This time period allows the client to transition smoothly to the newer version. An older version must go through a reasonable, well-communicated deprecation period before being shut down.

    +

    For releases that have alpha or beta stability, APIs must append the stability level after the major version number in the protobuf package.

    +

    Release-based versioning

    +

    An individual release is an alpha or beta release that is expected to be available for a limited time period before its functionality is incorporated into the stable channel, after which the individual release will be shut down. +When using release-based versioning strategy, an API may have any number of individual releases at each stability level.

    +

    Alpha and beta releases must have their stability level appended to the version, followed by an incrementing release number. For example, v1beta1 or v1alpha5. APIs should document the chronological order of these versions in their documentation (such as comments). +Each alpha or beta release may be updated in place with backwards-compatible changes. For beta releases, backwards-incompatible updates should be made by incrementing the release number and publishing a new release with the change. For example, if the current version is v1beta1, then v1beta2 is released next.

    +

    Adapted from + +google release-based_versioning + under Apache 2.0 License & Creative Commons Attribution 4.0 License

    +

    Backwards compatibility

    +

    The gRPC protocol is designed to support services that change over time. Generally, additions to gRPC services and methods are non-breaking. Non-breaking changes allow existing clients to continue working without changes. Changing or deleting gRPC services are breaking changes. When gRPC services have breaking changes, clients using that service have to be updated and redeployed.

    +

    Making non-breaking changes to a service has a number of benefits:

    + +

    Non-breaking changes

    +

    These changes are non-breaking at a gRPC protocol level and binary level.

    + +

    Binary breaking changes

    +

    The following changes are non-breaking at a gRPC protocol level, but the client needs to be updated if it upgrades to the latest .proto contract. Binary compatibility is important if you plan to publish a gRPC library.

    + +

    Protocol breaking changes

    +

    The following items are protocol and binary breaking changes:

    + +

    Behavior breaking changes

    +

    When making non-breaking changes, you must also consider whether older clients can continue working with the new service behavior. For example, adding a new field to a request message:

    + +

    Behavior compatibility is determined by your app-specific code.

    +

    Adapted from + +Versioning gRPC services + under Creative Commons Attribution 4.0 License

    +

    gRPC Error Handling

    +

    In gRPC, a large set of error codes has been + +defined + +As a general rule, SDV should use relevant gRPC error codes, +as described in + +this thread +

    +
       return grpc::Status(grpc::StatusCode::NOT_FOUND, "error details here");
    +

    Available constructor:

    +
       grpc::Status::Status ( StatusCode  code,
    +      const std::string & error_message,
    +      const std::string & error_details
    +

    The framework for drafting error messages could be useful as a later improvement. This could e.g., be used to specify which unit created the error message and to assure the same structure on all messages. The latter two may e.g., depend on debug settings, e.g., error details only in debug-builds to avoid leaks of sensitive information. A global function like below or similar could handle that and also possibly convert between internal error codes and gRPC codes.

    +
       grpc::Status status = CreateStatusMessage(PERMISSION_DENIED,"DataBroker","Rule access rights violated");
    +

    SDV error handling for gRPC interfaces (e.g., VAL vehicles services)

    + +

    SDV handling of gRPC error codes

    +

    The table below gives error code guidelines for each gRPC on:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    gRPC error codeRetry Relevant?Recommended SDV usage
    OKNoMandatory error code if operation succeeded. Shall never be used if operation failed.
    CANCELLEDNoNo explicit use case on server side in SDV identified
    UNKNOWNNoTo be used in default-statements when converting errors from e.g., Broker-errors to SDV/gRPC errors
    INVALID_ARGUMENTNoE.g., Rule syntax with errors
    DEADLINE_EXCEEDEDYesOnly applicable for asynchronous services, i.e. services which wait for completion before the result is returned. The behavior if an operation cannot finish within expected time must be defined. Two options exist. One is to return this error after e.g., X seconds. Another is that the server never gives up, but rather waits for the client to cancel the operation.
    NOT_FOUNDNoLong term situation that likely not will change in the near future.
    Example: SDV can not find the specified resource (e.g., no path to get data for specified seat)
    ALREADY_EXISTSNoNo explicit use case on server side in SDV identified
    PERMISSION_DENIEDNoOperation rejected due to permission denied
    RESOURCE_EXHAUSTEDYesPossibly if e.g., malloc fails or similar errors.
    FAILED_PRECONDITIONYesCould be returned if e.g., operation is rejected due to safety reasons. (E.g., vehicle moving)
    ABORTEDYesCould e.g., be returned if service does not support concurrent requests, and there is already either a related operation ongoing or the operation is aborted due to a newer request received. Could also be used if an operation is aborted on user/driver request, e.g., physical button in vehicle pressed.
    OUT_OF_RANGENoE.g., Arguments out of range
    UNIMPLEMENTEDNoTo be used if certain use-cases of the service are not implemented, e.g., if recline cannot be adjusted
    INTERNALNoInternal errors, like exceptions, unexpected null pointers and similar
    UNAVAILABLEYesTo be used if the service is temporarily unavailable, e.g., during system startup.
    DATA_LOSSNoNo explicit use case identified on server side in SDV.
    UNAUTHENTICATEDNoNo explicit use case identified on server side in SDV.
    +

    Other references

    + + +
    + + + + + + diff --git a/docs/concepts/development_model/val/grpc_style_guide/index.html b/docs/concepts/development_model/val/grpc_style_guide/index.html new file mode 100644 index 00000000..5d16764b --- /dev/null +++ b/docs/concepts/development_model/val/grpc_style_guide/index.html @@ -0,0 +1,976 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +GRPC Interface Style Guide | Velocitas + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +
    + + +
    + + + + + +
    +

    GRPC Interface Style Guide

    + + +

    This provides a style guide for .proto files. By following these conventions, you’ll make your protocol buffer message definitions and their corresponding classes consistent and easy to read. +Unless otherwise indicated, this style guide is based on the style guide from + +google protocol-buffers style + under Apache 2.0 License & Creative Commons Attribution 4.0 License.

    +

    Note that protocol buffer style can evolve over time, so it is likely that you will see .proto files written in different conventions or styles. Please respect the existing style when you modify these files. Consistency is key. However, it is best to adopt the current best style when you are creating a new .proto file.

    +

    Standard file formatting

    +
      +
    • Keep the line length to 80 characters.
    • +
    • Use an indent of 2 spaces.
    • +
    • Prefer the use of double quotes for strings.
    • +
    +

    File structure

    +

    Files should be named lower_snake_case.proto

    +

    All files should be ordered in the following manner:

    +
      +
    • License header
    • +
    • File overview
    • +
    • Syntax
    • +
    • Package
    • +
    • Imports (sorted)
    • +
    • File options
    • +
    • Everything else
    • +
    +

    Directory Structure

    +

    Files should be stored in a directory structure that matches their package sub-names. All files +in a given directory should be in the same package. +Below is an example based on the + +proto files + in the kuksa.-databroker repository.

    +
    |   proto/
    +|   └── sdv
    +|       └── databroker
    +|           └── v1                  // package sdv.databroker.broker.v1
    +|               ├── broker.proto    // service Broker in sdv.databroker.broker.v1
    +|               ├── collector.proto // service Collector in sdv.databroker.broker.v1
    +|               └── types.proto     // type definition and import of  in sdv.databroker.broker.v1
    +

    The proposed structure shown above is adapted from + +Uber Protobuf Style Guide V2 + under MIT License.

    +

    Packages

    +

    Package names should be in lowercase. Package names should have unique names based on the project name, and possibly based on the path of the file containing the protocol buffer type definitions.

    +

    Message and field names

    +

    Use PascalCase (CamelCase with an initial capital) for message names – for example, SongServerRequest. Use underscore_separated_names for field names (including oneof field and extension names) – for example, song_name.

    +
    message SongServerRequest {
    +   optional string song_name = 1;
    +}
    +

    Using this naming convention for field names gives you accessors like the following:

    +

    C++:

    +
    const string& song_name() { ... }
    +void set_song_name(const string& x) { ... }
    +

    If your field name contains a number, the number should appear after the letter instead of after the underscore. For example, use song_name1 instead of song_name_1 +Repeated fields

    +

    Use pluralized names for repeated fields.

    +
    repeated string keys = 1;
    +...
    +repeated MyMessage accounts = 17;
    +

    Enums

    +

    Use PascalCase (with an initial capital) for enum type names and CAPITALS_WITH_UNDERSCORES for value names:

    +
    enum FooBar {
    +   FOO_BAR_UNSPECIFIED = 0;
    +   FOO_BAR_FIRST_VALUE = 1;
    +   FOO_BAR_SECOND_VALUE = 2;
    +}
    +

    Each enum value should end with a semicolon, not a comma. The zero value enum should have the suffix UNSPECIFIED.

    +

    Services

    +

    If your .proto defines an RPC service, you should use PascalCase (with an initial capital) for both the service name and any RPC method names:

    +
    service FooService {
    +   rpc GetSomething(GetSomethingRequest) returns (GetSomethingResponse);
    +   rpc ListSomething(ListSomethingRequest) returns (ListSomethingResponse);
    +}
    +

    GRPC Interface Versioning

    +

    All API interfaces must provide a major version number, which is encoded at the end of the protobuf package. +If an API introduces a breaking change, such as removing or renaming a field, it must increment its API version number to ensure that existing user code does not suddenly break. +Note: The use of the term “major version number” above is taken from semantic versioning. However, unlike in traditional semantic versioning, APIs must not expose minor or patch version numbers. +For example, APIs use v1, not v1.0, v1.1, or v1.4.2. From a user’s perspective, minor versions are updated in place, and users receive new functionality without migration.

    +

    A new major version of an API must not depend on a previous major version of the same API. An API may depend on other APIs, with an expectation that the caller understands the dependency and stability risk associated with those APIs. In this scenario, a stable API version must only depend on stable versions of other APIs.

    +

    Different versions of the same API should preferably be able to work at the same time within a single client application for a reasonable transition period. This time period allows the client to transition smoothly to the newer version. An older version must go through a reasonable, well-communicated deprecation period before being shut down.

    +

    For releases that have alpha or beta stability, APIs must append the stability level after the major version number in the protobuf package.

    +

    Release-based versioning

    +

    An individual release is an alpha or beta release that is expected to be available for a limited time period before its functionality is incorporated into the stable channel, after which the individual release will be shut down. +When using release-based versioning strategy, an API may have any number of individual releases at each stability level.

    +

    Alpha and beta releases must have their stability level appended to the version, followed by an incrementing release number. For example, v1beta1 or v1alpha5. APIs should document the chronological order of these versions in their documentation (such as comments). +Each alpha or beta release may be updated in place with backwards-compatible changes. For beta releases, backwards-incompatible updates should be made by incrementing the release number and publishing a new release with the change. For example, if the current version is v1beta1, then v1beta2 is released next.

    +

    Adapted from + +google release-based_versioning + under Apache 2.0 License & Creative Commons Attribution 4.0 License

    +

    Backwards compatibility

    +

    The gRPC protocol is designed to support services that change over time. Generally, additions to gRPC services and methods are non-breaking. Non-breaking changes allow existing clients to continue working without changes. Changing or deleting gRPC services are breaking changes. When gRPC services have breaking changes, clients using that service have to be updated and redeployed.

    +

    Making non-breaking changes to a service has a number of benefits:

    +
      +
    • Existing clients continue to run.
    • +
    • Avoids work involved with notifying clients of breaking changes, and updating them.
    • +
    • Only one version of the service needs to be documented and maintained.
    • +
    +

    Non-breaking changes

    +

    These changes are non-breaking at a gRPC protocol level and binary level.

    +
      +
    • Adding a new service
    • +
    • Adding a new method to a service
    • +
    • Adding a field to a request message - Fields added to a request message are deserialized with the default value on the server when not set. To be a non-breaking change, the service must succeed when the new field isn’t set by older clients.
    • +
    • Adding a field to a response message - Fields added to a response message are deserialized into the message’s unknown fields collection on the client.
    • +
    • Adding a value to an enum - Enums are serialized as a numeric value. New enum values are deserialized on the client to the enum value without an enum name. To be a non-breaking change, older clients must run correctly when receiving the new enum value.
    • +
    +

    Binary breaking changes

    +

    The following changes are non-breaking at a gRPC protocol level, but the client needs to be updated if it upgrades to the latest .proto contract. Binary compatibility is important if you plan to publish a gRPC library.

    +
      +
    • Removing a field - Values from a removed field are deserialized to a message’s unknown fields. This isn’t a gRPC protocol breaking change, but the client needs to be updated if it upgrades to the latest contract. It’s important that a removed field number isn’t accidentally reused in the future. To ensure this doesn’t happen, specify deleted field numbers and names on the message using Protobuf’s reserved keyword.
    • +
    • Renaming a message - Message names aren’t typically sent on the network, so this isn’t a gRPC protocol breaking change. The client will need to be updated if it upgrades to the latest contract. One situation where message names are sent on the network is with Any fields, when the message name is used to identify the message type.
    • +
    • Nesting or unnesting a message - Message types can be nested. Nesting or unnesting a message changes its message name. Changing how a message type is nested has the same impact on compatibility as renaming.
    • +
    +

    Protocol breaking changes

    +

    The following items are protocol and binary breaking changes:

    +
      +
    • Renaming a field - With Protobuf content, the field names are only used in generated code. The field number is used to identify fields on the network. Renaming a field isn’t a protocol breaking change for Protobuf. However, if a server is using JSON content, then renaming a field is a breaking change.
    • +
    • Changing a field data type - Changing a field’s data type to an incompatible type will cause errors when deserializing the message. Even if the new data type is compatible, it’s likely the client needs to be updated to support the new type if it upgrades to the latest contract.
    • +
    • Changing a field number - With Protobuf payloads, the field number is used to identify fields on the network.
    • +
    • Renaming a package, service or method - gRPC uses the package name, service name, and method name to build the URL. The client gets an UNIMPLEMENTED status from the server.
    • +
    • Removing a service or method - The client gets an UNIMPLEMENTED status from the server when calling the removed method.
    • +
    +

    Behavior breaking changes

    +

    When making non-breaking changes, you must also consider whether older clients can continue working with the new service behavior. For example, adding a new field to a request message:

    +
      +
    • Isn’t a protocol breaking change.
    • +
    • Returning an error status on the server if the new field isn’t set makes it a breaking change for old clients.
    • +
    +

    Behavior compatibility is determined by your app-specific code.

    +

    Adapted from + +Versioning gRPC services + under Creative Commons Attribution 4.0 License

    +

    gRPC Error Handling

    +

    In gRPC, a large set of error codes has been + +defined + +As a general rule, SDV should use relevant gRPC error codes, +as described in + +this thread +

    +
       return grpc::Status(grpc::StatusCode::NOT_FOUND, "error details here");
    +

    Available constructor:

    +
       grpc::Status::Status ( StatusCode  code,
    +      const std::string & error_message,
    +      const std::string & error_details
    +

    The framework for drafting error messages could be useful as a later improvement. This could e.g., be used to specify which unit created the error message and to assure the same structure on all messages. The latter two may e.g., depend on debug settings, e.g., error details only in debug-builds to avoid leaks of sensitive information. A global function like below or similar could handle that and also possibly convert between internal error codes and gRPC codes.

    +
       grpc::Status status = CreateStatusMessage(PERMISSION_DENIED,"DataBroker","Rule access rights violated");
    +

    SDV error handling for gRPC interfaces (e.g., VAL vehicles services)

    +
      +
    • Use gRPC error codes as base
    • +
    • Document in proto files (as comments) which error codes that the service implementation can emit and the meaning of them. (Errors that only are emitted by the gRPC framework do not need to be listed.)
    • +
    • Do not - unless there are special reasons - add explicit error/status fields to rpc return messages.
    • +
    • Additional error information can be given by free text fields in gRPC error codes. Note, however, that sensitive information like Given password ABCD does not match expected password EFGH should not be passed in an unprotected/unencrypted manner.
    • +
    +

    SDV handling of gRPC error codes

    +

    The table below gives error code guidelines for each gRPC on:

    +
      +
    • If it is relevant for a client to retry the call or not when receiving the error code. Retry is only relevant if the error is of a temporary nature.
    • +
    • When to use the error code when implementing a service.
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    gRPC error codeRetry Relevant?Recommended SDV usage
    OKNoMandatory error code if operation succeeded. Shall never be used if operation failed.
    CANCELLEDNoNo explicit use case on server side in SDV identified
    UNKNOWNNoTo be used in default-statements when converting errors from e.g., Broker-errors to SDV/gRPC errors
    INVALID_ARGUMENTNoE.g., Rule syntax with errors
    DEADLINE_EXCEEDEDYesOnly applicable for asynchronous services, i.e. services which wait for completion before the result is returned. The behavior if an operation cannot finish within expected time must be defined. Two options exist. One is to return this error after e.g., X seconds. Another is that the server never gives up, but rather waits for the client to cancel the operation.
    NOT_FOUNDNoLong term situation that likely not will change in the near future.
    Example: SDV can not find the specified resource (e.g., no path to get data for specified seat)
    ALREADY_EXISTSNoNo explicit use case on server side in SDV identified
    PERMISSION_DENIEDNoOperation rejected due to permission denied
    RESOURCE_EXHAUSTEDYesPossibly if e.g., malloc fails or similar errors.
    FAILED_PRECONDITIONYesCould be returned if e.g., operation is rejected due to safety reasons. (E.g., vehicle moving)
    ABORTEDYesCould e.g., be returned if service does not support concurrent requests, and there is already either a related operation ongoing or the operation is aborted due to a newer request received. Could also be used if an operation is aborted on user/driver request, e.g., physical button in vehicle pressed.
    OUT_OF_RANGENoE.g., Arguments out of range
    UNIMPLEMENTEDNoTo be used if certain use-cases of the service are not implemented, e.g., if recline cannot be adjusted
    INTERNALNoInternal errors, like exceptions, unexpected null pointers and similar
    UNAVAILABLEYesTo be used if the service is temporarily unavailable, e.g., during system startup.
    DATA_LOSSNoNo explicit use case identified on server side in SDV.
    UNAUTHENTICATEDNoNo explicit use case identified on server side in SDV.
    +

    Other references

    + + + + +
    + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3) +
    + +
    + + +
    +
    +
    + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/docs/concepts/development_model/val/index.html b/docs/concepts/development_model/val/index.html index 3f081b19..43048b52 100644 --- a/docs/concepts/development_model/val/index.html +++ b/docs/concepts/development_model/val/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -433,7 +455,7 @@
  • Source Code
  • -
  • Guidelines
  • +
  • GRPC Interface Style Guide
  • @@ -517,13 +539,13 @@

    Introduction

    COVESA Vehicle Signal Specification (VSS) . The Vehicle API eliminates the need to know the source, destination, and format of signals for the vehicle system.

    -

    The Eclipse Velocitas project is using the VAL of the +

    The Eclipse Velocitas project is using the Eclipse KUKSA project -, also called KUKSA.VAL. -KUKSA.VAL does not provide a concrete VAL. That’s up to you as an OEM (vehicle manufacturer) or as a supplier. -But KUKSA.VAL provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an Vehicle App or Service.

    -

    KUKSA.VAL provides you with ready-to-use generic components for the signal-based access to the vehicle, like the KUKSA Databroker and the generic Data Providers (aka Data Feeders). +. +KUKSA does not provide a concrete VAL. That’s up to you as an OEM (vehicle manufacturer) or as a supplier. +But KUKSA provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an Vehicle App or Service.

    +

    KUKSA provides you with ready-to-use generic components for the signal-based access to the vehicle, like the KUKSA Databroker and the generic Data Providers (aka Data Feeders). It also provides you reference implementations of certain Vehicle Services, like the Seat Service and the HVAC Service.

    Architecture

    The image below shows the main components of the VAL and its relation to the @@ -565,7 +587,7 @@

    Vehicle Services

    It communicates with the Hardware Abstraction to execute the underlying services, but may also interact with the Databroker.

    The -KUKSA.VAL Services repository +KUKSA Incubation repository contains examples illustrating how such kind of vehicle services can be built.

    Hardware Abstraction

    Data feeders rely on hardware abstraction. Hardware abstraction is project/platform specific. @@ -658,13 +680,11 @@

    Source Code

    KUKSA example providers -

    Guidelines

    - +GRPC Interface Style Guide +

    @@ -675,13 +695,23 @@

    Guidelines

    +
    + + +
    +
    + GRPC Interface Style Guide +
    +

    +
    +
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/development_model/val/index.xml b/docs/concepts/development_model/val/index.xml index 8e80a273..0a84e602 100644 --- a/docs/concepts/development_model/val/index.xml +++ b/docs/concepts/development_model/val/index.xml @@ -15,5 +15,286 @@ + + Docs: GRPC Interface Style Guide + /velocitas-docs/docs/concepts/development_model/val/grpc_style_guide/ + Mon, 09 May 2022 14:24:56 +0530 + + /velocitas-docs/docs/concepts/development_model/val/grpc_style_guide/ + + + + <p>This provides a style guide for .proto files. By following these conventions, you&rsquo;ll make your protocol buffer message definitions and their corresponding classes consistent and easy to read. +Unless otherwise indicated, this style guide is based on the style guide from + +<a href="https://developers.google.com/protocol-buffers/docs/style" target="_blank" rel="noopener">google protocol-buffers style</a> + under Apache 2.0 License &amp; Creative Commons Attribution 4.0 License.</p> +<p>Note that protocol buffer style can evolve over time, so it is likely that you will see .proto files written in different conventions or styles. Please respect the existing style when you modify these files. Consistency is key. However, it is best to adopt the current best style when you are creating a new .proto file.</p> +<h3 id="standard-file-formatting">Standard file formatting</h3> +<ul> +<li>Keep the line length to 80 characters.</li> +<li>Use an indent of 2 spaces.</li> +<li>Prefer the use of double quotes for strings.</li> +</ul> +<h3 id="file-structure">File structure</h3> +<p>Files should be named lower_snake_case.proto</p> +<p>All files should be ordered in the following manner:</p> +<ul> +<li>License header</li> +<li>File overview</li> +<li>Syntax</li> +<li>Package</li> +<li>Imports (sorted)</li> +<li>File options</li> +<li>Everything else</li> +</ul> +<h3 id="directory-structure">Directory Structure</h3> +<p>Files should be stored in a directory structure that matches their package sub-names. All files +in a given directory should be in the same package. +Below is an example based on the + +<a href="https://github.com/eclipse-kuksa/kuksa-databroker/tree/main/proto/sdv/databroker/v1" target="_blank" rel="noopener">proto files</a> + in the kuksa.-databroker repository.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>| proto/ +</span></span><span style="display:flex;"><span>| └── sdv +</span></span><span style="display:flex;"><span>| └── databroker +</span></span><span style="display:flex;"><span>| └── v1 // package sdv.databroker.broker.v1 +</span></span><span style="display:flex;"><span>| ├── broker.proto // service Broker in sdv.databroker.broker.v1 +</span></span><span style="display:flex;"><span>| ├── collector.proto // service Collector in sdv.databroker.broker.v1 +</span></span><span style="display:flex;"><span>| └── types.proto // type definition and import of in sdv.databroker.broker.v1 +</span></span></code></pre></div><p>The proposed structure shown above is adapted from + +<a href="https://raw.githubusercontent.com/uber/prototool/dev/style/README.md" target="_blank" rel="noopener">Uber Protobuf Style Guide V2</a> + under MIT License.</p> +<h3 id="packages">Packages</h3> +<p>Package names should be in lowercase. Package names should have unique names based on the project name, and possibly based on the path of the file containing the protocol buffer type definitions.</p> +<h3 id="message-and-field-names">Message and field names</h3> +<p>Use PascalCase (CamelCase with an initial capital) for message names – for example, SongServerRequest. Use underscore_separated_names for field names (including oneof field and extension names) – for example, song_name.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>message SongServerRequest { +</span></span><span style="display:flex;"><span> optional string song_name = 1; +</span></span><span style="display:flex;"><span>} +</span></span></code></pre></div><p>Using this naming convention for field names gives you accessors like the following:</p> +<p>C++:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">const</span> <span style="color:#000">string</span><span style="color:#ce5c00;font-weight:bold">&amp;</span> <span style="color:#000">song_name</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#000;font-weight:bold">{</span> <span style="color:#000;font-weight:bold">...</span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">void</span> <span style="color:#000">set_song_name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">const</span> <span style="color:#000">string</span><span style="color:#ce5c00;font-weight:bold">&amp;</span> <span style="color:#000">x</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> <span style="color:#000;font-weight:bold">...</span> <span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><p>If your field name contains a number, the number should appear after the letter instead of after the underscore. For example, use song_name1 instead of song_name_1 +Repeated fields</p> +<p>Use pluralized names for repeated fields.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-proto" data-lang="proto"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">repeated</span> <span style="color:#204a87;font-weight:bold">string</span> <span style="color:#000">keys</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">;</span><span style="color:#a40000"> +</span></span></span><span style="display:flex;"><span><span style="color:#a40000"></span><span style="color:#ce5c00;font-weight:bold">...</span><span style="color:#a40000"> +</span></span></span><span style="display:flex;"><span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">repeated</span> <span style="color:#000">MyMessage</span> <span style="color:#000">accounts</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#0000cf;font-weight:bold">17</span><span style="color:#000;font-weight:bold">;</span><span style="color:#a40000"> +</span></span></span></code></pre></div><h3 id="enums">Enums</h3> +<p>Use PascalCase (with an initial capital) for enum type names and CAPITALS_WITH_UNDERSCORES for value names:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">enum</span> <span style="color:#000">FooBar</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">FOO_BAR_UNSPECIFIED</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">FOO_BAR_FIRST_VALUE</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">FOO_BAR_SECOND_VALUE</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#0000cf;font-weight:bold">2</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><p>Each enum value should end with a semicolon, not a comma. The zero value enum should have the suffix UNSPECIFIED.</p> +<h3 id="services">Services</h3> +<p>If your .proto defines an RPC service, you should use PascalCase (with an initial capital) for both the service name and any RPC method names:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-proto" data-lang="proto"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">service</span> <span style="color:#000">FooService</span> <span style="color:#000;font-weight:bold">{</span><span style="color:#a40000"> +</span></span></span><span style="display:flex;"><span><span style="color:#a40000"></span> <span style="color:#204a87;font-weight:bold">rpc</span> <span style="color:#000">GetSomething</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">GetSomethingRequest</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#204a87;font-weight:bold">returns</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">GetSomethingResponse</span><span style="color:#000;font-weight:bold">);</span><span style="color:#a40000"> +</span></span></span><span style="display:flex;"><span><span style="color:#a40000"></span> <span style="color:#204a87;font-weight:bold">rpc</span> <span style="color:#000">ListSomething</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">ListSomethingRequest</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#204a87;font-weight:bold">returns</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">ListSomethingResponse</span><span style="color:#000;font-weight:bold">);</span><span style="color:#a40000"> +</span></span></span><span style="display:flex;"><span><span style="color:#a40000"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#a40000"> +</span></span></span></code></pre></div><h3 id="grpc-interface-versioning">GRPC Interface Versioning</h3> +<p>All API interfaces must provide a major version number, which is encoded at the end of the protobuf package. +If an API introduces a breaking change, such as removing or renaming a field, it must increment its API version number to ensure that existing user code does not suddenly break. +Note: The use of the term &ldquo;major version number&rdquo; above is taken from semantic versioning. However, unlike in traditional semantic versioning, APIs must not expose minor or patch version numbers. +For example, APIs use v1, not v1.0, v1.1, or v1.4.2. From a user&rsquo;s perspective, minor versions are updated in place, and users receive new functionality without migration.</p> +<p>A new major version of an API must not depend on a previous major version of the same API. An API may depend on other APIs, with an expectation that the caller understands the dependency and stability risk associated with those APIs. In this scenario, a stable API version must only depend on stable versions of other APIs.</p> +<p>Different versions of the same API should preferably be able to work at the same time within a single client application for a reasonable transition period. This time period allows the client to transition smoothly to the newer version. An older version must go through a reasonable, well-communicated deprecation period before being shut down.</p> +<p>For releases that have alpha or beta stability, APIs must append the stability level after the major version number in the protobuf package.</p> +<h4 id="release-based-versioning">Release-based versioning</h4> +<p>An individual release is an alpha or beta release that is expected to be available for a limited time period before its functionality is incorporated into the stable channel, after which the individual release will be shut down. +When using release-based versioning strategy, an API may have any number of individual releases at each stability level.</p> +<p>Alpha and beta releases must have their stability level appended to the version, followed by an incrementing release number. For example, v1beta1 or v1alpha5. APIs should document the chronological order of these versions in their documentation (such as comments). +Each alpha or beta release may be updated in place with backwards-compatible changes. For beta releases, backwards-incompatible updates should be made by incrementing the release number and publishing a new release with the change. For example, if the current version is v1beta1, then v1beta2 is released next.</p> +<p>Adapted from + +<a href="https://cloud.google.com/apis/design/versioning?hl=en#release-based_versioning" target="_blank" rel="noopener">google release-based_versioning</a> + under Apache 2.0 License &amp; Creative Commons Attribution 4.0 License</p> +<h3 id="backwards-compatibility">Backwards compatibility</h3> +<p>The gRPC protocol is designed to support services that change over time. Generally, additions to gRPC services and methods are non-breaking. Non-breaking changes allow existing clients to continue working without changes. Changing or deleting gRPC services are breaking changes. When gRPC services have breaking changes, clients using that service have to be updated and redeployed.</p> +<p>Making non-breaking changes to a service has a number of benefits:</p> +<ul> +<li>Existing clients continue to run.</li> +<li>Avoids work involved with notifying clients of breaking changes, and updating them.</li> +<li>Only one version of the service needs to be documented and maintained.</li> +</ul> +<h3 id="non-breaking-changes">Non-breaking changes</h3> +<p>These changes are non-breaking at a gRPC protocol level and binary level.</p> +<ul> +<li>Adding a new service</li> +<li>Adding a new method to a service</li> +<li>Adding a field to a request message - Fields added to a request message are deserialized with the default value on the server when not set. To be a non-breaking change, the service must succeed when the new field isn&rsquo;t set by older clients.</li> +<li>Adding a field to a response message - Fields added to a response message are deserialized into the message&rsquo;s unknown fields collection on the client.</li> +<li>Adding a value to an enum - Enums are serialized as a numeric value. New enum values are deserialized on the client to the enum value without an enum name. To be a non-breaking change, older clients must run correctly when receiving the new enum value.</li> +</ul> +<h3 id="binary-breaking-changes">Binary breaking changes</h3> +<p>The following changes are non-breaking at a gRPC protocol level, but the client needs to be updated if it upgrades to the latest .proto contract. Binary compatibility is important if you plan to publish a gRPC library.</p> +<ul> +<li>Removing a field - Values from a removed field are deserialized to a message&rsquo;s unknown fields. This isn&rsquo;t a gRPC protocol breaking change, but the client needs to be updated if it upgrades to the latest contract. It&rsquo;s important that a removed field number isn&rsquo;t accidentally reused in the future. To ensure this doesn&rsquo;t happen, specify deleted field numbers and names on the message using Protobuf&rsquo;s reserved keyword.</li> +<li>Renaming a message - Message names aren&rsquo;t typically sent on the network, so this isn&rsquo;t a gRPC protocol breaking change. The client will need to be updated if it upgrades to the latest contract. One situation where message names are sent on the network is with Any fields, when the message name is used to identify the message type.</li> +<li>Nesting or unnesting a message - Message types can be nested. Nesting or unnesting a message changes its message name. Changing how a message type is nested has the same impact on compatibility as renaming.</li> +</ul> +<h3 id="protocol-breaking-changes">Protocol breaking changes</h3> +<p>The following items are protocol and binary breaking changes:</p> +<ul> +<li>Renaming a field - With Protobuf content, the field names are only used in generated code. The field number is used to identify fields on the network. Renaming a field isn&rsquo;t a protocol breaking change for Protobuf. However, if a server is using JSON content, then renaming a field is a breaking change.</li> +<li>Changing a field data type - Changing a field&rsquo;s data type to an incompatible type will cause errors when deserializing the message. Even if the new data type is compatible, it&rsquo;s likely the client needs to be updated to support the new type if it upgrades to the latest contract.</li> +<li>Changing a field number - With Protobuf payloads, the field number is used to identify fields on the network.</li> +<li>Renaming a package, service or method - gRPC uses the package name, service name, and method name to build the URL. The client gets an UNIMPLEMENTED status from the server.</li> +<li>Removing a service or method - The client gets an UNIMPLEMENTED status from the server when calling the removed method.</li> +</ul> +<h3 id="behavior-breaking-changes">Behavior breaking changes</h3> +<p>When making non-breaking changes, you must also consider whether older clients can continue working with the new service behavior. For example, adding a new field to a request message:</p> +<ul> +<li>Isn&rsquo;t a protocol breaking change.</li> +<li>Returning an error status on the server if the new field isn&rsquo;t set makes it a breaking change for old clients.</li> +</ul> +<p>Behavior compatibility is determined by your app-specific code.</p> +<p>Adapted from + +<a href="https://docs.microsoft.com/en-us/aspnet/core/grpc/versioning?view=aspnetcore-6.0" target="_blank" rel="noopener">Versioning gRPC services</a> + under Creative Commons Attribution 4.0 License</p> +<h2 id="grpc-error-handling">gRPC Error Handling</h2> +<p>In gRPC, a large set of error codes has been + +<a href="https://grpc.github.io/grpc/cpp/md_doc_statuscodes.html" target="_blank" rel="noopener">defined</a> + +As a general rule, SDV should use relevant gRPC error codes, +as described in + +<a href="https://stackoverflow.com/questions/59094839/whats-the-correct-way-to-return-a-not-found-response-from-a-grpc-c-server-i" target="_blank" rel="noopener">this thread</a> +</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">StatusCode</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">NOT_FOUND</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;error details here&#34;</span><span style="color:#000;font-weight:bold">);</span> +</span></span></code></pre></div><p>Available constructor:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span> <span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span> <span style="color:#000;font-weight:bold">(</span> <span style="color:#000">StatusCode</span> <span style="color:#000">code</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">const</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">string</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span> <span style="color:#000">error_message</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">const</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">string</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span> <span style="color:#000">error_details</span> +</span></span></code></pre></div><p>The framework for drafting error messages could be useful as a later improvement. This could e.g., be used to specify which unit created the error message and to assure the same structure on all messages. The latter two may e.g., depend on debug settings, e.g., error details only in debug-builds to avoid leaks of sensitive information. A global function like below or similar could handle that and also possibly convert between internal error codes and gRPC codes.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span> <span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span> <span style="color:#000">status</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">CreateStatusMessage</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">PERMISSION_DENIED</span><span style="color:#000;font-weight:bold">,</span><span style="color:#4e9a06">&#34;DataBroker&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#4e9a06">&#34;Rule access rights violated&#34;</span><span style="color:#000;font-weight:bold">);</span> +</span></span></code></pre></div><h3 id="sdv-error-handling-for-grpc-interfaces-eg-val-vehicles-services">SDV error handling for gRPC interfaces (e.g., VAL vehicles services)</h3> +<ul> +<li>Use gRPC error codes as base</li> +<li>Document in proto files (as comments) which error codes that the service implementation can emit and the meaning of them. (Errors that only are emitted by the gRPC framework do not need to be listed.)</li> +<li>Do not - unless there are special reasons - add explicit error/status fields to rpc return messages.</li> +<li>Additional error information can be given by free text fields in gRPC error codes. Note, however, that sensitive information like <code>Given password ABCD does not match expected password EFGH</code> should not be passed in an unprotected/unencrypted manner.</li> +</ul> +<h3 id="sdv-handling-of-grpc-error-codes">SDV handling of gRPC error codes</h3> +<p>The table below gives error code guidelines for each gRPC on:</p> +<ul> +<li>If it is relevant for a client to retry the call or not when receiving the error code. Retry is only relevant if the error is of a temporary nature.</li> +<li>When to use the error code when implementing a service.</li> +</ul> +<table border="1"> + <tbody> + <tr> + <th>gRPC error code</th> + <th>Retry Relevant?</th> + <th>Recommended SDV usage</th> + </tr> + <tr> + <td>OK</td> + <td>No</td> + <td>Mandatory error code if operation succeeded. Shall never be used if operation failed.</td> + </tr> + <tr> + <td>CANCELLED</td> + <td>No</td> + <td>No explicit use case on server side in SDV identified</td> + </tr> + <tr> + <td>UNKNOWN</td> + <td>No</td> + <td>To be used in default-statements when converting errors from e.g., Broker-errors to SDV/gRPC errors</td> + </tr> + <tr> + <td>INVALID_ARGUMENT</td> + <td>No</td> + <td>E.g., Rule syntax with errors</td> + </tr> + <tr> + <td>DEADLINE_EXCEEDED</td> + <td>Yes</td> + <td>Only applicable for asynchronous services, i.e. services which wait for completion before the result is returned. The behavior if an operation cannot finish within expected time must be defined. Two options exist. One is to return this error after e.g., X seconds. Another is that the server never gives up, but rather waits for the client to cancel the operation.</td> + </tr> + <tr> + <td>NOT_FOUND</td> + <td>No</td> + <td>Long term situation that likely not will change in the near future. <br/> Example: SDV can not find the specified resource (e.g., no path to get data for specified seat) </td> + </tr> + <tr> + <td>ALREADY_EXISTS</td> + <td>No</td> + <td>No explicit use case on server side in SDV identified</td> + </tr> + <tr> + <td>PERMISSION_DENIED</td> + <td>No</td> + <td>Operation rejected due to permission denied</td> + </tr> + <tr> + <td>RESOURCE_EXHAUSTED</td> + <td>Yes</td> + <td>Possibly if e.g., malloc fails or similar errors.</td> + </tr> + <tr> + <td>FAILED_PRECONDITION</td> + <td>Yes</td> + <td>Could be returned if e.g., operation is rejected due to safety reasons. (E.g., vehicle moving)</td> + </tr> + <tr> + <td>ABORTED</td> + <td>Yes</td> + <td>Could e.g., be returned if service does not support concurrent requests, and there is already either a related operation ongoing or the operation is aborted due to a newer request received. Could also be used if an operation is aborted on user/driver request, e.g., physical button in vehicle pressed.</td> + </tr> + <tr> + <td>OUT_OF_RANGE</td> + <td>No</td> + <td>E.g., Arguments out of range</td> + </tr> + <tr> + <td>UNIMPLEMENTED</td> + <td>No</td> + <td>To be used if certain use-cases of the service are not implemented, e.g., if recline cannot be adjusted</td> + </tr> + <tr> + <td>INTERNAL</td> + <td>No</td> + <td>Internal errors, like exceptions, unexpected null pointers and similar</td> + </tr> + <tr> + <td>UNAVAILABLE</td> + <td>Yes</td> + <td>To be used if the service is temporarily unavailable, e.g., during system startup.</td> + </tr> + <tr> + <td>DATA_LOSS</td> + <td>No</td> + <td>No explicit use case identified on server side in SDV.</td> + </tr> + <tr> + <td>UNAUTHENTICATED</td> + <td>No</td> + <td>No explicit use case identified on server side in SDV.</td> + </tr> +</table> +<h3 id="other-references">Other references</h3> +<ul> +<li> + +<a href="https://stackoverflow.com/questions/48748745/pattern-for-rich-error-handling-in-grpc" target="_blank" rel="noopener">Pattern for rich error handling in gRPC</a> +</li> +<li> + +<a href="https://jbrandhorst.com/post/grpc-errors/" target="_blank" rel="noopener">Advanced gRPC Error Usage</a> +</li> +</ul> + + + + diff --git a/docs/concepts/development_model/vehicle_app_manifest/_print/index.html b/docs/concepts/development_model/vehicle_app_manifest/_print/index.html index 9c649d20..c8230737 100644 --- a/docs/concepts/development_model/vehicle_app_manifest/_print/index.html +++ b/docs/concepts/development_model/vehicle_app_manifest/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -530,6 +530,15 @@

    Configuration structure

    URI of the used COVESA Vehicle Signal Specification JSON export. URI may point to a local file or to a file provided by a server.  +unit_src +string +["abs_path_unit_file_1", "abs_path_unit_file_2", "uri_unit_file_3"] +An array of URI’s/absolute path’s of the used COVESA Vehicle Signal Specification unit file(s) in yaml format. URI may point to a local file or to a file provided by a server. If none is provided a default one will be used ( + +https://github.com/COVESA/vehicle_signal_specification/blob/v4.0/spec/units.yaml) +.  + + datapoints object Object containing both required and provided datapoints. @@ -600,7 +609,9 @@

    Example

    } } } - +

    Different VSS versions

    +

    The model generation is supported for VSS versions up to v4.0. There are some changes for some paths from v3.0 to v4.0. For example Vehicle.Cabin.Seat.Row1.Pos1.Position in v3.0 is Vehicle.Cabin.Seat.Row1.DriverSide.Position in v4.0. If you are using the mock provider you would need to take that into account when you sepcify your mock.py.

    + @@ -690,7 +701,11 @@

    Configuration structure

    -

    Example

    +

    Execution

    +

    velocitas init +or +velocitas exec grpc-interface-support generate-sdk

    +

    Project configuration

    {
       "type": "grpc-interface",
       "config": {
    @@ -699,10 +714,23 @@ 

    Example

    "methods": [ "Move", "MoveComponent" ] - } + }, + "provided": { } } } -
    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    + diff --git a/docs/concepts/development_model/vehicle_app_manifest/index.html b/docs/concepts/development_model/vehicle_app_manifest/index.html index 8369d0d6..02fc4f6f 100644 --- a/docs/concepts/development_model/vehicle_app_manifest/index.html +++ b/docs/concepts/development_model/vehicle_app_manifest/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -772,7 +794,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/development_model/vehicle_app_manifest/interfaces/_print/index.html b/docs/concepts/development_model/vehicle_app_manifest/interfaces/_print/index.html index cb3ba635..99e47740 100644 --- a/docs/concepts/development_model/vehicle_app_manifest/interfaces/_print/index.html +++ b/docs/concepts/development_model/vehicle_app_manifest/interfaces/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -247,6 +247,15 @@

    Configuration structure

    URI of the used COVESA Vehicle Signal Specification JSON export. URI may point to a local file or to a file provided by a server.  +unit_src +string +["abs_path_unit_file_1", "abs_path_unit_file_2", "uri_unit_file_3"] +An array of URI’s/absolute path’s of the used COVESA Vehicle Signal Specification unit file(s) in yaml format. URI may point to a local file or to a file provided by a server. If none is provided a default one will be used ( + +https://github.com/COVESA/vehicle_signal_specification/blob/v4.0/spec/units.yaml) +.  + + datapoints object Object containing both required and provided datapoints. @@ -317,7 +326,9 @@

    Example

    } } } - +

    Different VSS versions

    +

    The model generation is supported for VSS versions up to v4.0. There are some changes for some paths from v3.0 to v4.0. For example Vehicle.Cabin.Seat.Row1.Pos1.Position in v3.0 is Vehicle.Cabin.Seat.Row1.DriverSide.Position in v4.0. If you are using the mock provider you would need to take that into account when you sepcify your mock.py.

    + @@ -407,7 +418,11 @@

    Configuration structure

    -

    Example

    +

    Execution

    +

    velocitas init +or +velocitas exec grpc-interface-support generate-sdk

    +

    Project configuration

    {
       "type": "grpc-interface",
       "config": {
    @@ -416,10 +431,23 @@ 

    Example

    "methods": [ "Move", "MoveComponent" ] - } + }, + "provided": { } } } -
    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    + diff --git a/docs/concepts/development_model/vehicle_app_manifest/interfaces/grpc_interface/index.html b/docs/concepts/development_model/vehicle_app_manifest/interfaces/grpc_interface/index.html index 9419ae83..9afb49e3 100644 --- a/docs/concepts/development_model/vehicle_app_manifest/interfaces/grpc_interface/index.html +++ b/docs/concepts/development_model/vehicle_app_manifest/interfaces/grpc_interface/index.html @@ -42,13 +42,13 @@ - + - - + + @@ -93,7 +93,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -422,7 +444,8 @@ @@ -576,7 +599,11 @@

    Configuration structure

    -

    Example

    +

    Execution

    +

    velocitas init +or +velocitas exec grpc-interface-support generate-sdk

    +

    Project configuration

    {
       "type": "grpc-interface",
       "config": {
    @@ -585,14 +612,27 @@ 

    Example

    "methods": [ "Move", "MoveComponent" ] - } + }, + "provided": { } } } -
    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    +
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/development_model/vehicle_app_manifest/interfaces/index.html b/docs/concepts/development_model/vehicle_app_manifest/interfaces/index.html index 4581b746..41cd80a1 100644 --- a/docs/concepts/development_model/vehicle_app_manifest/interfaces/index.html +++ b/docs/concepts/development_model/vehicle_app_manifest/interfaces/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -530,7 +552,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/development_model/vehicle_app_manifest/interfaces/index.xml b/docs/concepts/development_model/vehicle_app_manifest/interfaces/index.xml index 498b3dcd..87b50782 100644 --- a/docs/concepts/development_model/vehicle_app_manifest/interfaces/index.xml +++ b/docs/concepts/development_model/vehicle_app_manifest/interfaces/index.xml @@ -85,6 +85,15 @@ <td>URI of the used COVESA Vehicle Signal Specification JSON export. URI may point to a local file or to a file provided by a server. </td> </tr> <tr> +<td><code>unit_src</code></td> +<td>string</td> +<td><code>[&quot;abs_path_unit_file_1&quot;, &quot;abs_path_unit_file_2&quot;, &quot;uri_unit_file_3&quot;]</code></td> +<td>An array of URI&rsquo;s/absolute path&rsquo;s of the used COVESA Vehicle Signal Specification unit file(s) in yaml format. URI may point to a local file or to a file provided by a server. If none is provided a default one will be used ( + +<a href="https://github.com/COVESA/vehicle_signal_specification/blob/v4.0/spec/units.yaml%29" target="_blank" rel="noopener">https://github.com/COVESA/vehicle_signal_specification/blob/v4.0/spec/units.yaml)</a> +. </td> +</tr> +<tr> <td><code>datapoints</code></td> <td>object</td> <td>Object containing both required and provided datapoints.</td> @@ -155,7 +164,9 @@ </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> </span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> -</span></span></code></pre></div> +</span></span></code></pre></div><h2 id="different-vss-versions">Different VSS versions</h2> +<p>The model generation is supported for VSS versions up to v4.0. There are some changes for some paths from v3.0 to v4.0. For example <code>Vehicle.Cabin.Seat.Row1.Pos1.Position</code> in v3.0 is <code>Vehicle.Cabin.Seat.Row1.DriverSide.Position</code> in v4.0. If you are using the mock provider you would need to take that into account when you sepcify your mock.py.</p> + @@ -241,7 +252,11 @@ </table> -<h2 id="example">Example</h2> +<h2 id="execution">Execution</h2> +<p><code>velocitas init</code> +<strong>or</strong> +<code>velocitas exec grpc-interface-support generate-sdk</code></p> +<h2 id="project-configuration">Project configuration</h2> <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span> </span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;type&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;grpc-interface&#34;</span><span style="color:#000;font-weight:bold">,</span> </span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;config&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> @@ -250,10 +265,23 @@ </span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;methods&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span> </span></span><span style="display:flex;"><span> <span style="color:#4e9a06">&#34;Move&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;MoveComponent&#34;</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">]</span> -</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;provided&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> <span style="color:#000;font-weight:bold">}</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> </span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> -</span></span></code></pre></div> +</span></span></code></pre></div><p>You need to specify <code>devenv-devcontainer-setup</code> &gt;= <code>v2.4.2</code> in your project configuration. Therefore your <code>.veloitas.json</code> should look similair to this example:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;packages&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;devenv-devcontainer-setup&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;v2.4.2&#34;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;components&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;grpc-interface-support&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">],</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><p>To do that you can run <code>velocitas component add grpc-interface-support</code> when your package is above or equal to v2.4.2</p> + diff --git a/docs/concepts/development_model/vehicle_app_manifest/interfaces/pubsub/index.html b/docs/concepts/development_model/vehicle_app_manifest/interfaces/pubsub/index.html index 3f8de4fc..54142879 100644 --- a/docs/concepts/development_model/vehicle_app_manifest/interfaces/pubsub/index.html +++ b/docs/concepts/development_model/vehicle_app_manifest/interfaces/pubsub/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -576,7 +598,7 @@

    Example

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/development_model/vehicle_app_manifest/interfaces/vehicle_signal_interface/index.html b/docs/concepts/development_model/vehicle_app_manifest/interfaces/vehicle_signal_interface/index.html index e366e888..cb1c6558 100644 --- a/docs/concepts/development_model/vehicle_app_manifest/interfaces/vehicle_signal_interface/index.html +++ b/docs/concepts/development_model/vehicle_app_manifest/interfaces/vehicle_signal_interface/index.html @@ -42,13 +42,13 @@ - + - - + + @@ -93,7 +93,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -422,6 +444,7 @@ @@ -563,6 +586,15 @@

    Configuration structure

    URI of the used COVESA Vehicle Signal Specification JSON export. URI may point to a local file or to a file provided by a server.  +unit_src +string +["abs_path_unit_file_1", "abs_path_unit_file_2", "uri_unit_file_3"] +An array of URI’s/absolute path’s of the used COVESA Vehicle Signal Specification unit file(s) in yaml format. URI may point to a local file or to a file provided by a server. If none is provided a default one will be used ( + +https://github.com/COVESA/vehicle_signal_specification/blob/v4.0/spec/units.yaml) +.  + + datapoints object Object containing both required and provided datapoints. @@ -633,11 +665,13 @@

    Example

    } } } - +

    Different VSS versions

    +

    The model generation is supported for VSS versions up to v4.0. There are some changes for some paths from v3.0 to v4.0. For example Vehicle.Cabin.Seat.Row1.Pos1.Position in v3.0 is Vehicle.Cabin.Seat.Row1.DriverSide.Position in v4.0. If you are using the mock provider you would need to take that into account when you sepcify your mock.py.

    +
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/development_model/vehicle_app_sdk/_print/index.html b/docs/concepts/development_model/vehicle_app_sdk/_print/index.html index 09074abb..35a614a9 100644 --- a/docs/concepts/development_model/vehicle_app_sdk/_print/index.html +++ b/docs/concepts/development_model/vehicle_app_sdk/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -179,7 +179,7 @@

    Vehicle Model Ontology

    The Vehicle Model is a tree-based model where every branch in the tree, including the root, is derived from the Model base class provided by the SDK.

    The Vehicle Model Ontology consists of the following classes:

    Model

    -

    A model contains services, data points and other models. It corresponds to branch entries in VSS, interfaces in DTDL or namespaces in VSC.

    +

    A model contains data points (leaves) and other models (branches).

    ModelCollection

    diff --git a/docs/concepts/development_model/vehicle_app_sdk/index.html b/docs/concepts/development_model/vehicle_app_sdk/index.html index a1875c61..bbf41265 100644 --- a/docs/concepts/development_model/vehicle_app_sdk/index.html +++ b/docs/concepts/development_model/vehicle_app_sdk/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -562,7 +584,7 @@

    Vehicle Model Ontology

    The Vehicle Model is a tree-based model where every branch in the tree, including the root, is derived from the Model base class provided by the SDK.

    The Vehicle Model Ontology consists of the following classes:

    Model

    -

    A model contains services, data points and other models. It corresponds to branch entries in VSS, interfaces in DTDL or namespaces in VSC.

    +

    A model contains data points (leaves) and other models (branches).

    ModelCollection

    @@ -1263,7 +1285,7 @@

    Further information

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/index.html b/docs/concepts/index.html index 384eb4bf..09278e04 100644 --- a/docs/concepts/index.html +++ b/docs/concepts/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -529,7 +551,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/index.xml b/docs/concepts/index.xml index 82d97958..2db0c91a 100644 --- a/docs/concepts/index.xml +++ b/docs/concepts/index.xml @@ -92,21 +92,14 @@ SDKs are available for Python and C++, currently. Further SDKs for Rust and C ar <a href="https://covesa.github.io/vehicle_signal_specification/" target="_blank" rel="noopener">VSS</a> ) provides a domain taxonomy for vehicle signals and defines the vehicle data semantically, which is exchanged between <em>Vehicle Apps</em> and the Databroker.</p> -<p>The Vehicle Service Catalog ( - -<a href="https://github.com/COVESA/vehicle_service_catalog#vehicle-service-catalog" target="_blank" rel="noopener">VSC</a> -) extends VSS with functional remote procedure call definitions and semantically defines the gRPC interfaces of Vehicle Services and <em>Vehicle Apps</em>.</p> -<p>As an alternative to VSS and VSC, vehicle data and services can be defined semantically in a general IoT modelling language like Digital Twin Definition Language ( - -<a href="https://github.com/Azure/opendigitaltwins-dtdl/blob/master/DTDL/v2/dtdlv2.md" target="_blank" rel="noopener">DTDL</a> -) or BAMM Aspect Meta Model - -<a href="https://github.com/OpenManufacturingPlatform/sds-bamm-aspect-meta-model" target="_blank" rel="noopener">BAMM</a> - as well.</p> <p>The Velocitas SDK is using <a href="https://covesa.github.io/vehicle_signal_specification/" target="_blank" rel="noopener">VSS</a> - as the semantic model for the Vehicle Model.</p> + as the semantic model for the Vehicle Model. +Vehicle Service models can be defined with + +<a href="vehicle_app_manifest/interfaces/grpc_interface/">Protobuf service definitions</a> +.</p> <h3 id="communication-protocols">Communication Protocols</h3> <p>Asynchronous communication between diff --git a/docs/concepts/lifecycle_management/_print/index.html b/docs/concepts/lifecycle_management/_print/index.html index a094aad8..2344a500 100644 --- a/docs/concepts/lifecycle_management/_print/index.html +++ b/docs/concepts/lifecycle_management/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -595,14 +595,12 @@

    Interaction mockup

    > 3. Which API dependencies does your project have? [x] gRPC service [ ] uProtocol service -[x] Vehicle Service Catalogue > 4. Add an API dependency (y/n)? y > 5. What type of dependency? [x] gRPC-IF -[ ] VSC-IF > 6. URI of the .proto file? https://some-url/if.proto @@ -617,7 +615,6 @@

    Interaction mockup

    --name MyApp \ --lang cpp \ --package grpc-service-support \ - --package vsc-support \ --require grpc-interface:https://some-url/if.proto > Project created! diff --git a/docs/concepts/lifecycle_management/index.html b/docs/concepts/lifecycle_management/index.html index 6a626e97..c8afaf72 100644 --- a/docs/concepts/lifecycle_management/index.html +++ b/docs/concepts/lifecycle_management/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -579,7 +601,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/lifecycle_management/packages/_print/index.html b/docs/concepts/lifecycle_management/packages/_print/index.html index fc5c90b8..6d4666bd 100644 --- a/docs/concepts/lifecycle_management/packages/_print/index.html +++ b/docs/concepts/lifecycle_management/packages/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/concepts/lifecycle_management/packages/development/index.html b/docs/concepts/lifecycle_management/packages/development/index.html index ffa6391c..1d30a2aa 100644 --- a/docs/concepts/lifecycle_management/packages/development/index.html +++ b/docs/concepts/lifecycle_management/packages/development/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -689,7 +711,7 @@

    Next steps

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/lifecycle_management/packages/index.html b/docs/concepts/lifecycle_management/packages/index.html index a8338d46..24a1b76e 100644 --- a/docs/concepts/lifecycle_management/packages/index.html +++ b/docs/concepts/lifecycle_management/packages/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -519,7 +541,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/lifecycle_management/packages/usage/index.html b/docs/concepts/lifecycle_management/packages/usage/index.html index 29b8ad10..86a3f463 100644 --- a/docs/concepts/lifecycle_management/packages/usage/index.html +++ b/docs/concepts/lifecycle_management/packages/usage/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -629,7 +651,7 @@

    Next steps

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/lifecycle_management/phases/_print/index.html b/docs/concepts/lifecycle_management/phases/_print/index.html index 849ad1ee..83820d5e 100644 --- a/docs/concepts/lifecycle_management/phases/_print/index.html +++ b/docs/concepts/lifecycle_management/phases/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -209,14 +209,12 @@

    Interaction mockup

    > 3. Which API dependencies does your project have? [x] gRPC service [ ] uProtocol service -[x] Vehicle Service Catalogue > 4. Add an API dependency (y/n)? y > 5. What type of dependency? [x] gRPC-IF -[ ] VSC-IF > 6. URI of the .proto file? https://some-url/if.proto @@ -231,7 +229,6 @@

    Interaction mockup

    --name MyApp \ --lang cpp \ --package grpc-service-support \ - --package vsc-support \ --require grpc-interface:https://some-url/if.proto > Project created! diff --git a/docs/concepts/lifecycle_management/phases/create/index.html b/docs/concepts/lifecycle_management/phases/create/index.html index fed98c7c..dc2ccebc 100644 --- a/docs/concepts/lifecycle_management/phases/create/index.html +++ b/docs/concepts/lifecycle_management/phases/create/index.html @@ -42,13 +42,13 @@ - + - - + + @@ -93,7 +93,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -542,14 +564,12 @@

    Interaction mockup

    > 3. Which API dependencies does your project have? [x] gRPC service [ ] uProtocol service -[x] Vehicle Service Catalogue > 4. Add an API dependency (y/n)? y > 5. What type of dependency? [x] gRPC-IF -[ ] VSC-IF > 6. URI of the .proto file? https://some-url/if.proto @@ -564,7 +584,6 @@

    Interaction mockup

    --name MyApp \ --lang cpp \ --package grpc-service-support \ - --package vsc-support \ --require grpc-interface:https://some-url/if.proto > Project created! @@ -572,7 +591,7 @@

    Interaction mockup

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/lifecycle_management/phases/index.html b/docs/concepts/lifecycle_management/phases/index.html index 3cbec7b7..75d87d29 100644 --- a/docs/concepts/lifecycle_management/phases/index.html +++ b/docs/concepts/lifecycle_management/phases/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -511,7 +533,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/lifecycle_management/phases/index.xml b/docs/concepts/lifecycle_management/phases/index.xml index 81efbc63..cce71b98 100644 --- a/docs/concepts/lifecycle_management/phases/index.xml +++ b/docs/concepts/lifecycle_management/phases/index.xml @@ -63,14 +63,12 @@ </span></span><span style="display:flex;"><span>&gt; 3. Which API dependencies does your project have? </span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">[</span>x<span style="color:#ce5c00;font-weight:bold">]</span> gRPC service </span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">[</span> <span style="color:#ce5c00;font-weight:bold">]</span> uProtocol service -</span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">[</span>x<span style="color:#ce5c00;font-weight:bold">]</span> Vehicle Service Catalogue </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>&gt; 4. Add an API dependency <span style="color:#ce5c00;font-weight:bold">(</span>y/n<span style="color:#ce5c00;font-weight:bold">)</span>? </span></span><span style="display:flex;"><span>y </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>&gt; 5. What <span style="color:#204a87">type</span> of dependency? </span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">[</span>x<span style="color:#ce5c00;font-weight:bold">]</span> gRPC-IF -</span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">[</span> <span style="color:#ce5c00;font-weight:bold">]</span> VSC-IF </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>&gt; 6. URI of the .proto file? </span></span><span style="display:flex;"><span>https://some-url/if.proto @@ -85,7 +83,6 @@ </span></span></span><span style="display:flex;"><span><span style="color:#4e9a06"></span> --name MyApp <span style="color:#4e9a06">\ </span></span></span><span style="display:flex;"><span><span style="color:#4e9a06"></span> --lang cpp <span style="color:#4e9a06">\ </span></span></span><span style="display:flex;"><span><span style="color:#4e9a06"></span> --package grpc-service-support <span style="color:#4e9a06">\ -</span></span></span><span style="display:flex;"><span><span style="color:#4e9a06"></span> --package vsc-support <span style="color:#4e9a06">\ </span></span></span><span style="display:flex;"><span><span style="color:#4e9a06"></span> --require grpc-interface:https://some-url/if.proto </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>&gt; Project created! diff --git a/docs/concepts/lifecycle_management/project_configuration/index.html b/docs/concepts/lifecycle_management/project_configuration/index.html index 3fa4f4bb..30e04871 100644 --- a/docs/concepts/lifecycle_management/project_configuration/index.html +++ b/docs/concepts/lifecycle_management/project_configuration/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -540,7 +562,7 @@

    Next steps

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/lifecycle_management/troubleshooting/index.html b/docs/concepts/lifecycle_management/troubleshooting/index.html index e6167a2d..32ac1270 100644 --- a/docs/concepts/lifecycle_management/troubleshooting/index.html +++ b/docs/concepts/lifecycle_management/troubleshooting/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -563,7 +585,7 @@

    GitHub rate limit exceeded

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/lifecycle_management/velocitas_cli/index.html b/docs/concepts/lifecycle_management/velocitas_cli/index.html index 09dde5b0..3342f8df 100644 --- a/docs/concepts/lifecycle_management/velocitas_cli/index.html +++ b/docs/concepts/lifecycle_management/velocitas_cli/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -695,7 +717,7 @@

    Next steps

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/concepts/logging/index.html b/docs/concepts/logging/index.html index 881e85b9..a67a2afc 100644 --- a/docs/concepts/logging/index.html +++ b/docs/concepts/logging/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -616,7 +638,7 @@

    References

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/contribution-guidelines/_print/index.html b/docs/contribution-guidelines/_print/index.html index eef1c36d..6396e4ac 100644 --- a/docs/contribution-guidelines/_print/index.html +++ b/docs/contribution-guidelines/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/contribution-guidelines/index.html b/docs/contribution-guidelines/index.html index d7a83ff0..1c11316a 100644 --- a/docs/contribution-guidelines/index.html +++ b/docs/contribution-guidelines/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -615,7 +637,7 @@

    Build

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/index.html b/docs/index.html index 3932863a..5893dce9 100644 --- a/docs/index.html +++ b/docs/index.html @@ -86,7 +86,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -112,7 +112,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -168,10 +168,17 @@ -
  • +
  • +
  • @@ -378,6 +385,21 @@ +
  • + +
  • + + + +
  • @@ -523,7 +545,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/index.xml b/docs/index.xml index 0681b096..23d23fcd 100644 --- a/docs/index.xml +++ b/docs/index.xml @@ -2211,13 +2211,13 @@ You can adapt the JSON to your needs (e.g., change the ports, add new tasks) or <h3 id="modify-existing-services">Modify existing services</h3> <p>For more advanced usage you can also try to modify existing services. Check out -<a href="https://github.com/eclipse/kuksa.val.services/tree/main/seat_service" target="_blank" rel="noopener">the seat service</a> +<a href="https://github.com/eclipse-kuksa/kuksa-incubation/tree/main/seat_service" target="_blank" rel="noopener">the seat service</a> for example, modify it and integrate it into your <em>Vehicle App</em> repository.</p> <h3 id="create-your-own-services">Create your own services</h3> <p>If you want to create your own service the -<a href="https://github.com/eclipse/kuksa.val.services/" target="_blank" rel="noopener">KUKSA.VAL Services repository</a> - contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to <em>KUKSA.VAL</em> listening to changes of a <em>target value</em> of some VSS data point and then do whatever you want. You can achieve this by using the <em>KUKSA.VAL</em> +<a href="https://github.com/eclipse-kuksa/kuksa-incubation" target="_blank" rel="noopener">KUKSA Incubation repository</a> + contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to <em>KUKSA</em> listening to changes of a <em>target value</em> of some VSS data point and then do whatever you want. You can achieve this by using the <em>KUKSA</em> <a href="https://github.com/eclipse-kuksa/kuksa-databroker/tree/main/proto/kuksa/val/v1" target="_blank" rel="noopener">gRPC API</a> with any programming language of your choice (learn more about @@ -2311,6 +2311,15 @@ The default behavior is predefined in <td>URI of the used COVESA Vehicle Signal Specification JSON export. URI may point to a local file or to a file provided by a server. </td> </tr> <tr> +<td><code>unit_src</code></td> +<td>string</td> +<td><code>[&quot;abs_path_unit_file_1&quot;, &quot;abs_path_unit_file_2&quot;, &quot;uri_unit_file_3&quot;]</code></td> +<td>An array of URI&rsquo;s/absolute path&rsquo;s of the used COVESA Vehicle Signal Specification unit file(s) in yaml format. URI may point to a local file or to a file provided by a server. If none is provided a default one will be used ( + +<a href="https://github.com/COVESA/vehicle_signal_specification/blob/v4.0/spec/units.yaml%29" target="_blank" rel="noopener">https://github.com/COVESA/vehicle_signal_specification/blob/v4.0/spec/units.yaml)</a> +. </td> +</tr> +<tr> <td><code>datapoints</code></td> <td>object</td> <td>Object containing both required and provided datapoints.</td> @@ -2381,7 +2390,9 @@ The default behavior is predefined in </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> </span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> -</span></span></code></pre></div> +</span></span></code></pre></div><h2 id="different-vss-versions">Different VSS versions</h2> +<p>The model generation is supported for VSS versions up to v4.0. There are some changes for some paths from v3.0 to v4.0. For example <code>Vehicle.Cabin.Seat.Row1.Pos1.Position</code> in v3.0 is <code>Vehicle.Cabin.Seat.Row1.DriverSide.Position</code> in v4.0. If you are using the mock provider you would need to take that into account when you sepcify your mock.py.</p> + @@ -2439,6 +2450,287 @@ The default behavior is predefined in + + Docs: GRPC Interface Style Guide + /velocitas-docs/docs/concepts/development_model/val/grpc_style_guide/ + Mon, 09 May 2022 14:24:56 +0530 + + /velocitas-docs/docs/concepts/development_model/val/grpc_style_guide/ + + + + <p>This provides a style guide for .proto files. By following these conventions, you&rsquo;ll make your protocol buffer message definitions and their corresponding classes consistent and easy to read. +Unless otherwise indicated, this style guide is based on the style guide from + +<a href="https://developers.google.com/protocol-buffers/docs/style" target="_blank" rel="noopener">google protocol-buffers style</a> + under Apache 2.0 License &amp; Creative Commons Attribution 4.0 License.</p> +<p>Note that protocol buffer style can evolve over time, so it is likely that you will see .proto files written in different conventions or styles. Please respect the existing style when you modify these files. Consistency is key. However, it is best to adopt the current best style when you are creating a new .proto file.</p> +<h3 id="standard-file-formatting">Standard file formatting</h3> +<ul> +<li>Keep the line length to 80 characters.</li> +<li>Use an indent of 2 spaces.</li> +<li>Prefer the use of double quotes for strings.</li> +</ul> +<h3 id="file-structure">File structure</h3> +<p>Files should be named lower_snake_case.proto</p> +<p>All files should be ordered in the following manner:</p> +<ul> +<li>License header</li> +<li>File overview</li> +<li>Syntax</li> +<li>Package</li> +<li>Imports (sorted)</li> +<li>File options</li> +<li>Everything else</li> +</ul> +<h3 id="directory-structure">Directory Structure</h3> +<p>Files should be stored in a directory structure that matches their package sub-names. All files +in a given directory should be in the same package. +Below is an example based on the + +<a href="https://github.com/eclipse-kuksa/kuksa-databroker/tree/main/proto/sdv/databroker/v1" target="_blank" rel="noopener">proto files</a> + in the kuksa.-databroker repository.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>| proto/ +</span></span><span style="display:flex;"><span>| └── sdv +</span></span><span style="display:flex;"><span>| └── databroker +</span></span><span style="display:flex;"><span>| └── v1 // package sdv.databroker.broker.v1 +</span></span><span style="display:flex;"><span>| ├── broker.proto // service Broker in sdv.databroker.broker.v1 +</span></span><span style="display:flex;"><span>| ├── collector.proto // service Collector in sdv.databroker.broker.v1 +</span></span><span style="display:flex;"><span>| └── types.proto // type definition and import of in sdv.databroker.broker.v1 +</span></span></code></pre></div><p>The proposed structure shown above is adapted from + +<a href="https://raw.githubusercontent.com/uber/prototool/dev/style/README.md" target="_blank" rel="noopener">Uber Protobuf Style Guide V2</a> + under MIT License.</p> +<h3 id="packages">Packages</h3> +<p>Package names should be in lowercase. Package names should have unique names based on the project name, and possibly based on the path of the file containing the protocol buffer type definitions.</p> +<h3 id="message-and-field-names">Message and field names</h3> +<p>Use PascalCase (CamelCase with an initial capital) for message names – for example, SongServerRequest. Use underscore_separated_names for field names (including oneof field and extension names) – for example, song_name.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>message SongServerRequest { +</span></span><span style="display:flex;"><span> optional string song_name = 1; +</span></span><span style="display:flex;"><span>} +</span></span></code></pre></div><p>Using this naming convention for field names gives you accessors like the following:</p> +<p>C++:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">const</span> <span style="color:#000">string</span><span style="color:#ce5c00;font-weight:bold">&amp;</span> <span style="color:#000">song_name</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#000;font-weight:bold">{</span> <span style="color:#000;font-weight:bold">...</span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">void</span> <span style="color:#000">set_song_name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">const</span> <span style="color:#000">string</span><span style="color:#ce5c00;font-weight:bold">&amp;</span> <span style="color:#000">x</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> <span style="color:#000;font-weight:bold">...</span> <span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><p>If your field name contains a number, the number should appear after the letter instead of after the underscore. For example, use song_name1 instead of song_name_1 +Repeated fields</p> +<p>Use pluralized names for repeated fields.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-proto" data-lang="proto"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">repeated</span> <span style="color:#204a87;font-weight:bold">string</span> <span style="color:#000">keys</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">;</span><span style="color:#a40000"> +</span></span></span><span style="display:flex;"><span><span style="color:#a40000"></span><span style="color:#ce5c00;font-weight:bold">...</span><span style="color:#a40000"> +</span></span></span><span style="display:flex;"><span><span style="color:#a40000"></span><span style="color:#204a87;font-weight:bold">repeated</span> <span style="color:#000">MyMessage</span> <span style="color:#000">accounts</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#0000cf;font-weight:bold">17</span><span style="color:#000;font-weight:bold">;</span><span style="color:#a40000"> +</span></span></span></code></pre></div><h3 id="enums">Enums</h3> +<p>Use PascalCase (with an initial capital) for enum type names and CAPITALS_WITH_UNDERSCORES for value names:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">enum</span> <span style="color:#000">FooBar</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">FOO_BAR_UNSPECIFIED</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">FOO_BAR_FIRST_VALUE</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">FOO_BAR_SECOND_VALUE</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#0000cf;font-weight:bold">2</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><p>Each enum value should end with a semicolon, not a comma. The zero value enum should have the suffix UNSPECIFIED.</p> +<h3 id="services">Services</h3> +<p>If your .proto defines an RPC service, you should use PascalCase (with an initial capital) for both the service name and any RPC method names:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-proto" data-lang="proto"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">service</span> <span style="color:#000">FooService</span> <span style="color:#000;font-weight:bold">{</span><span style="color:#a40000"> +</span></span></span><span style="display:flex;"><span><span style="color:#a40000"></span> <span style="color:#204a87;font-weight:bold">rpc</span> <span style="color:#000">GetSomething</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">GetSomethingRequest</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#204a87;font-weight:bold">returns</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">GetSomethingResponse</span><span style="color:#000;font-weight:bold">);</span><span style="color:#a40000"> +</span></span></span><span style="display:flex;"><span><span style="color:#a40000"></span> <span style="color:#204a87;font-weight:bold">rpc</span> <span style="color:#000">ListSomething</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">ListSomethingRequest</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#204a87;font-weight:bold">returns</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">ListSomethingResponse</span><span style="color:#000;font-weight:bold">);</span><span style="color:#a40000"> +</span></span></span><span style="display:flex;"><span><span style="color:#a40000"></span><span style="color:#000;font-weight:bold">}</span><span style="color:#a40000"> +</span></span></span></code></pre></div><h3 id="grpc-interface-versioning">GRPC Interface Versioning</h3> +<p>All API interfaces must provide a major version number, which is encoded at the end of the protobuf package. +If an API introduces a breaking change, such as removing or renaming a field, it must increment its API version number to ensure that existing user code does not suddenly break. +Note: The use of the term &ldquo;major version number&rdquo; above is taken from semantic versioning. However, unlike in traditional semantic versioning, APIs must not expose minor or patch version numbers. +For example, APIs use v1, not v1.0, v1.1, or v1.4.2. From a user&rsquo;s perspective, minor versions are updated in place, and users receive new functionality without migration.</p> +<p>A new major version of an API must not depend on a previous major version of the same API. An API may depend on other APIs, with an expectation that the caller understands the dependency and stability risk associated with those APIs. In this scenario, a stable API version must only depend on stable versions of other APIs.</p> +<p>Different versions of the same API should preferably be able to work at the same time within a single client application for a reasonable transition period. This time period allows the client to transition smoothly to the newer version. An older version must go through a reasonable, well-communicated deprecation period before being shut down.</p> +<p>For releases that have alpha or beta stability, APIs must append the stability level after the major version number in the protobuf package.</p> +<h4 id="release-based-versioning">Release-based versioning</h4> +<p>An individual release is an alpha or beta release that is expected to be available for a limited time period before its functionality is incorporated into the stable channel, after which the individual release will be shut down. +When using release-based versioning strategy, an API may have any number of individual releases at each stability level.</p> +<p>Alpha and beta releases must have their stability level appended to the version, followed by an incrementing release number. For example, v1beta1 or v1alpha5. APIs should document the chronological order of these versions in their documentation (such as comments). +Each alpha or beta release may be updated in place with backwards-compatible changes. For beta releases, backwards-incompatible updates should be made by incrementing the release number and publishing a new release with the change. For example, if the current version is v1beta1, then v1beta2 is released next.</p> +<p>Adapted from + +<a href="https://cloud.google.com/apis/design/versioning?hl=en#release-based_versioning" target="_blank" rel="noopener">google release-based_versioning</a> + under Apache 2.0 License &amp; Creative Commons Attribution 4.0 License</p> +<h3 id="backwards-compatibility">Backwards compatibility</h3> +<p>The gRPC protocol is designed to support services that change over time. Generally, additions to gRPC services and methods are non-breaking. Non-breaking changes allow existing clients to continue working without changes. Changing or deleting gRPC services are breaking changes. When gRPC services have breaking changes, clients using that service have to be updated and redeployed.</p> +<p>Making non-breaking changes to a service has a number of benefits:</p> +<ul> +<li>Existing clients continue to run.</li> +<li>Avoids work involved with notifying clients of breaking changes, and updating them.</li> +<li>Only one version of the service needs to be documented and maintained.</li> +</ul> +<h3 id="non-breaking-changes">Non-breaking changes</h3> +<p>These changes are non-breaking at a gRPC protocol level and binary level.</p> +<ul> +<li>Adding a new service</li> +<li>Adding a new method to a service</li> +<li>Adding a field to a request message - Fields added to a request message are deserialized with the default value on the server when not set. To be a non-breaking change, the service must succeed when the new field isn&rsquo;t set by older clients.</li> +<li>Adding a field to a response message - Fields added to a response message are deserialized into the message&rsquo;s unknown fields collection on the client.</li> +<li>Adding a value to an enum - Enums are serialized as a numeric value. New enum values are deserialized on the client to the enum value without an enum name. To be a non-breaking change, older clients must run correctly when receiving the new enum value.</li> +</ul> +<h3 id="binary-breaking-changes">Binary breaking changes</h3> +<p>The following changes are non-breaking at a gRPC protocol level, but the client needs to be updated if it upgrades to the latest .proto contract. Binary compatibility is important if you plan to publish a gRPC library.</p> +<ul> +<li>Removing a field - Values from a removed field are deserialized to a message&rsquo;s unknown fields. This isn&rsquo;t a gRPC protocol breaking change, but the client needs to be updated if it upgrades to the latest contract. It&rsquo;s important that a removed field number isn&rsquo;t accidentally reused in the future. To ensure this doesn&rsquo;t happen, specify deleted field numbers and names on the message using Protobuf&rsquo;s reserved keyword.</li> +<li>Renaming a message - Message names aren&rsquo;t typically sent on the network, so this isn&rsquo;t a gRPC protocol breaking change. The client will need to be updated if it upgrades to the latest contract. One situation where message names are sent on the network is with Any fields, when the message name is used to identify the message type.</li> +<li>Nesting or unnesting a message - Message types can be nested. Nesting or unnesting a message changes its message name. Changing how a message type is nested has the same impact on compatibility as renaming.</li> +</ul> +<h3 id="protocol-breaking-changes">Protocol breaking changes</h3> +<p>The following items are protocol and binary breaking changes:</p> +<ul> +<li>Renaming a field - With Protobuf content, the field names are only used in generated code. The field number is used to identify fields on the network. Renaming a field isn&rsquo;t a protocol breaking change for Protobuf. However, if a server is using JSON content, then renaming a field is a breaking change.</li> +<li>Changing a field data type - Changing a field&rsquo;s data type to an incompatible type will cause errors when deserializing the message. Even if the new data type is compatible, it&rsquo;s likely the client needs to be updated to support the new type if it upgrades to the latest contract.</li> +<li>Changing a field number - With Protobuf payloads, the field number is used to identify fields on the network.</li> +<li>Renaming a package, service or method - gRPC uses the package name, service name, and method name to build the URL. The client gets an UNIMPLEMENTED status from the server.</li> +<li>Removing a service or method - The client gets an UNIMPLEMENTED status from the server when calling the removed method.</li> +</ul> +<h3 id="behavior-breaking-changes">Behavior breaking changes</h3> +<p>When making non-breaking changes, you must also consider whether older clients can continue working with the new service behavior. For example, adding a new field to a request message:</p> +<ul> +<li>Isn&rsquo;t a protocol breaking change.</li> +<li>Returning an error status on the server if the new field isn&rsquo;t set makes it a breaking change for old clients.</li> +</ul> +<p>Behavior compatibility is determined by your app-specific code.</p> +<p>Adapted from + +<a href="https://docs.microsoft.com/en-us/aspnet/core/grpc/versioning?view=aspnetcore-6.0" target="_blank" rel="noopener">Versioning gRPC services</a> + under Creative Commons Attribution 4.0 License</p> +<h2 id="grpc-error-handling">gRPC Error Handling</h2> +<p>In gRPC, a large set of error codes has been + +<a href="https://grpc.github.io/grpc/cpp/md_doc_statuscodes.html" target="_blank" rel="noopener">defined</a> + +As a general rule, SDV should use relevant gRPC error codes, +as described in + +<a href="https://stackoverflow.com/questions/59094839/whats-the-correct-way-to-return-a-not-found-response-from-a-grpc-c-server-i" target="_blank" rel="noopener">this thread</a> +</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">StatusCode</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">NOT_FOUND</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;error details here&#34;</span><span style="color:#000;font-weight:bold">);</span> +</span></span></code></pre></div><p>Available constructor:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span> <span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span> <span style="color:#000;font-weight:bold">(</span> <span style="color:#000">StatusCode</span> <span style="color:#000">code</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">const</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">string</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span> <span style="color:#000">error_message</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">const</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">string</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span> <span style="color:#000">error_details</span> +</span></span></code></pre></div><p>The framework for drafting error messages could be useful as a later improvement. This could e.g., be used to specify which unit created the error message and to assure the same structure on all messages. The latter two may e.g., depend on debug settings, e.g., error details only in debug-builds to avoid leaks of sensitive information. A global function like below or similar could handle that and also possibly convert between internal error codes and gRPC codes.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span> <span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span> <span style="color:#000">status</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">CreateStatusMessage</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">PERMISSION_DENIED</span><span style="color:#000;font-weight:bold">,</span><span style="color:#4e9a06">&#34;DataBroker&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#4e9a06">&#34;Rule access rights violated&#34;</span><span style="color:#000;font-weight:bold">);</span> +</span></span></code></pre></div><h3 id="sdv-error-handling-for-grpc-interfaces-eg-val-vehicles-services">SDV error handling for gRPC interfaces (e.g., VAL vehicles services)</h3> +<ul> +<li>Use gRPC error codes as base</li> +<li>Document in proto files (as comments) which error codes that the service implementation can emit and the meaning of them. (Errors that only are emitted by the gRPC framework do not need to be listed.)</li> +<li>Do not - unless there are special reasons - add explicit error/status fields to rpc return messages.</li> +<li>Additional error information can be given by free text fields in gRPC error codes. Note, however, that sensitive information like <code>Given password ABCD does not match expected password EFGH</code> should not be passed in an unprotected/unencrypted manner.</li> +</ul> +<h3 id="sdv-handling-of-grpc-error-codes">SDV handling of gRPC error codes</h3> +<p>The table below gives error code guidelines for each gRPC on:</p> +<ul> +<li>If it is relevant for a client to retry the call or not when receiving the error code. Retry is only relevant if the error is of a temporary nature.</li> +<li>When to use the error code when implementing a service.</li> +</ul> +<table border="1"> + <tbody> + <tr> + <th>gRPC error code</th> + <th>Retry Relevant?</th> + <th>Recommended SDV usage</th> + </tr> + <tr> + <td>OK</td> + <td>No</td> + <td>Mandatory error code if operation succeeded. Shall never be used if operation failed.</td> + </tr> + <tr> + <td>CANCELLED</td> + <td>No</td> + <td>No explicit use case on server side in SDV identified</td> + </tr> + <tr> + <td>UNKNOWN</td> + <td>No</td> + <td>To be used in default-statements when converting errors from e.g., Broker-errors to SDV/gRPC errors</td> + </tr> + <tr> + <td>INVALID_ARGUMENT</td> + <td>No</td> + <td>E.g., Rule syntax with errors</td> + </tr> + <tr> + <td>DEADLINE_EXCEEDED</td> + <td>Yes</td> + <td>Only applicable for asynchronous services, i.e. services which wait for completion before the result is returned. The behavior if an operation cannot finish within expected time must be defined. Two options exist. One is to return this error after e.g., X seconds. Another is that the server never gives up, but rather waits for the client to cancel the operation.</td> + </tr> + <tr> + <td>NOT_FOUND</td> + <td>No</td> + <td>Long term situation that likely not will change in the near future. <br/> Example: SDV can not find the specified resource (e.g., no path to get data for specified seat) </td> + </tr> + <tr> + <td>ALREADY_EXISTS</td> + <td>No</td> + <td>No explicit use case on server side in SDV identified</td> + </tr> + <tr> + <td>PERMISSION_DENIED</td> + <td>No</td> + <td>Operation rejected due to permission denied</td> + </tr> + <tr> + <td>RESOURCE_EXHAUSTED</td> + <td>Yes</td> + <td>Possibly if e.g., malloc fails or similar errors.</td> + </tr> + <tr> + <td>FAILED_PRECONDITION</td> + <td>Yes</td> + <td>Could be returned if e.g., operation is rejected due to safety reasons. (E.g., vehicle moving)</td> + </tr> + <tr> + <td>ABORTED</td> + <td>Yes</td> + <td>Could e.g., be returned if service does not support concurrent requests, and there is already either a related operation ongoing or the operation is aborted due to a newer request received. Could also be used if an operation is aborted on user/driver request, e.g., physical button in vehicle pressed.</td> + </tr> + <tr> + <td>OUT_OF_RANGE</td> + <td>No</td> + <td>E.g., Arguments out of range</td> + </tr> + <tr> + <td>UNIMPLEMENTED</td> + <td>No</td> + <td>To be used if certain use-cases of the service are not implemented, e.g., if recline cannot be adjusted</td> + </tr> + <tr> + <td>INTERNAL</td> + <td>No</td> + <td>Internal errors, like exceptions, unexpected null pointers and similar</td> + </tr> + <tr> + <td>UNAVAILABLE</td> + <td>Yes</td> + <td>To be used if the service is temporarily unavailable, e.g., during system startup.</td> + </tr> + <tr> + <td>DATA_LOSS</td> + <td>No</td> + <td>No explicit use case identified on server side in SDV.</td> + </tr> + <tr> + <td>UNAUTHENTICATED</td> + <td>No</td> + <td>No explicit use case identified on server side in SDV.</td> + </tr> +</table> +<h3 id="other-references">Other references</h3> +<ul> +<li> + +<a href="https://stackoverflow.com/questions/48748745/pattern-for-rich-error-handling-in-grpc" target="_blank" rel="noopener">Pattern for rich error handling in gRPC</a> +</li> +<li> + +<a href="https://jbrandhorst.com/post/grpc-errors/" target="_blank" rel="noopener">Advanced gRPC Error Usage</a> +</li> +</ul> + + + + Docs: C++ Manual Vehicle Model Creation /velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_cpp/ @@ -2535,7 +2827,11 @@ The default behavior is predefined in </table> -<h2 id="example">Example</h2> +<h2 id="execution">Execution</h2> +<p><code>velocitas init</code> +<strong>or</strong> +<code>velocitas exec grpc-interface-support generate-sdk</code></p> +<h2 id="project-configuration">Project configuration</h2> <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span> </span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;type&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;grpc-interface&#34;</span><span style="color:#000;font-weight:bold">,</span> </span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;config&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> @@ -2544,10 +2840,23 @@ The default behavior is predefined in </span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;methods&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span> </span></span><span style="display:flex;"><span> <span style="color:#4e9a06">&#34;Move&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;MoveComponent&#34;</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">]</span> -</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;provided&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> <span style="color:#000;font-weight:bold">}</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> </span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> -</span></span></code></pre></div> +</span></span></code></pre></div><p>You need to specify <code>devenv-devcontainer-setup</code> &gt;= <code>v2.4.2</code> in your project configuration. Therefore your <code>.veloitas.json</code> should look similair to this example:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;packages&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;devenv-devcontainer-setup&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;v2.4.2&#34;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;components&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;grpc-interface-support&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">],</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><p>To do that you can run <code>velocitas component add grpc-interface-support</code> when your package is above or equal to v2.4.2</p> + @@ -2681,14 +2990,12 @@ The default behavior is predefined in </span></span><span style="display:flex;"><span>&gt; 3. Which API dependencies does your project have? </span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">[</span>x<span style="color:#ce5c00;font-weight:bold">]</span> gRPC service </span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">[</span> <span style="color:#ce5c00;font-weight:bold">]</span> uProtocol service -</span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">[</span>x<span style="color:#ce5c00;font-weight:bold">]</span> Vehicle Service Catalogue </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>&gt; 4. Add an API dependency <span style="color:#ce5c00;font-weight:bold">(</span>y/n<span style="color:#ce5c00;font-weight:bold">)</span>? </span></span><span style="display:flex;"><span>y </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>&gt; 5. What <span style="color:#204a87">type</span> of dependency? </span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">[</span>x<span style="color:#ce5c00;font-weight:bold">]</span> gRPC-IF -</span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">[</span> <span style="color:#ce5c00;font-weight:bold">]</span> VSC-IF </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>&gt; 6. URI of the .proto file? </span></span><span style="display:flex;"><span>https://some-url/if.proto @@ -2703,7 +3010,6 @@ The default behavior is predefined in </span></span></span><span style="display:flex;"><span><span style="color:#4e9a06"></span> --name MyApp <span style="color:#4e9a06">\ </span></span></span><span style="display:flex;"><span><span style="color:#4e9a06"></span> --lang cpp <span style="color:#4e9a06">\ </span></span></span><span style="display:flex;"><span><span style="color:#4e9a06"></span> --package grpc-service-support <span style="color:#4e9a06">\ -</span></span></span><span style="display:flex;"><span><span style="color:#4e9a06"></span> --package vsc-support <span style="color:#4e9a06">\ </span></span></span><span style="display:flex;"><span><span style="color:#4e9a06"></span> --require grpc-interface:https://some-url/if.proto </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>&gt; Project created! @@ -2990,6 +3296,220 @@ More detailed information about the <em>Project Cache</em> can be fo + + Docs: Create a client + /velocitas-docs/docs/tutorials/grpc_service_generation/create_client/ + Fri, 07 Jun 2024 14:02:00 +0530 + + /velocitas-docs/docs/tutorials/grpc_service_generation/create_client/ + + + + <h2 id="app-configuration">App configuration</h2> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;type&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;grpc-interface&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;config&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;src&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// &#34;required&#34; indicates you are trying to write a client for the service +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#204a87;font-weight:bold">&#34;required&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;methods&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span> +</span></span><span style="display:flex;"><span> <span style="color:#4e9a06">&#34;Move&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;CurrentPosition&#34;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">]</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><h2 id="project-configuration">Project configuration</h2> +<p>You need to specify <code>devenv-devcontainer-setup</code> &gt;= <code>v2.4.2</code> in your project configuration. Therefore your <code>.veloitas.json</code> should look similair to this example:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;packages&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;devenv-devcontainer-setup&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;v2.4.2&#34;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;components&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;grpc-interface-support&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">],</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><p>To do that you can run <code>velocitas component add grpc-interface-support</code> when your package is above or equal to v2.4.2</p> +<h2 id="example-code">Example code</h2> +<p>To create a client we use the generated <code>SeatsServiceClientFactory.h</code> and <code>seats.grpc.pb.h</code>. These define request and response types and the operations that are available. An example implementation for the SeatService follows:</p> +<h3 id="maincpp">main.cpp</h3> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;sdk/middleware/Middleware.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;services/seats/SeatsServiceClientFactory.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;services/seats/seats.grpc.pb.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> +</span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;iostream&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> +</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">using</span> <span style="color:#204a87;font-weight:bold">namespace</span> <span style="color:#000">velocitas</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">int</span> <span style="color:#000">main</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">int</span> <span style="color:#000">argc</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">char</span><span style="color:#ce5c00;font-weight:bold">**</span> <span style="color:#000">argv</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">serviceClient</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">SeatsServiceClientFactory</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">create</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">Middleware</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">getInstance</span><span style="color:#000;font-weight:bold">());</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">ClientContext</span> <span style="color:#000">context</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveRequest</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveReply</span> <span style="color:#000">response</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Seat</span> <span style="color:#000">seat</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">SeatLocation</span> <span style="color:#000">seat_location</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">seat_location</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_row</span><span style="color:#000;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">seat_location</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_index</span><span style="color:#000;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Position</span> <span style="color:#000">seat_position</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// we only set base here to keep the example simple +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#8f5902;font-style:italic">// extend here if yu want to set lumbar etc. +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#000">seat_position</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_base</span><span style="color:#000;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1000</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#000">seat</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_allocated_location</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">seat_location</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">seat</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_allocated_position</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">seat_position</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_allocated_seat</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">seat</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">status</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">serviceClient</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">Move</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">context</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">response</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">cout</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#4e9a06">&#34;gRPC Server returned code: &#34;</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">status</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">error_code</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">endl</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">cout</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#4e9a06">&#34;gRPC error message: &#34;</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">status</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">error_message</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">c_str</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">endl</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">status</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">error_code</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#ce5c00;font-weight:bold">==</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">StatusCode</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">UNIMPLEMENTED</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> <span style="color:#204a87;font-weight:bold">else</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">ClientContext</span> <span style="color:#000">context</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">CurrentPositionRequest</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">CurrentPositionReply</span> <span style="color:#000">response</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_row</span><span style="color:#000;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_index</span><span style="color:#000;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">status_curr_pos</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">seatService</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">CurrentPosition</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">context</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">response</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">cout</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#4e9a06">&#34;current Position:&#34;</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">response</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">seat</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">position</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">base</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">endl</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">cout</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#4e9a06">&#34;gRPC Server returned code: &#34;</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">status_curr_pos</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">error_code</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">endl</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">cout</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#4e9a06">&#34;gRPC error message: &#34;</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">status_curr_pos</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">error_message</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">c_str</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">endl</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div> + + + + + Docs: Create a server + /velocitas-docs/docs/tutorials/grpc_service_generation/create_server/ + Fri, 07 Jun 2024 14:02:00 +0530 + + /velocitas-docs/docs/tutorials/grpc_service_generation/create_server/ + + + + <h2 id="app-configuration">App configuration</h2> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;type&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;grpc-interface&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;config&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;src&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// &#34;provided&#34; indicates you want to implement the server business logic for the service +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#204a87;font-weight:bold">&#34;provided&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><h2 id="project-configuration">Project configuration</h2> +<p>You need to specify <code>devenv-devcontainer-setup</code> &gt;= <code>v2.4.2</code> in your project configuration. Therefore your <code>.veloitas.json</code> should look similair to this example:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;packages&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;devenv-devcontainer-setup&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;v2.4.2&#34;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;components&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;grpc-interface-support&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">],</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><p>To do that you can run <code>velocitas component add grpc-interface-support</code> when your package is above or equal to v2.4.2</p> +<p>To create a server that is providing the gRPC service we are leveraging the generated <code>SeatsServiceImpl.h</code> and <code>SeatsServiceServerFactory.h</code>. The <code>SeatsServiceImpl.cpp</code> needs to be filled with the actual implementation of the service. A quick example for a SeatService is described in the following:</p> +<h3 id="maincpp">main.cpp</h3> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;sdk/middleware/Middleware.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;services/seats/SeatsServiceServerFactory.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&#34;SeatsServiceImpl.h&#34;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> +</span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;memory&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> +</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">using</span> <span style="color:#204a87;font-weight:bold">namespace</span> <span style="color:#000">velocitas</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">int</span> <span style="color:#000">main</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">int</span> <span style="color:#000">argc</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">char</span><span style="color:#ce5c00;font-weight:bold">**</span> <span style="color:#000">argv</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">seatsImpl</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">make_shared</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">SeatsService</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#000">velocitas</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">VehicleModelContext</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">getInstance</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">setVdbc</span><span style="color:#000;font-weight:bold">(</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">velocitas</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">IVehicleDataBrokerClient</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">createInstance</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;vehicledatabroker&#34;</span><span style="color:#000;font-weight:bold">));</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">seatServer</span> <span style="color:#ce5c00;font-weight:bold">=</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">SeatsServiceServerFactory</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">create</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">Middleware</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">getInstance</span><span style="color:#000;font-weight:bold">(),</span> <span style="color:#000">seatsImpl</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#000">seatServer</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">Wait</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><h3 id="seatsserviceimplcpp">SeatsServiceImpl.cpp</h3> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&#34;SeatsServiceImpl.h&#34;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;sdk/VehicleApp.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;sdk/VehicleModelContext.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;sdk/vdb/IVehicleDataBrokerClient.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;vehicle/Vehicle.hpp&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;grpc/grpc.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;services/seats/seats.grpc.pb.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> +</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">namespace</span> <span style="color:#000">velocitas</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span> <span style="color:#000">SeatsService</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Move</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">ServerContext</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">context</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">const</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveRequest</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveReply</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">response</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">context</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">response</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">vehicle</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Vehicle</span> <span style="color:#000">Vehicle</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">seat</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">request</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">seat</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">location</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">seat</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">location</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">row</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">location</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">row</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">pos</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">location</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">index</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// you would need to extend this to add support for lumbar etc. +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#8f5902;font-style:italic">// Vehicle.Cabin.Seat.Row(row).Pos(pos).Position.set(seat-&gt;position()-&gt;xxxxxx())-&gt;await(); +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">status</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">Vehicle</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Cabin</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Seat</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Row1</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">DriverSide</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Position</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">seat</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">position</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">base</span><span style="color:#000;font-weight:bold">())</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">await</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">status</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">ok</span><span style="color:#000;font-weight:bold">())</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">StatusCode</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">OK</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;&#34;</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> <span style="color:#204a87;font-weight:bold">else</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">StatusCode</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">CANCELLED</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">status</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">errorMessage</span><span style="color:#000;font-weight:bold">());</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span> +</span></span><span style="display:flex;"><span><span style="color:#000">SeatsService</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveComponent</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">ServerContext</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">context</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">const</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveComponentRequest</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveComponentReply</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">response</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">context</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">request</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">response</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">StatusCode</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">UNIMPLEMENTED</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;&#34;</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span> <span style="color:#000">SeatsService</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">CurrentPosition</span><span style="color:#000;font-weight:bold">(</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">ServerContext</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">context</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">const</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">CurrentPositionRequest</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">CurrentPositionReply</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">response</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">context</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">request</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">vehicle</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Vehicle</span> <span style="color:#000">Vehicle</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">seat</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">response</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">mutable_seat</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">seat_position</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">seat</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">mutable_position</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">seatPos</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">Vehicle</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Cabin</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Seat</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Row1</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">DriverSide</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Position</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">get</span><span style="color:#000;font-weight:bold">()</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">await</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">value</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// we only set base here to keep the example simple +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#8f5902;font-style:italic">// extend here if yu want to set lumbar etc. +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#000">seat_position</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">set_base</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">seatPos</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">StatusCode</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">OK</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;&#34;</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> <span style="color:#8f5902;font-style:italic">// namespace velocitas +</span></span></span></code></pre></div> + + + Docs: Vehicle App Integration Testing /velocitas-docs/docs/tutorials/vehicle_app_development/integration_tests/ @@ -3292,7 +3812,7 @@ Successfully installed my-vehicle-model-0.1 <p>As example you could use the protocol buffers message definition <a href="https://github.com/eclipse-kuksa/kuksa-incubation/blob/main/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto" target="_blank" rel="noopener">seats.proto</a> - provided by the KUKSA.VAL services which describes a + provided by the KUKSA services which describes a <a href="https://github.com/eclipse-kuksa/kuksa-incubation/tree/main/seat_service" target="_blank" rel="noopener">seat control service</a> .</p> diff --git a/docs/tutorials/_print/index.html b/docs/tutorials/_print/index.html index 104b250d..583fbfdd 100644 --- a/docs/tutorials/_print/index.html +++ b/docs/tutorials/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -409,7 +409,42 @@

    Tutorials

    -
  • 6: Vehicle App Deployment
  • +
  • 6: gRPC service generation
  • + + + + + + + + + +
  • 7: Vehicle App Deployment
  • @@ -1495,13 +1530,13 @@

    2.2 - Service Integration

    Modify existing services

    For more advanced usage you can also try to modify existing services. Check out -the seat service +the seat service for example, modify it and integrate it into your Vehicle App repository.

    Create your own services

    If you want to create your own service the -KUKSA.VAL Services repository - contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to KUKSA.VAL listening to changes of a target value of some VSS data point and then do whatever you want. You can achieve this by using the KUKSA.VAL +KUKSA Incubation repository + contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to KUKSA listening to changes of a target value of some VSS data point and then do whatever you want. You can achieve this by using the KUKSA gRPC API with any programming language of your choice (learn more about @@ -3077,7 +3112,7 @@

    Add a Vehicle Service

    As example you could use the protocol buffers message definition seats.proto - provided by the KUKSA.VAL services which describes a + provided by the KUKSA services which describes a seat control service .

    @@ -3511,7 +3546,271 @@

    Next steps

    -

    6 - Vehicle App Deployment

    +

    6 - gRPC service generation

    +
    Learn how to generate and fill your own gRPC services.
    +

    This tutorial shows how to generate a basic gRPC service like a seat service. For this example the proto file under + +https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto + is taken.

    +

    All files included from services/seats are auto-generated and added to the app project as Conan dependency. +For writing a complete gRPC service you need two velocitas apps/projects. +One is implementing a client and the other one is for providing the server. +To complete the server implementation you have to fill the generated *ServiceImpl.cpp. +Have a look at the linked content beneath for a tutorial how it would be done for a SeatService leveraging + +https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto +.

    +

    To run the example you need to start the velocitas app for the server first and then the second velocitas app for the client.

    + +
    + + + + + + + + + + + + + + + + + + + +
    + +

    6.1 - Create a client

    +
    Learn how to create a client for a service definition.
    +

    App configuration

    +
    {
    +  "type": "grpc-interface",
    +  "config": {
    +      "src": "https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto",
    +      // "required" indicates you are trying to write a client for the service
    +      "required": {
    +        "methods": [
    +          "Move", "CurrentPosition"
    +        ]
    +      },
    +  }
    +}
    +

    Project configuration

    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    +

    Example code

    +

    To create a client we use the generated SeatsServiceClientFactory.h and seats.grpc.pb.h. These define request and response types and the operations that are available. An example implementation for the SeatService follows:

    +

    main.cpp

    +
    #include <sdk/middleware/Middleware.h>
    +#include <services/seats/SeatsServiceClientFactory.h>
    +#include <services/seats/seats.grpc.pb.h>
    +
    +#include <iostream>
    +
    +using namespace velocitas;
    +
    +int main(int argc, char** argv) {
    +    auto serviceClient = SeatsServiceClientFactory::create(Middleware::getInstance());
    +
    +    ::grpc::ClientContext                        context;
    +    ::sdv::edge::comfort::seats::v1::MoveRequest request;
    +    ::sdv::edge::comfort::seats::v1::MoveReply   response;
    +
    +    ::sdv::edge::comfort::seats::v1::Seat seat;
    +
    +    ::sdv::edge::comfort::seats::v1::SeatLocation seat_location;
    +    seat_location.set_row(1);
    +    seat_location.set_index(1);
    +
    +    ::sdv::edge::comfort::seats::v1::Position seat_position;
    +    // we only set base here to keep the example simple
    +    // extend here if yu want to set lumbar etc.
    +    seat_position.set_base(1000);
    +
    +    seat.set_allocated_location(&seat_location);
    +    seat.set_allocated_position(&seat_position);
    +
    +    request.set_allocated_seat(&seat);
    +
    +    auto status = serviceClient->Move(&context, request, &response);
    +
    +    std::cout << "gRPC Server returned code: " << status.error_code() << std::endl;
    +    std::cout << "gRPC error message: " << status.error_message().c_str() << std::endl;
    +
    +    if (status.error_code() == ::grpc::StatusCode::UNIMPLEMENTED) {
    +        return 1;
    +    } else {
    +        ::grpc::ClientContext                                   context;
    +        ::sdv::edge::comfort::seats::v1::CurrentPositionRequest request;
    +        ::sdv::edge::comfort::seats::v1::CurrentPositionReply   response;
    +
    +        request.set_row(1);
    +        request.set_index(1);
    +
    +        auto status_curr_pos = seatService->CurrentPosition(&context, request, &response);
    +        std::cout << "current Position:" << response.seat().position().base() << std::endl;
    +        std::cout << "gRPC Server returned code: " << status_curr_pos.error_code() << std::endl;
    +        std::cout << "gRPC error message: " << status_curr_pos.error_message().c_str() << std::endl;
    +        return 0;
    +    }
    +}
    +
    +
    + + + + + + + + + + + +
    + +

    6.2 - Create a server

    +
    Learn how to create a server for a service definition.
    +

    App configuration

    +
    {
    +  "type": "grpc-interface",
    +  "config": {
    +      "src": "https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto",
    +      // "provided" indicates you want to implement the server business logic for the service
    +      "provided": { }
    +  }
    +}
    +

    Project configuration

    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    +

    To create a server that is providing the gRPC service we are leveraging the generated SeatsServiceImpl.h and SeatsServiceServerFactory.h. The SeatsServiceImpl.cpp needs to be filled with the actual implementation of the service. A quick example for a SeatService is described in the following:

    +

    main.cpp

    +
    #include <sdk/middleware/Middleware.h>
    +#include <services/seats/SeatsServiceServerFactory.h>
    +#include "SeatsServiceImpl.h"
    +
    +#include <memory>
    +
    +using namespace velocitas;
    +
    +int main(int argc, char** argv) {
    +    auto seatsImpl = std::make_shared<SeatsService>();
    +
    +    velocitas::VehicleModelContext::getInstance().setVdbc(
    +        velocitas::IVehicleDataBrokerClient::createInstance("vehicledatabroker"));
    +    auto seatServer =
    +        SeatsServiceServerFactory::create(Middleware::getInstance(), seatsImpl);
    +
    +    seatServer->Wait();
    +    return 0;
    +}
    +

    SeatsServiceImpl.cpp

    +
    #include "SeatsServiceImpl.h"
    +#include <sdk/VehicleApp.h>
    +#include <sdk/VehicleModelContext.h>
    +#include <sdk/vdb/IVehicleDataBrokerClient.h>
    +#include <vehicle/Vehicle.hpp>
    +#include <grpc/grpc.h>
    +#include <services/seats/seats.grpc.pb.h>
    +
    +namespace velocitas {
    +
    +::grpc::Status SeatsService::Move(::grpc::ServerContext*                              context,
    +                                  const ::sdv::edge::comfort::seats::v1::MoveRequest* request,
    +                                  ::sdv::edge::comfort::seats::v1::MoveReply*         response) {
    +    (void)context;
    +    (void)response;
    +    vehicle::Vehicle Vehicle;
    +
    +    auto seat     = request->seat();
    +    auto location = seat.location();
    +    auto row      = location.row();
    +    auto pos      = location.index();
    +
    +    // you would need to extend this to add support for lumbar etc.
    +    // Vehicle.Cabin.Seat.Row(row).Pos(pos).Position.set(seat->position()->xxxxxx())->await();
    +    auto status = Vehicle.Cabin.Seat.Row1.DriverSide.Position.set(seat.position().base())->await();
    +    if (status.ok()) {
    +        return ::grpc::Status(::grpc::StatusCode::OK, "");
    +    } else {
    +        return ::grpc::Status(::grpc::StatusCode::CANCELLED, status.errorMessage());
    +    }
    +}
    +
    +::grpc::Status
    +SeatsService::MoveComponent(::grpc::ServerContext*                                       context,
    +                            const ::sdv::edge::comfort::seats::v1::MoveComponentRequest* request,
    +                            ::sdv::edge::comfort::seats::v1::MoveComponentReply*         response) {
    +    (void)context;
    +    (void)request;
    +    (void)response;
    +    return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    +}
    +
    +::grpc::Status SeatsService::CurrentPosition(
    +    ::grpc::ServerContext*                                         context,
    +    const ::sdv::edge::comfort::seats::v1::CurrentPositionRequest* request,
    +    ::sdv::edge::comfort::seats::v1::CurrentPositionReply*         response) {
    +    (void)context;
    +    (void)request;
    +    vehicle::Vehicle Vehicle;
    +
    +    auto             seat          = response->mutable_seat();
    +    auto             seat_position = seat->mutable_position();
    +
    +    auto seatPos = Vehicle.Cabin.Seat.Row1.DriverSide.Position.get()->await().value();
    +
    +    // we only set base here to keep the example simple
    +    // extend here if yu want to set lumbar etc.
    +    seat_position->set_base(seatPos);
    +    return ::grpc::Status(::grpc::StatusCode::OK, "");
    +}
    +
    +} // namespace velocitas
    +
    +
    + + + + + + + + + + + + + + + +
    + +

    7 - Vehicle App Deployment

    Learn how to deploy the Vehicle App to currently supported infrastructure targets.

    See the diff --git a/docs/tutorials/grpc_service_generation/_print/index.html b/docs/tutorials/grpc_service_generation/_print/index.html new file mode 100644 index 00000000..9e644838 --- /dev/null +++ b/docs/tutorials/grpc_service_generation/_print/index.html @@ -0,0 +1,562 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +gRPC service generation | Velocitas + + + + + + + + + + + + + + + + + + + + + +

    + +
    +
    +
    +
    +
    + + + + + +
    +
    +

    +This is the multi-page printable view of this section. +Click here to print. +

    +Return to the regular view of this page. +

    +
    + + + +

    gRPC service generation

    +
    Learn how to generate and fill your own gRPC services.
    + + + + + + + +
    +

    This tutorial shows how to generate a basic gRPC service like a seat service. For this example the proto file under + +https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto + is taken.

    +

    All files included from services/seats are auto-generated and added to the app project as Conan dependency. +For writing a complete gRPC service you need two velocitas apps/projects. +One is implementing a client and the other one is for providing the server. +To complete the server implementation you have to fill the generated *ServiceImpl.cpp. +Have a look at the linked content beneath for a tutorial how it would be done for a SeatService leveraging + +https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto +.

    +

    To run the example you need to start the velocitas app for the server first and then the second velocitas app for the client.

    + +
    +
    + + + + + + + + + + + + + + + + +
    + +

    1 - Create a client

    +
    Learn how to create a client for a service definition.
    +

    App configuration

    +
    {
    +  "type": "grpc-interface",
    +  "config": {
    +      "src": "https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto",
    +      // "required" indicates you are trying to write a client for the service
    +      "required": {
    +        "methods": [
    +          "Move", "CurrentPosition"
    +        ]
    +      },
    +  }
    +}
    +

    Project configuration

    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    +

    Example code

    +

    To create a client we use the generated SeatsServiceClientFactory.h and seats.grpc.pb.h. These define request and response types and the operations that are available. An example implementation for the SeatService follows:

    +

    main.cpp

    +
    #include <sdk/middleware/Middleware.h>
    +#include <services/seats/SeatsServiceClientFactory.h>
    +#include <services/seats/seats.grpc.pb.h>
    +
    +#include <iostream>
    +
    +using namespace velocitas;
    +
    +int main(int argc, char** argv) {
    +    auto serviceClient = SeatsServiceClientFactory::create(Middleware::getInstance());
    +
    +    ::grpc::ClientContext                        context;
    +    ::sdv::edge::comfort::seats::v1::MoveRequest request;
    +    ::sdv::edge::comfort::seats::v1::MoveReply   response;
    +
    +    ::sdv::edge::comfort::seats::v1::Seat seat;
    +
    +    ::sdv::edge::comfort::seats::v1::SeatLocation seat_location;
    +    seat_location.set_row(1);
    +    seat_location.set_index(1);
    +
    +    ::sdv::edge::comfort::seats::v1::Position seat_position;
    +    // we only set base here to keep the example simple
    +    // extend here if yu want to set lumbar etc.
    +    seat_position.set_base(1000);
    +
    +    seat.set_allocated_location(&seat_location);
    +    seat.set_allocated_position(&seat_position);
    +
    +    request.set_allocated_seat(&seat);
    +
    +    auto status = serviceClient->Move(&context, request, &response);
    +
    +    std::cout << "gRPC Server returned code: " << status.error_code() << std::endl;
    +    std::cout << "gRPC error message: " << status.error_message().c_str() << std::endl;
    +
    +    if (status.error_code() == ::grpc::StatusCode::UNIMPLEMENTED) {
    +        return 1;
    +    } else {
    +        ::grpc::ClientContext                                   context;
    +        ::sdv::edge::comfort::seats::v1::CurrentPositionRequest request;
    +        ::sdv::edge::comfort::seats::v1::CurrentPositionReply   response;
    +
    +        request.set_row(1);
    +        request.set_index(1);
    +
    +        auto status_curr_pos = seatService->CurrentPosition(&context, request, &response);
    +        std::cout << "current Position:" << response.seat().position().base() << std::endl;
    +        std::cout << "gRPC Server returned code: " << status_curr_pos.error_code() << std::endl;
    +        std::cout << "gRPC error message: " << status_curr_pos.error_message().c_str() << std::endl;
    +        return 0;
    +    }
    +}
    +
    +
    + + + + + + + + + + + +
    + +

    2 - Create a server

    +
    Learn how to create a server for a service definition.
    +

    App configuration

    +
    {
    +  "type": "grpc-interface",
    +  "config": {
    +      "src": "https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto",
    +      // "provided" indicates you want to implement the server business logic for the service
    +      "provided": { }
    +  }
    +}
    +

    Project configuration

    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    +

    To create a server that is providing the gRPC service we are leveraging the generated SeatsServiceImpl.h and SeatsServiceServerFactory.h. The SeatsServiceImpl.cpp needs to be filled with the actual implementation of the service. A quick example for a SeatService is described in the following:

    +

    main.cpp

    +
    #include <sdk/middleware/Middleware.h>
    +#include <services/seats/SeatsServiceServerFactory.h>
    +#include "SeatsServiceImpl.h"
    +
    +#include <memory>
    +
    +using namespace velocitas;
    +
    +int main(int argc, char** argv) {
    +    auto seatsImpl = std::make_shared<SeatsService>();
    +
    +    velocitas::VehicleModelContext::getInstance().setVdbc(
    +        velocitas::IVehicleDataBrokerClient::createInstance("vehicledatabroker"));
    +    auto seatServer =
    +        SeatsServiceServerFactory::create(Middleware::getInstance(), seatsImpl);
    +
    +    seatServer->Wait();
    +    return 0;
    +}
    +

    SeatsServiceImpl.cpp

    +
    #include "SeatsServiceImpl.h"
    +#include <sdk/VehicleApp.h>
    +#include <sdk/VehicleModelContext.h>
    +#include <sdk/vdb/IVehicleDataBrokerClient.h>
    +#include <vehicle/Vehicle.hpp>
    +#include <grpc/grpc.h>
    +#include <services/seats/seats.grpc.pb.h>
    +
    +namespace velocitas {
    +
    +::grpc::Status SeatsService::Move(::grpc::ServerContext*                              context,
    +                                  const ::sdv::edge::comfort::seats::v1::MoveRequest* request,
    +                                  ::sdv::edge::comfort::seats::v1::MoveReply*         response) {
    +    (void)context;
    +    (void)response;
    +    vehicle::Vehicle Vehicle;
    +
    +    auto seat     = request->seat();
    +    auto location = seat.location();
    +    auto row      = location.row();
    +    auto pos      = location.index();
    +
    +    // you would need to extend this to add support for lumbar etc.
    +    // Vehicle.Cabin.Seat.Row(row).Pos(pos).Position.set(seat->position()->xxxxxx())->await();
    +    auto status = Vehicle.Cabin.Seat.Row1.DriverSide.Position.set(seat.position().base())->await();
    +    if (status.ok()) {
    +        return ::grpc::Status(::grpc::StatusCode::OK, "");
    +    } else {
    +        return ::grpc::Status(::grpc::StatusCode::CANCELLED, status.errorMessage());
    +    }
    +}
    +
    +::grpc::Status
    +SeatsService::MoveComponent(::grpc::ServerContext*                                       context,
    +                            const ::sdv::edge::comfort::seats::v1::MoveComponentRequest* request,
    +                            ::sdv::edge::comfort::seats::v1::MoveComponentReply*         response) {
    +    (void)context;
    +    (void)request;
    +    (void)response;
    +    return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    +}
    +
    +::grpc::Status SeatsService::CurrentPosition(
    +    ::grpc::ServerContext*                                         context,
    +    const ::sdv::edge::comfort::seats::v1::CurrentPositionRequest* request,
    +    ::sdv::edge::comfort::seats::v1::CurrentPositionReply*         response) {
    +    (void)context;
    +    (void)request;
    +    vehicle::Vehicle Vehicle;
    +
    +    auto             seat          = response->mutable_seat();
    +    auto             seat_position = seat->mutable_position();
    +
    +    auto seatPos = Vehicle.Cabin.Seat.Row1.DriverSide.Position.get()->await().value();
    +
    +    // we only set base here to keep the example simple
    +    // extend here if yu want to set lumbar etc.
    +    seat_position->set_base(seatPos);
    +    return ::grpc::Status(::grpc::StatusCode::OK, "");
    +}
    +
    +} // namespace velocitas
    +
    +
    + + + + + + + + + +
    +
    +
    + + + + + + + +
    + + + + + + diff --git a/docs/tutorials/grpc_service_generation/create_client/index.html b/docs/tutorials/grpc_service_generation/create_client/index.html new file mode 100644 index 00000000..c45e676c --- /dev/null +++ b/docs/tutorials/grpc_service_generation/create_client/index.html @@ -0,0 +1,770 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Create a client | Velocitas + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +
    + + +
    + + + + + +
    +

    Create a client

    +
    Learn how to create a client for a service definition.
    + +

    App configuration

    +
    {
    +  "type": "grpc-interface",
    +  "config": {
    +      "src": "https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto",
    +      // "required" indicates you are trying to write a client for the service
    +      "required": {
    +        "methods": [
    +          "Move", "CurrentPosition"
    +        ]
    +      },
    +  }
    +}
    +

    Project configuration

    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    +

    Example code

    +

    To create a client we use the generated SeatsServiceClientFactory.h and seats.grpc.pb.h. These define request and response types and the operations that are available. An example implementation for the SeatService follows:

    +

    main.cpp

    +
    #include <sdk/middleware/Middleware.h>
    +#include <services/seats/SeatsServiceClientFactory.h>
    +#include <services/seats/seats.grpc.pb.h>
    +
    +#include <iostream>
    +
    +using namespace velocitas;
    +
    +int main(int argc, char** argv) {
    +    auto serviceClient = SeatsServiceClientFactory::create(Middleware::getInstance());
    +
    +    ::grpc::ClientContext                        context;
    +    ::sdv::edge::comfort::seats::v1::MoveRequest request;
    +    ::sdv::edge::comfort::seats::v1::MoveReply   response;
    +
    +    ::sdv::edge::comfort::seats::v1::Seat seat;
    +
    +    ::sdv::edge::comfort::seats::v1::SeatLocation seat_location;
    +    seat_location.set_row(1);
    +    seat_location.set_index(1);
    +
    +    ::sdv::edge::comfort::seats::v1::Position seat_position;
    +    // we only set base here to keep the example simple
    +    // extend here if yu want to set lumbar etc.
    +    seat_position.set_base(1000);
    +
    +    seat.set_allocated_location(&seat_location);
    +    seat.set_allocated_position(&seat_position);
    +
    +    request.set_allocated_seat(&seat);
    +
    +    auto status = serviceClient->Move(&context, request, &response);
    +
    +    std::cout << "gRPC Server returned code: " << status.error_code() << std::endl;
    +    std::cout << "gRPC error message: " << status.error_message().c_str() << std::endl;
    +
    +    if (status.error_code() == ::grpc::StatusCode::UNIMPLEMENTED) {
    +        return 1;
    +    } else {
    +        ::grpc::ClientContext                                   context;
    +        ::sdv::edge::comfort::seats::v1::CurrentPositionRequest request;
    +        ::sdv::edge::comfort::seats::v1::CurrentPositionReply   response;
    +
    +        request.set_row(1);
    +        request.set_index(1);
    +
    +        auto status_curr_pos = seatService->CurrentPosition(&context, request, &response);
    +        std::cout << "current Position:" << response.seat().position().base() << std::endl;
    +        std::cout << "gRPC Server returned code: " << status_curr_pos.error_code() << std::endl;
    +        std::cout << "gRPC error message: " << status_curr_pos.error_message().c_str() << std::endl;
    +        return 0;
    +    }
    +}
    +
    + + +
    + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3) +
    + +
    + + +
    +
    +
    + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/docs/tutorials/grpc_service_generation/create_server/index.html b/docs/tutorials/grpc_service_generation/create_server/index.html new file mode 100644 index 00000000..50e19e0b --- /dev/null +++ b/docs/tutorials/grpc_service_generation/create_server/index.html @@ -0,0 +1,794 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Create a server | Velocitas + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +
    + + +
    + + + + + +
    +

    Create a server

    +
    Learn how to create a server for a service definition.
    + +

    App configuration

    +
    {
    +  "type": "grpc-interface",
    +  "config": {
    +      "src": "https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto",
    +      // "provided" indicates you want to implement the server business logic for the service
    +      "provided": { }
    +  }
    +}
    +

    Project configuration

    +

    You need to specify devenv-devcontainer-setup >= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:

    +
    {
    +  "packages": {
    +    "devenv-devcontainer-setup": "v2.4.2"
    +  },
    +  "components": [
    +    {
    +      "id": "grpc-interface-support", 
    +    }
    +  ],
    +}
    +

    To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2

    +

    To create a server that is providing the gRPC service we are leveraging the generated SeatsServiceImpl.h and SeatsServiceServerFactory.h. The SeatsServiceImpl.cpp needs to be filled with the actual implementation of the service. A quick example for a SeatService is described in the following:

    +

    main.cpp

    +
    #include <sdk/middleware/Middleware.h>
    +#include <services/seats/SeatsServiceServerFactory.h>
    +#include "SeatsServiceImpl.h"
    +
    +#include <memory>
    +
    +using namespace velocitas;
    +
    +int main(int argc, char** argv) {
    +    auto seatsImpl = std::make_shared<SeatsService>();
    +
    +    velocitas::VehicleModelContext::getInstance().setVdbc(
    +        velocitas::IVehicleDataBrokerClient::createInstance("vehicledatabroker"));
    +    auto seatServer =
    +        SeatsServiceServerFactory::create(Middleware::getInstance(), seatsImpl);
    +
    +    seatServer->Wait();
    +    return 0;
    +}
    +

    SeatsServiceImpl.cpp

    +
    #include "SeatsServiceImpl.h"
    +#include <sdk/VehicleApp.h>
    +#include <sdk/VehicleModelContext.h>
    +#include <sdk/vdb/IVehicleDataBrokerClient.h>
    +#include <vehicle/Vehicle.hpp>
    +#include <grpc/grpc.h>
    +#include <services/seats/seats.grpc.pb.h>
    +
    +namespace velocitas {
    +
    +::grpc::Status SeatsService::Move(::grpc::ServerContext*                              context,
    +                                  const ::sdv::edge::comfort::seats::v1::MoveRequest* request,
    +                                  ::sdv::edge::comfort::seats::v1::MoveReply*         response) {
    +    (void)context;
    +    (void)response;
    +    vehicle::Vehicle Vehicle;
    +
    +    auto seat     = request->seat();
    +    auto location = seat.location();
    +    auto row      = location.row();
    +    auto pos      = location.index();
    +
    +    // you would need to extend this to add support for lumbar etc.
    +    // Vehicle.Cabin.Seat.Row(row).Pos(pos).Position.set(seat->position()->xxxxxx())->await();
    +    auto status = Vehicle.Cabin.Seat.Row1.DriverSide.Position.set(seat.position().base())->await();
    +    if (status.ok()) {
    +        return ::grpc::Status(::grpc::StatusCode::OK, "");
    +    } else {
    +        return ::grpc::Status(::grpc::StatusCode::CANCELLED, status.errorMessage());
    +    }
    +}
    +
    +::grpc::Status
    +SeatsService::MoveComponent(::grpc::ServerContext*                                       context,
    +                            const ::sdv::edge::comfort::seats::v1::MoveComponentRequest* request,
    +                            ::sdv::edge::comfort::seats::v1::MoveComponentReply*         response) {
    +    (void)context;
    +    (void)request;
    +    (void)response;
    +    return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    +}
    +
    +::grpc::Status SeatsService::CurrentPosition(
    +    ::grpc::ServerContext*                                         context,
    +    const ::sdv::edge::comfort::seats::v1::CurrentPositionRequest* request,
    +    ::sdv::edge::comfort::seats::v1::CurrentPositionReply*         response) {
    +    (void)context;
    +    (void)request;
    +    vehicle::Vehicle Vehicle;
    +
    +    auto             seat          = response->mutable_seat();
    +    auto             seat_position = seat->mutable_position();
    +
    +    auto seatPos = Vehicle.Cabin.Seat.Row1.DriverSide.Position.get()->await().value();
    +
    +    // we only set base here to keep the example simple
    +    // extend here if yu want to set lumbar etc.
    +    seat_position->set_base(seatPos);
    +    return ::grpc::Status(::grpc::StatusCode::OK, "");
    +}
    +
    +} // namespace velocitas
    +
    + + +
    + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3) +
    + +
    + + +
    +
    +
    + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/docs/tutorials/grpc_service_generation/index.html b/docs/tutorials/grpc_service_generation/index.html new file mode 100644 index 00000000..aab9b5a0 --- /dev/null +++ b/docs/tutorials/grpc_service_generation/index.html @@ -0,0 +1,711 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +gRPC service generation | Velocitas + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +
    + + +
    + + + + + +
    +

    gRPC service generation

    +
    Learn how to generate and fill your own gRPC services.
    + +

    This tutorial shows how to generate a basic gRPC service like a seat service. For this example the proto file under + +https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto + is taken.

    +

    All files included from services/seats are auto-generated and added to the app project as Conan dependency. +For writing a complete gRPC service you need two velocitas apps/projects. +One is implementing a client and the other one is for providing the server. +To complete the server implementation you have to fill the generated *ServiceImpl.cpp. +Have a look at the linked content beneath for a tutorial how it would be done for a SeatService leveraging + +https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto +.

    +

    To run the example you need to start the velocitas app for the server first and then the second velocitas app for the client.

    + +
    + + + + + + + + +
    + + +
    +
    + Create a client +
    +

    Learn how to create a client for a service definition.

    +
    + + +
    +
    + Create a server +
    +

    Learn how to create a server for a service definition.

    +
    + + +
    + + + +
    + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3) +
    + +
    + +
    +
    +
    + + + + + + + +
    + + + + + + \ No newline at end of file diff --git a/docs/tutorials/grpc_service_generation/index.xml b/docs/tutorials/grpc_service_generation/index.xml new file mode 100644 index 00000000..f2f7e2fd --- /dev/null +++ b/docs/tutorials/grpc_service_generation/index.xml @@ -0,0 +1,233 @@ + + + Velocitas – gRPC service generation + /velocitas-docs/docs/tutorials/grpc_service_generation/ + Recent content in gRPC service generation on Velocitas + Hugo -- gohugo.io + en + Fri, 07 Jun 2024 14:02:00 +0530 + + + + + + + + + + + Docs: Create a client + /velocitas-docs/docs/tutorials/grpc_service_generation/create_client/ + Fri, 07 Jun 2024 14:02:00 +0530 + + /velocitas-docs/docs/tutorials/grpc_service_generation/create_client/ + + + + <h2 id="app-configuration">App configuration</h2> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;type&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;grpc-interface&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;config&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;src&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// &#34;required&#34; indicates you are trying to write a client for the service +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#204a87;font-weight:bold">&#34;required&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;methods&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span> +</span></span><span style="display:flex;"><span> <span style="color:#4e9a06">&#34;Move&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;CurrentPosition&#34;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">]</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><h2 id="project-configuration">Project configuration</h2> +<p>You need to specify <code>devenv-devcontainer-setup</code> &gt;= <code>v2.4.2</code> in your project configuration. Therefore your <code>.veloitas.json</code> should look similair to this example:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;packages&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;devenv-devcontainer-setup&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;v2.4.2&#34;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;components&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;grpc-interface-support&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">],</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><p>To do that you can run <code>velocitas component add grpc-interface-support</code> when your package is above or equal to v2.4.2</p> +<h2 id="example-code">Example code</h2> +<p>To create a client we use the generated <code>SeatsServiceClientFactory.h</code> and <code>seats.grpc.pb.h</code>. These define request and response types and the operations that are available. An example implementation for the SeatService follows:</p> +<h3 id="maincpp">main.cpp</h3> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;sdk/middleware/Middleware.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;services/seats/SeatsServiceClientFactory.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;services/seats/seats.grpc.pb.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> +</span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;iostream&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> +</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">using</span> <span style="color:#204a87;font-weight:bold">namespace</span> <span style="color:#000">velocitas</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">int</span> <span style="color:#000">main</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">int</span> <span style="color:#000">argc</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">char</span><span style="color:#ce5c00;font-weight:bold">**</span> <span style="color:#000">argv</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">serviceClient</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">SeatsServiceClientFactory</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">create</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">Middleware</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">getInstance</span><span style="color:#000;font-weight:bold">());</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">ClientContext</span> <span style="color:#000">context</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveRequest</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveReply</span> <span style="color:#000">response</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Seat</span> <span style="color:#000">seat</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">SeatLocation</span> <span style="color:#000">seat_location</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">seat_location</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_row</span><span style="color:#000;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">seat_location</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_index</span><span style="color:#000;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Position</span> <span style="color:#000">seat_position</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// we only set base here to keep the example simple +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#8f5902;font-style:italic">// extend here if yu want to set lumbar etc. +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#000">seat_position</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_base</span><span style="color:#000;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1000</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#000">seat</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_allocated_location</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">seat_location</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">seat</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_allocated_position</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">seat_position</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_allocated_seat</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">seat</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">status</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">serviceClient</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">Move</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">context</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">response</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">cout</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#4e9a06">&#34;gRPC Server returned code: &#34;</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">status</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">error_code</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">endl</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">cout</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#4e9a06">&#34;gRPC error message: &#34;</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">status</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">error_message</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">c_str</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">endl</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">status</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">error_code</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#ce5c00;font-weight:bold">==</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">StatusCode</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">UNIMPLEMENTED</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> <span style="color:#204a87;font-weight:bold">else</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">ClientContext</span> <span style="color:#000">context</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">CurrentPositionRequest</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">CurrentPositionReply</span> <span style="color:#000">response</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_row</span><span style="color:#000;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set_index</span><span style="color:#000;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">status_curr_pos</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">seatService</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">CurrentPosition</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">context</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">response</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">cout</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#4e9a06">&#34;current Position:&#34;</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">response</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">seat</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">position</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">base</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">endl</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">cout</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#4e9a06">&#34;gRPC Server returned code: &#34;</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">status_curr_pos</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">error_code</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">endl</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">cout</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#4e9a06">&#34;gRPC error message: &#34;</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">status_curr_pos</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">error_message</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">c_str</span><span style="color:#000;font-weight:bold">()</span> <span style="color:#ce5c00;font-weight:bold">&lt;&lt;</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">endl</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div> + + + + + Docs: Create a server + /velocitas-docs/docs/tutorials/grpc_service_generation/create_server/ + Fri, 07 Jun 2024 14:02:00 +0530 + + /velocitas-docs/docs/tutorials/grpc_service_generation/create_server/ + + + + <h2 id="app-configuration">App configuration</h2> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;type&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;grpc-interface&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;config&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;src&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// &#34;provided&#34; indicates you want to implement the server business logic for the service +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#204a87;font-weight:bold">&#34;provided&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><h2 id="project-configuration">Project configuration</h2> +<p>You need to specify <code>devenv-devcontainer-setup</code> &gt;= <code>v2.4.2</code> in your project configuration. Therefore your <code>.veloitas.json</code> should look similair to this example:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;packages&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;devenv-devcontainer-setup&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;v2.4.2&#34;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;components&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;grpc-interface-support&#34;</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">],</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><p>To do that you can run <code>velocitas component add grpc-interface-support</code> when your package is above or equal to v2.4.2</p> +<p>To create a server that is providing the gRPC service we are leveraging the generated <code>SeatsServiceImpl.h</code> and <code>SeatsServiceServerFactory.h</code>. The <code>SeatsServiceImpl.cpp</code> needs to be filled with the actual implementation of the service. A quick example for a SeatService is described in the following:</p> +<h3 id="maincpp">main.cpp</h3> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;sdk/middleware/Middleware.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;services/seats/SeatsServiceServerFactory.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&#34;SeatsServiceImpl.h&#34;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> +</span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;memory&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> +</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">using</span> <span style="color:#204a87;font-weight:bold">namespace</span> <span style="color:#000">velocitas</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">int</span> <span style="color:#000">main</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">int</span> <span style="color:#000">argc</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">char</span><span style="color:#ce5c00;font-weight:bold">**</span> <span style="color:#000">argv</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">seatsImpl</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">std</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">make_shared</span><span style="color:#ce5c00;font-weight:bold">&lt;</span><span style="color:#000">SeatsService</span><span style="color:#ce5c00;font-weight:bold">&gt;</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#000">velocitas</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">VehicleModelContext</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">getInstance</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">setVdbc</span><span style="color:#000;font-weight:bold">(</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">velocitas</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">IVehicleDataBrokerClient</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">createInstance</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;vehicledatabroker&#34;</span><span style="color:#000;font-weight:bold">));</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">seatServer</span> <span style="color:#ce5c00;font-weight:bold">=</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">SeatsServiceServerFactory</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">create</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">Middleware</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">getInstance</span><span style="color:#000;font-weight:bold">(),</span> <span style="color:#000">seatsImpl</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#000">seatServer</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">Wait</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span></code></pre></div><h3 id="seatsserviceimplcpp">SeatsServiceImpl.cpp</h3> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cpp" data-lang="cpp"><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&#34;SeatsServiceImpl.h&#34;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;sdk/VehicleApp.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;sdk/VehicleModelContext.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;sdk/vdb/IVehicleDataBrokerClient.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;vehicle/Vehicle.hpp&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;grpc/grpc.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">#include</span> <span style="color:#8f5902;font-style:italic">&lt;services/seats/seats.grpc.pb.h&gt;</span><span style="color:#8f5902;font-style:italic"> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> +</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">namespace</span> <span style="color:#000">velocitas</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span> <span style="color:#000">SeatsService</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Move</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">ServerContext</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">context</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">const</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveRequest</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveReply</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">response</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">context</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">response</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">vehicle</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Vehicle</span> <span style="color:#000">Vehicle</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">seat</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">request</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">seat</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">location</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">seat</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">location</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">row</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">location</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">row</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">pos</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">location</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">index</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// you would need to extend this to add support for lumbar etc. +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#8f5902;font-style:italic">// Vehicle.Cabin.Seat.Row(row).Pos(pos).Position.set(seat-&gt;position()-&gt;xxxxxx())-&gt;await(); +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">status</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">Vehicle</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Cabin</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Seat</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Row1</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">DriverSide</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Position</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">set</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">seat</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">position</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">base</span><span style="color:#000;font-weight:bold">())</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">await</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">status</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">ok</span><span style="color:#000;font-weight:bold">())</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">StatusCode</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">OK</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;&#34;</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> <span style="color:#204a87;font-weight:bold">else</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">StatusCode</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">CANCELLED</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">status</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">errorMessage</span><span style="color:#000;font-weight:bold">());</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span> +</span></span><span style="display:flex;"><span><span style="color:#000">SeatsService</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveComponent</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">ServerContext</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">context</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">const</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveComponentRequest</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">MoveComponentReply</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">response</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">context</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">request</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">response</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">StatusCode</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">UNIMPLEMENTED</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;&#34;</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span> <span style="color:#000">SeatsService</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">CurrentPosition</span><span style="color:#000;font-weight:bold">(</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">ServerContext</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">context</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">const</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">CurrentPositionRequest</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">request</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">sdv</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">edge</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">comfort</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">seats</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">v1</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">CurrentPositionReply</span><span style="color:#ce5c00;font-weight:bold">*</span> <span style="color:#000">response</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">context</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#000;font-weight:bold">)</span><span style="color:#000">request</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">vehicle</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Vehicle</span> <span style="color:#000">Vehicle</span><span style="color:#000;font-weight:bold">;</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">seat</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">response</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">mutable_seat</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">seat_position</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">seat</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">mutable_position</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">auto</span> <span style="color:#000">seatPos</span> <span style="color:#ce5c00;font-weight:bold">=</span> <span style="color:#000">Vehicle</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Cabin</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Seat</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Row1</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">DriverSide</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Position</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">get</span><span style="color:#000;font-weight:bold">()</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">await</span><span style="color:#000;font-weight:bold">().</span><span style="color:#000">value</span><span style="color:#000;font-weight:bold">();</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// we only set base here to keep the example simple +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#8f5902;font-style:italic">// extend here if yu want to set lumbar etc. +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#000">seat_position</span><span style="color:#ce5c00;font-weight:bold">-&gt;</span><span style="color:#000">set_base</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">seatPos</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">Status</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">grpc</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">StatusCode</span><span style="color:#ce5c00;font-weight:bold">::</span><span style="color:#000">OK</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;&#34;</span><span style="color:#000;font-weight:bold">);</span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> +</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> <span style="color:#8f5902;font-style:italic">// namespace velocitas +</span></span></span></code></pre></div> + + + + + diff --git a/docs/tutorials/index.html b/docs/tutorials/index.html index 2c62fed0..d64ec23a 100644 --- a/docs/tutorials/index.html +++ b/docs/tutorials/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -533,6 +555,14 @@
    +
    +
    + gRPC service generation +
    +

    Learn how to generate and fill your own gRPC services.

    +
    + +
    Vehicle App Deployment @@ -546,7 +576,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/index.xml b/docs/tutorials/index.xml index 5ef0d7a2..d94b938b 100644 --- a/docs/tutorials/index.xml +++ b/docs/tutorials/index.xml @@ -110,6 +110,32 @@ now.</p></p> + + Docs: gRPC service generation + /velocitas-docs/docs/tutorials/grpc_service_generation/ + Fri, 07 Jun 2024 14:02:00 +0530 + + /velocitas-docs/docs/tutorials/grpc_service_generation/ + + + + <p>This tutorial shows how to generate a basic gRPC service like a seat service. For this example the proto file under + +<a href="https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto" target="_blank" rel="noopener">https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto</a> + is taken.</p> +<p>All files included from <code>services/seats</code> are auto-generated and added to the app project as Conan dependency. +For writing a complete gRPC service you need two velocitas apps/projects. +One is implementing a client and the other one is for providing the server. +To complete the server implementation you have to fill the generated <code>*ServiceImpl.cpp</code>. +Have a look at the linked content beneath for a tutorial how it would be done for a SeatService leveraging + +<a href="https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto" target="_blank" rel="noopener">https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto</a> +.</p> +<p>To run the example you need to start the velocitas app for the server first and then the second velocitas app for the client.</p> + + + + Docs: Vehicle App Deployment /velocitas-docs/docs/tutorials/vehicle_app_deployment/ diff --git a/docs/tutorials/prototyping/_print/index.html b/docs/tutorials/prototyping/_print/index.html index e36e2156..4e387ace 100644 --- a/docs/tutorials/prototyping/_print/index.html +++ b/docs/tutorials/prototyping/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -393,13 +393,13 @@

    2 - Service Integration

    Modify existing services

    For more advanced usage you can also try to modify existing services. Check out -the seat service +the seat service for example, modify it and integrate it into your Vehicle App repository.

    Create your own services

    If you want to create your own service the -KUKSA.VAL Services repository - contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to KUKSA.VAL listening to changes of a target value of some VSS data point and then do whatever you want. You can achieve this by using the KUKSA.VAL +KUKSA Incubation repository + contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to KUKSA listening to changes of a target value of some VSS data point and then do whatever you want. You can achieve this by using the KUKSA gRPC API with any programming language of your choice (learn more about diff --git a/docs/tutorials/prototyping/digital_auto/index.html b/docs/tutorials/prototyping/digital_auto/index.html index 7ec2b4a3..6e334092 100644 --- a/docs/tutorials/prototyping/digital_auto/index.html +++ b/docs/tutorials/prototyping/digital_auto/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -

  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -687,7 +709,7 @@

    Transfer your pr
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/prototyping/index.html b/docs/tutorials/prototyping/index.html index 19ceee78..d0d6bd42 100644 --- a/docs/tutorials/prototyping/index.html +++ b/docs/tutorials/prototyping/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -

  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -516,7 +538,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/prototyping/index.xml b/docs/tutorials/prototyping/index.xml index 844f86d2..d498bfd7 100644 --- a/docs/tutorials/prototyping/index.xml +++ b/docs/tutorials/prototyping/index.xml @@ -235,13 +235,13 @@ Clone your newly created repository and open the <em>Vehicle App</em> <h3 id="modify-existing-services">Modify existing services</h3> <p>For more advanced usage you can also try to modify existing services. Check out -<a href="https://github.com/eclipse/kuksa.val.services/tree/main/seat_service" target="_blank" rel="noopener">the seat service</a> +<a href="https://github.com/eclipse-kuksa/kuksa-incubation/tree/main/seat_service" target="_blank" rel="noopener">the seat service</a> for example, modify it and integrate it into your <em>Vehicle App</em> repository.</p> <h3 id="create-your-own-services">Create your own services</h3> <p>If you want to create your own service the -<a href="https://github.com/eclipse/kuksa.val.services/" target="_blank" rel="noopener">KUKSA.VAL Services repository</a> - contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to <em>KUKSA.VAL</em> listening to changes of a <em>target value</em> of some VSS data point and then do whatever you want. You can achieve this by using the <em>KUKSA.VAL</em> +<a href="https://github.com/eclipse-kuksa/kuksa-incubation" target="_blank" rel="noopener">KUKSA Incubation repository</a> + contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to <em>KUKSA</em> listening to changes of a <em>target value</em> of some VSS data point and then do whatever you want. You can achieve this by using the <em>KUKSA</em> <a href="https://github.com/eclipse-kuksa/kuksa-databroker/tree/main/proto/kuksa/val/v1" target="_blank" rel="noopener">gRPC API</a> with any programming language of your choice (learn more about diff --git a/docs/tutorials/prototyping/service_integration/index.html b/docs/tutorials/prototyping/service_integration/index.html index 3a46081a..8eb5aa78 100644 --- a/docs/tutorials/prototyping/service_integration/index.html +++ b/docs/tutorials/prototyping/service_integration/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -518,13 +540,13 @@

    Service Integration

    Modify existing services

    For more advanced usage you can also try to modify existing services. Check out -the seat service +the seat service for example, modify it and integrate it into your Vehicle App repository.

    Create your own services

    If you want to create your own service the -KUKSA.VAL Services repository - contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to KUKSA.VAL listening to changes of a target value of some VSS data point and then do whatever you want. You can achieve this by using the KUKSA.VAL +KUKSA Incubation repository + contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to KUKSA listening to changes of a target value of some VSS data point and then do whatever you want. You can achieve this by using the KUKSA gRPC API with any programming language of your choice (learn more about @@ -548,7 +570,7 @@

    Mock Provider and Mock Prov
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/quickstart/_print/index.html b/docs/tutorials/quickstart/_print/index.html index 64213881..bf26de75 100644 --- a/docs/tutorials/quickstart/_print/index.html +++ b/docs/tutorials/quickstart/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/tutorials/quickstart/behind_proxy/index.html b/docs/tutorials/quickstart/behind_proxy/index.html index 56d01bcb..e4f31577 100644 --- a/docs/tutorials/quickstart/behind_proxy/index.html +++ b/docs/tutorials/quickstart/behind_proxy/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -

  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -711,7 +733,7 @@

    GitHub rate limit exceeded

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/quickstart/container_runtime/index.html b/docs/tutorials/quickstart/container_runtime/index.html index eeb89add..1050a889 100644 --- a/docs/tutorials/quickstart/container_runtime/index.html +++ b/docs/tutorials/quickstart/container_runtime/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -548,7 +570,7 @@

    Other alternatives

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/quickstart/import_examples/index.html b/docs/tutorials/quickstart/import_examples/index.html index 9ed2d594..2851e956 100644 --- a/docs/tutorials/quickstart/import_examples/index.html +++ b/docs/tutorials/quickstart/import_examples/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -532,7 +554,7 @@

    Run the Vehicle App fro
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/quickstart/index.html b/docs/tutorials/quickstart/index.html index b1d42a8b..005f6b9b 100644 --- a/docs/tutorials/quickstart/index.html +++ b/docs/tutorials/quickstart/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -

  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -532,7 +554,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/quickstart/quickstart/index.html b/docs/tutorials/quickstart/quickstart/index.html index a6e4c132..18ab45ea 100644 --- a/docs/tutorials/quickstart/quickstart/index.html +++ b/docs/tutorials/quickstart/quickstart/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -934,7 +956,7 @@

    Next steps

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_app_deployment/_print/index.html b/docs/tutorials/vehicle_app_deployment/_print/index.html index 03e2ba4a..cb1f6e79 100644 --- a/docs/tutorials/vehicle_app_deployment/_print/index.html +++ b/docs/tutorials/vehicle_app_deployment/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/tutorials/vehicle_app_deployment/index.html b/docs/tutorials/vehicle_app_deployment/index.html index 2e6ed1b1..0339d43a 100644 --- a/docs/tutorials/vehicle_app_deployment/index.html +++ b/docs/tutorials/vehicle_app_deployment/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -502,7 +524,7 @@

    Vehicle App Deployment

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_app_development/_print/index.html b/docs/tutorials/vehicle_app_development/_print/index.html index 72462914..d88c5c13 100644 --- a/docs/tutorials/vehicle_app_development/_print/index.html +++ b/docs/tutorials/vehicle_app_development/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/tutorials/vehicle_app_development/cpp_development/index.html b/docs/tutorials/vehicle_app_development/cpp_development/index.html index 7f5a32b8..4a85db4e 100644 --- a/docs/tutorials/vehicle_app_development/cpp_development/index.html +++ b/docs/tutorials/vehicle_app_development/cpp_development/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -963,7 +985,7 @@

    Next steps

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_app_development/index.html b/docs/tutorials/vehicle_app_development/index.html index 693c0488..97e00e36 100644 --- a/docs/tutorials/vehicle_app_development/index.html +++ b/docs/tutorials/vehicle_app_development/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -528,7 +550,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_app_development/integration_tests/index.html b/docs/tutorials/vehicle_app_development/integration_tests/index.html index 3ddd87af..6aa96d11 100644 --- a/docs/tutorials/vehicle_app_development/integration_tests/index.html +++ b/docs/tutorials/vehicle_app_development/integration_tests/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -634,7 +656,7 @@

    Next steps

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_app_development/python_development/index.html b/docs/tutorials/vehicle_app_development/python_development/index.html index 6f2bac4f..8650e7fb 100644 --- a/docs/tutorials/vehicle_app_development/python_development/index.html +++ b/docs/tutorials/vehicle_app_development/python_development/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -874,7 +896,7 @@

    Next steps

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_app_runtime/_print/index.html b/docs/tutorials/vehicle_app_runtime/_print/index.html index 4378eb74..8617ff6b 100644 --- a/docs/tutorials/vehicle_app_runtime/_print/index.html +++ b/docs/tutorials/vehicle_app_runtime/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/tutorials/vehicle_app_runtime/index.html b/docs/tutorials/vehicle_app_runtime/index.html index d84660b3..970b67d7 100644 --- a/docs/tutorials/vehicle_app_runtime/index.html +++ b/docs/tutorials/vehicle_app_runtime/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -516,7 +538,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_app_runtime/kanto_runtime/index.html b/docs/tutorials/vehicle_app_runtime/kanto_runtime/index.html index 6fa2f91d..db51e8cd 100644 --- a/docs/tutorials/vehicle_app_runtime/kanto_runtime/index.html +++ b/docs/tutorials/vehicle_app_runtime/kanto_runtime/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -582,7 +604,7 @@

    Next steps

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_app_runtime/local_runtime/index.html b/docs/tutorials/vehicle_app_runtime/local_runtime/index.html index 8d3aead1..d1cbaefb 100644 --- a/docs/tutorials/vehicle_app_runtime/local_runtime/index.html +++ b/docs/tutorials/vehicle_app_runtime/local_runtime/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -582,7 +604,7 @@

    Next steps

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_model_creation/_print/index.html b/docs/tutorials/vehicle_model_creation/_print/index.html index a3d4e174..9c0c39f5 100644 --- a/docs/tutorials/vehicle_model_creation/_print/index.html +++ b/docs/tutorials/vehicle_model_creation/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -774,7 +774,7 @@

    Add a Vehicle Service

    As example you could use the protocol buffers message definition seats.proto - provided by the KUKSA.VAL services which describes a + provided by the KUKSA services which describes a seat control service .

    diff --git a/docs/tutorials/vehicle_model_creation/automated_model_lifecycle/_print/index.html b/docs/tutorials/vehicle_model_creation/automated_model_lifecycle/_print/index.html index aa477253..7c9638e3 100644 --- a/docs/tutorials/vehicle_model_creation/automated_model_lifecycle/_print/index.html +++ b/docs/tutorials/vehicle_model_creation/automated_model_lifecycle/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/tutorials/vehicle_model_creation/automated_model_lifecycle/index.html b/docs/tutorials/vehicle_model_creation/automated_model_lifecycle/index.html index 2225c92c..beb0e289 100644 --- a/docs/tutorials/vehicle_model_creation/automated_model_lifecycle/index.html +++ b/docs/tutorials/vehicle_model_creation/automated_model_lifecycle/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -635,7 +657,7 @@

    Further information

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_model_creation/index.html b/docs/tutorials/vehicle_model_creation/index.html index 85c21347..b126fe61 100644 --- a/docs/tutorials/vehicle_model_creation/index.html +++ b/docs/tutorials/vehicle_model_creation/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -542,7 +564,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_model_creation/manual_model_creation/_print/index.html b/docs/tutorials/vehicle_model_creation/manual_model_creation/_print/index.html index 0e666aa5..98869c86 100644 --- a/docs/tutorials/vehicle_model_creation/manual_model_creation/_print/index.html +++ b/docs/tutorials/vehicle_model_creation/manual_model_creation/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -531,7 +531,7 @@

    Add a Vehicle Service

    As example you could use the protocol buffers message definition seats.proto - provided by the KUKSA.VAL services which describes a + provided by the KUKSA services which describes a seat control service .

    diff --git a/docs/tutorials/vehicle_model_creation/manual_model_creation/index.html b/docs/tutorials/vehicle_model_creation/manual_model_creation/index.html index 89dbe7c5..a17f1c29 100644 --- a/docs/tutorials/vehicle_model_creation/manual_model_creation/index.html +++ b/docs/tutorials/vehicle_model_creation/manual_model_creation/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -
  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -678,7 +700,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_model_creation/manual_model_creation/index.xml b/docs/tutorials/vehicle_model_creation/manual_model_creation/index.xml index 2ae68509..25583157 100644 --- a/docs/tutorials/vehicle_model_creation/manual_model_creation/index.xml +++ b/docs/tutorials/vehicle_model_creation/manual_model_creation/index.xml @@ -197,7 +197,7 @@ Successfully installed my-vehicle-model-0.1 <p>As example you could use the protocol buffers message definition <a href="https://github.com/eclipse-kuksa/kuksa-incubation/blob/main/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto" target="_blank" rel="noopener">seats.proto</a> - provided by the KUKSA.VAL services which describes a + provided by the KUKSA services which describes a <a href="https://github.com/eclipse-kuksa/kuksa-incubation/tree/main/seat_service" target="_blank" rel="noopener">seat control service</a> .</p> diff --git a/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_cpp/index.html b/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_cpp/index.html index 58d96c79..8d29add6 100644 --- a/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_cpp/index.html +++ b/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_cpp/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -496,7 +518,7 @@

    C++ Manual Vehicle Model Creation

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_python/index.html b/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_python/index.html index 6daa143b..482d48b5 100644 --- a/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_python/index.html +++ b/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_python/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -662,7 +684,7 @@

    Add a Vehicle Service

    As example you could use the protocol buffers message definition seats.proto - provided by the KUKSA.VAL services which describes a + provided by the KUKSA services which describes a seat control service .

    @@ -742,7 +764,7 @@

    Add a Vehicle Service

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/_print/index.html b/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/_print/index.html index 79aac143..9c9bd164 100644 --- a/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/_print/index.html +++ b/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/_print/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_cpp/index.html b/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_cpp/index.html index f4118563..442bd104 100644 --- a/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_cpp/index.html +++ b/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_cpp/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -523,7 +545,7 @@

    Using a git submodule

    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_python/index.html b/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_python/index.html index f0961423..1c96cf8d 100644 --- a/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_python/index.html +++ b/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_python/index.html @@ -42,12 +42,12 @@ - + - + @@ -119,7 +119,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -175,10 +175,17 @@ -
  • +
  • +
  • @@ -385,6 +392,21 @@ +
  • + +
  • + + + +
  • @@ -552,7 +574,7 @@

    Distribute publicly as open source - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3) diff --git a/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/index.html b/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/index.html index 024f47ad..69d76939 100644 --- a/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/index.html +++ b/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/index.html @@ -90,7 +90,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -116,7 +116,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -172,10 +172,17 @@ -

  • +
  • +
  • @@ -382,6 +389,21 @@ +
  • + +
  • + + + +
  • @@ -522,7 +544,7 @@
    - Last modified May 31, 2024: Another fix of cpp_development.md (976a356) + Last modified September 12, 2024: Remove kuksa.val and VSC references (#128) (e8ca8f3)
    diff --git a/index.html b/index.html index 154dc2cf..a76da04b 100644 --- a/index.html +++ b/index.html @@ -86,7 +86,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/offline-search-index.898608b2e212281545d5ed2fdb781372.json b/offline-search-index.898608b2e212281545d5ed2fdb781372.json new file mode 100644 index 00000000..c530c1d2 --- /dev/null +++ b/offline-search-index.898608b2e212281545d5ed2fdb781372.json @@ -0,0 +1 @@ +[{"body":"The open and web based digital.auto offers a rapid prototyping environment to explore and validate ideas of a Vehicle App. digital.auto interacts with different vehicle sensors and actuators via standardized APIs specified by the COVESA Vehicle Signal Specification (VSS) without custom setup requirements. Within the platform you can:\nbrowse, navigate and enhance vehicle signals (sensors, actuators and branches) in the Vehicle API Catalogue mapped to a 3D model of the vehicle. build Vehicle App prototypes in the browser using Python and the Vehicle API Catalogue. test the Vehicle App prototype in a dashboard with 3D animation for API calls. create new plugins, which usually represent UX widgets or remote server communication to enhance the vehicle mockup experience in the playground. collect and evaluate user feedback to prioritize your development portfolio. Start the journey of a Vehicle App As first step open digital.auto , select Get Started in the prototyping section of the landing page and use the Vehicle Model of your choice.\nYou now have the possibility to browse existing vehicle signals for the selected vehicle model which you can use for prototyping your Vehicle App by clicking on Vehicle APIs.\nAdd additional Vehicle APIs If the ideation of your Vehicle App prototype comes with any new Vehicle API which is not part of the standard VSS you also have the option to include it into your pre-selected model by clicking the + New Wishlist API button. After filling out all required fields, simply click the create button - this will commit the new API to the existing model.\nNote For this feature, a digital.auto account is required. Get in touch with us or the digital.auto team in case you want to explore this feature. Prototype an idea of a Vehicle App The next step would be to prototype your idea. To do so:\nClick on Prototype Library of your selected model. Create a new prototype, by clicking on New Prototype and filling out the information or select one from the list. Click on the Open button. Go to the Code section and start your prototype right away. Test the prototype of a Vehicle App Testing of your prototype starts in the Run section. You will find a dashboard consisting all vehicle and application components similar to mockups. The control center on the right side has an integrated terminal showing all of your prototyped outputs as well as a list of all called VSS API’s. The Run button executes all your prototype code from top to bottom. The Debug button allows you to step through your prototype line by line.\nTo get started quickly, the digital.auto team has added a number of widgets to simulate related elements of the vehicle – like doors, seats, light, etc. – and made them available in the playground.\nFeel free to add your own Plugins with widgets for additional car features (maybe an antenna waving a warm “welcome”…?).\nTransfer your prototype into a Velocitas Vehicle App In the previous steps you started with envisioning and prototyping your Vehicle App idea and tested it against mocked vehicle components in digital.auto. The Velocitas team provides a project generator to transfer the prototype from digital.auto into your own development environment where you are able to test it with real Vehicle Services . The generator creates a Vehicle App GitHub repository using your prototype code based on our vehicle-app-python-template . In the ‘Code’ section of your prototype in digital.auto you have the button ‘Create Eclipse Velocitas Project’.\nAfter pressing the button you will be forwarded to GitHub . Login with your GitHub Account and authorize velocitas-project-generator to create the repository for you. You will be redirected to digital.auto and asked for a repository name (equals to the name of the Vehicle App). By clicking on “Create repository”:\nthe project generator takes over your prototype code. the code is adapted to the structure in the vehicle-app-python-template . a new private repository under your specified GitHub User will be created. A successful generation of the repository is followed by a pop-up dialogue with the URL of your repository.\nAmong other things the newly created repository will contain:\nFiles Description /app/src/main.py Main class of the Vehicle App, containing your modified prototype code /app/AppManifest.json Settings file defining required services /app/requirements.txt Requirements file defining all Python dependencies /.devcontainer/ Required scripts and settings to setup the devcontainer in Microsoft Visual Studio Code /.github/workflows/ All required CI/CD pipelines to build, test and deploy the Vehicle App as container image to the GitHub container registry /gen/vehicle_model/ The generated model classes. If your prototype includes any exceptional API you added beforehand our automated vehicle model lifecycle takes care of handling the custom VSS vspec file coming from digital.auto and generates a vehicle_model when starting the devContainer Your prototype Vehicle App transferred into a GitHub repository is now ready to be extended. Clone your newly created repository and open the Vehicle App in Microsoft Visual Studio Code and start to extend it.\nYou can proceed with the following topics:\nStarting development environment Vehicle App Development ","categories":"","description":"Learn how to start a _Vehicle App_ prototype with the playground of digital.auto and integrate it into Velocitas.\n","excerpt":"Learn how to start a _Vehicle App_ prototype with the playground of …","ref":"/velocitas-docs/docs/tutorials/prototyping/digital_auto/","tags":"","title":"digital.auto"},{"body":"Using tasks in Visual Studio Code Overview: If you are developing in Visual Studio Code, the runtime components (like KUKSA Databroker or Vehicle Services) are available for local execution coming from our devenv-runtimes package and are accessible as Tasks, a feature of the Visual Studio Code. Additional information on tasks can be found here .\nStart local runtime: To start local runtime, a task called Local Runtime - Up is available. This task runs the runtime services in the correct order. You can run this task by clicking F1 and choose Tasks: Run task, then select Local Runtime - Up.\nStop local runtime: To stop local runtime, a task called Local Runtime - Down is available. This task stops running runtime services gracefully. You can run this task by clicking F1 and choose Tasks: Run task, then select Local Runtime - Down.\nTasks Management: Visual Studio Code offers various other commands concerning tasks like Start/Terminate/Restart/… You can access them by pressing F1 and typing task. A list with available task commands will appear.\nLogging: Running tasks appear in the Terminals View of Visual Studio Code. From there, you can see the logs of each running task. More detailed logs can be found inside your workspace’s logs directory ./logs/*\nAdd/Change runtime service configuration The configuration for services of our provided local runtime are defined in the runtime.json at the root of the repository devenv-runtimes . For a more detailed view on how to change or add runtime service configuration, please visit: Lifecycle Management Package Development Using KUKSA Databroker CLI A CLI tool is provided for interacting with a running instance of the KUKSA Databroker. It can be started by running the task Local Runtime - VehicleDataBroker CLI(by pressing F1, type Run Task followed by Local Runtime - VehicleDataBroker CLI). The Runtime Local needs to be running for you to be able to use the tool.\nIntegrating a new runtime service into Visual Studio Code Task Integration of a new runtime service can be done by duplicating one of the existing tasks.\nCreate a new service in either a new created Package or branch/fork of devenv-runtimes as already explained above In .vscode/tasks.json, duplicate section from task e.g. Local Runtime - Up, Local Runtime - Run VehicleApp or Local Runtime - VehicleDataBroker CLI Correct names in a new code block Disclaimer: Problem Matcher defined in tasks.json is a feature of the Visual Studio Code Task, to ensure that the process runs in background Run task using [F1 -\u003e Tasks: Run Task -\u003e \u003cYour new task label\u003e] Task should be visible in Terminal section of Visual Studio Code Task CodeBlock helper { \"label\": \"\u003ctask_name\u003e\", \"detail\": \"\u003ctask_description\u003e\", \"type\": \"shell\", \"command\": [ \"velocitas exec runtime-local \u003cservice_id\u003e \u003cargs\u003e\" ], \"presentation\": { \"close\": true, \"reveal\": \"never\" }, \"problemMatcher\": [] } Troubleshooting Problem description: When integrating new services into an existing dev environment, it is highly recommended to use the Visual Studio Code Task Feature. A new service can be easily started by calling it from bash script, however restarting the same service might lead to port conflicts (GRPC Port or APP port). That can be easily avoided by using the Visual Studio Code Task Feature.\nCodespaces If you are using Codespaces, remember that you are working on a remote agent. That’s why it could happen that the tasks are already running in the background. If that’s the case a new start of the tasks will fail, since the ports are already in use. Another possibility to check if the processes are already running, is to check which ports are already open. Check the Ports-tab to view all open ports (if not already open, hit F1 and enter View: Toggle Ports).\nNext steps Tutorial: Quickstart Concept: Deployment Model Concept: Build and release process ","categories":"","description":"Learn how to run the _Vehicle App_ Runtime Services locally.\n","excerpt":"Learn how to run the _Vehicle App_ Runtime Services locally.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_app_runtime/local_runtime/","tags":"","title":"Local Runtime"},{"body":" We recommend that you make yourself familiar with the Vehicle App SDK first, before going through this tutorial.\nThe following information describes how to develop and test the sample Vehicle App that is included in the Python template repository . You will learn how to use the Vehicle App Python SDK and how to interact with the Vehicle Model.\nOnce you have completed all steps, you will have a solid understanding of the development workflow and you will be able to reuse the template repository for your own Vehicle App development project.\nDevelop your first Vehicle App This section describes how to develop your first Vehicle App. Before you start building a new Vehicle App, make sure you have already read this manual:\nQuickstart Once you have established your development environment, you will be able to start developing your first Vehicle App.\nFor this tutorial, you will recreate the Vehicle App that is included with the SDK repository : The Vehicle App allows to change the position of the driver’s seat in the car and also provides its current positions to other applications. A detailed explanation of the use case and the example is available here .\nNote If you don’t like to do the following steps by yourself, you can use the Import example app from SDK task within VS Code to get a working copy of this example into your repository. For details about the import of an example from the SDK look here\nSetting up the basic skeleton of your app At first, you have to create the main Python script called main.py in /app/src. All the relevant code for your new Vehicle App goes there.\nIf you’ve created your app development repository from our Python template repository , the Velocitas CLI create command or via digital.auto prototyping a file with this name is already present and can be adjusted to your needs.\nSetting up the basic skeleton of an app consists of the following steps:\nManage your imports Enable logging Initialize your class Define the entry point of your app Manage your imports Before you start development in the main.py you just created, it will be necessary to include the imports required, which you will understand better later through the development:\nimport asyncio import json import logging import signal from velocitas_sdk.util.log import ( # type: ignore get_opentelemetry_log_factory, get_opentelemetry_log_format, ) from velocitas_sdk.vdb.reply import DataPointReply from velocitas_sdk.vehicle_app import VehicleApp, subscribe_topic from vehicle import Vehicle, vehicle # type: ignore Enable logging The following logging configuration applies the default log format provided by the SDK and sets the log level to INFO:\nlogging.setLogRecordFactory(get_opentelemetry_log_factory()) logging.basicConfig(format=get_opentelemetry_log_format()) logging.getLogger().setLevel(\"INFO\") logger = logging.getLogger(__name__) Initialize your class The main class of your new Vehicle App needs to inherit the VehicleApp provided by the Python SDK .\nclass MyVehicleApp(VehicleApp): In class initialization, you have to pass an instance of the Vehicle Model:\ndef __init__(self, vehicle_client: Vehicle): super().__init__() self.Vehicle = vehicle_client We save the vehicle object to use it in our app. Now, you have initialized the app and can continue developing relevant methods.\nEntry point of your app Here’s an example of an entry point to the MyVehicleApp that we just developed:\nasync def main(): \"\"\"Main function\"\"\" logger.info(\"Starting my VehicleApp...\") vehicle_app = MyVehicleApp(vehicle) await vehicle_app.run() LOOP = asyncio.get_event_loop() LOOP.add_signal_handler(signal.SIGTERM, LOOP.stop) LOOP.run_until_complete(main()) LOOP.close() With this your app can now be started. In order to provide some meaningful behaviour of the app, we will enhance it with more features in the next sections.\nVehicle Model Access In order to facilitate the implementation, the whole vehicle is abstracted into model classes. Please check tutorial about creating models for more details about this topic. In this section, the focus is on using the model.\nThe first thing you need to do is to get access to the Vehicle Model. If you derived your project repository from our template, we already provide a generated model installed as a Python package named vehicle. Hence, in most cases no additional setup is necessary. How to tailor the model to your needs or how you could get access to vehicle services is described in the tutorial linked above.\nIf you want to access a single DataPoint e.g. for the vehicle speed, this can be done via\nvehicle_speed = (await self.Vehicle.Speed.get()).value As the get() method of the DataPoint-class there is a coroutine you have to use the await keyword when using it and access its .value.\nIf you want to get deeper inside the vehicle, to access a single seat for example, you just have to go the model-chain down:\nself.DriverSeatPosition = await self.Vehicle.Cabin.Seat.Row1.DriverSide.Position.get() Subscription to Data Points If you want to get notified about changes of a specific DataPoint, you can subscribe to this event, e.g. as part of the on_start() method in your app.\nasync def on_start(self): \"\"\"Run when the vehicle app starts\"\"\" await self.Vehicle.Cabin.Seat.Row1.DriverSide.Position.subscribe( self.on_seat_position_changed ) Every DataPoint provides a .subscribe() method that allows for providing a callback function which will be invoked on every data point update. Subscribed data is available in the respective DataPointReply object and need to be accessed via the reference to the subscribed data point. The returned object is of type TypedDataPointResult which holds the value of the data point and the timestamp at which the value was captured by the Databroker. Therefore the on_seat_position_changed callback function needs to be implemented like this:\nasync def on_seat_position_changed(self, data: DataPointReply): # handle the event here response_topic = \"seatadjuster/currentPosition\" position = data.get(self.Vehicle.Cabin.Seat.Row1.DriverSide.Position).value # ... Subscription using Annotations The Python SDK also supports annotations for subscribing to data point changes with @subscribe_data_points defined by the whole path to the DataPoint of interest. This would replace the implementation of the Subscription to Data Points @subscribe_data_points(\"Vehicle.Cabin.Seat.Row1.DriverSide.Position\") async def on_seat_position_changed(self, data: DataPointReply): response_topic = \"seatadjuster/currentPosition\" response_data = {\"position\": data.get(self.Vehicle.Cabin.Seat.Row1.DriverSide.Position).value} await self.publish_event(response_topic, json.dumps(response_data)) Similarly, subscribed data is available in the respective DataPointReply object and needs to be accessed via the reference to the subscribed data point.\nServices Services are used to communicate with other parts of the vehicle via remote function calls (RPC). Please read the basics about them here .\nNote Services are not supported by our automated vehicle model lifecycle for the time being. If you need access to services please read\nhere how you can create a model and add services to it manually.\nYou can ignore the following step if you would like to reach the final implementation of the example . The following code snippet shows how to use the MoveComponent() method of the SeatService from the vehicle model:\nlocation = SeatLocation(row=1, index=1) await self.vehicle_client.Cabin.SeatService.MoveComponent( location, BASE, data[\"position\"] ) In order to define which seat you like to move, you have to pass a SeatLocation object as the first parameter. The second argument specifies the component of the seat to be moved. The possible components are defined in the proto files. The last parameter to be passed into the method is the desired position of the component.\nMake sure to use the await keyword when calling service methods, since these methods are asynchronously working coroutines.\nMQTT Interaction with other Vehicle Apps or with the cloud is enabled by using the Mosquitto MQTT Broker. The MQTT broker runs inside a docker container, which is started as part of one of our predefined runtimes .\nIn the quickstart section about the Vehicle App, you already tested sending MQTT messages to the app. In the previous sections, you generally saw how to use Vehicle Models, DataPoints and Services. In this section, you will learn how to combine them with MQTT.\nIn order to receive and process MQTT messages inside your app, simply use the @subscribe_topic annotations from the SDK for an additional method on_set_position_request_received() you have to implement:\n@subscribe_topic(\"seatadjuster/setPosition/request\") async def on_set_position_request_received(self, data_str: str) -\u003e None: logger.info(f\"Got message: {data_str!r}\") data = json.loads(data_str) response_topic = \"seatadjuster/setPosition/response\" response_data = {\"requestId\": data[\"requestId\"], \"result\": {}} # ... The on_set_position_request_received method will now be invoked every time a message is published to the subscribed topic \"seatadjuster/setPosition/response\". The message data (string) is provided as parameter. In the example above the data is parsed from json (data = json.loads(data_str)).\nIn order to publish data to topics, the SDK provides the appropriate convenience method: self.publish_event() which will be added to the on_seat_position_changed callback function from before.\nasync def on_seat_position_changed(self, data: DataPointReply): response_topic = \"seatadjuster/currentPosition\" position = data.get(self.Vehicle.Cabin.Seat.Row1.DriverSide.Position).value await self.publish_event( response_topic, json.dumps({\"position\": position}), ) The above example illustrates how one can easily publish messages. In this case, every time the seat position changes, the new position is published to seatadjuster/currentPosition\nYour main.py should now have a full implementation for class MyVehicleApp(VehicleApp): containing:\n__init__() on_start() on_seat_position_changed() on_set_position_request_received() and last but not least a main() method to run the app.\nCheck the seat-adjuster example to see a more detailed implementation including error handling.\nUnitTests Unit testing is an important part of the development, so let’s have a look at how to do that. You can find some example tests in /app/tests/unit. First, you have to import the relevant packages for unit testing and everything you need for your implementation:\nfrom unittest import mock import pytest from sdv.vehicle_app import VehicleApp from sdv_model.Cabin.SeatService import SeatService # type: ignore from sdv_model.proto.seats_pb2 import BASE, SeatLocation # type: ignore @pytest.mark.asyncio async def test_for_publish_to_topic(): # Disable no-value-for-parameter, seems to be false positive with mock lib with mock.patch.object( VehicleApp, \"publish_event\", new_callable=mock.AsyncMock, return_value=-1 ): response = await VehicleApp.publish_event( str(\"sampleTopic\"), get_sample_request_data() # type: ignore ) assert response == -1 def get_sample_request_data(): return {\"position\": 330, \"requestId\": 123} Looking at a test you notice the annotation @pytest.mark.asyncio. This is required if the test is defined as a coroutine. The next step is to create a mock from all the external dependencies. The method takes 4 arguments: first is the object to be mocked, second the method for which you want to modify the return value, third a callable and the last argument is the return value. After creating the mock, you can test the method and check the response. Use asserts to make your test fail if the response does not match. Check the seat-adjuster unit tests to see a more detailed implementation.\nSee the results Once the implementation is done, it is time to run and debug the app.\nRun your App In order to run the app:\nMake sure the devenv-runtimes \u0026 devenv-devcontainer-setup packages are part of your .velocitas.json (which should be the default). Have a correctly configured app/AppManifest.json . See more Trigger our automated vehicle model lifecycle . (e. g. velocitas init) A runtime needs to be up and running. Read more about it in the run runtime services section. Now chose one of the options to start the VehicleApp under development:\nPress F5 or:\nPress F1 Select command Tasks: Run Task Select Local Runtime - Run VehicleApp Debug your Vehicle App In the introduction about debugging , you saw how to start a debugging session. In this section, you will learn what is happening in the background.\nThe debug session launch settings are already prepared for the VehicleApp in /.vscode/launch.json.\n{ \"configurations\": [ { \"type\": \"python\", \"justMyCode\": false, \"request\": \"launch\", \"name\": \"VehicleApp\", \"program\": \"${workspaceFolder}/app/src/main.py\", \"console\": \"integratedTerminal\", \"env\": { \"SDV_MIDDLEWARE_TYPE\": \"native\", \"SDV_VEHICLEDATABROKER_ADDRESS\": \"grpc://127.0.0.1:55555\", \"SDV_MQTT_ADDRESS\": \"mqtt://127.0.0.1:1883\" } } ] } We specify which python-script to run using the program key.\nYou can adapt the configuration in /.vscode/launch.json and in /.vscode/tasks.json to your needs (e.g., change the ports, add new tasks) or even add a completely new configuration for another Vehicle App.\nOnce you are done, you have to switch to the debugging tab (sidebar on the left) and select your configuration using the dropdown on the top. You can now start the debug session by clicking the play button or F5. Debugging is now as simple as in every other IDE, just place your breakpoints and follow the flow of your Vehicle App.\nNext steps Concept: SDK Overview Tutorial: Deploy runtime services in Kanto Tutorial: Start runtime services locally Tutorial: Creating a Python Vehicle Model Tutorial: Develop and run integration tests for a Vehicle App Concept: Deployment Model ","categories":"","description":"Learn how to develop and test a _Vehicle App_ using Python.\n","excerpt":"Learn how to develop and test a _Vehicle App_ using Python.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_app_development/python_development/","tags":"","title":"Python Vehicle App Development"},{"body":"This page describes\nhow to create a GitHub repository for your Vehicle App development, how to set up and configure the DevContainer-based development environment , and how to build, customize and test the sample Vehicle App included in your freshly created Vehicle App repository. You will learn how to use the Vehicle App SDK, interact with the Vehicle API and work with CI/CD using the pre-configured GitHub Workflows that come with the template repository.\nOnce you have completed all steps, you will have a solid understanding of the development workflow, and you will be able to use one of our template repositories as a starting point for your own Vehicle App development project.\nNote Before you start, we recommend familiarizing yourself with our Basic Concept to understand all mentioned terms.\nPrerequisites Please make sure you did all the prerequisite steps to create comprehensive development environment for your Vehicle App:\nInstall VS Code Install a working container runtime Add the Remote-Containers extension to VS Code via the marketplace or using the command line:\ncode --install-extension ms-vscode-remote.remote-containers How to create your Vehicle App repository? For your (GitHub) organization and Vehicle App repository the name MyOrg/MyFirstVehicleApp is used as a place holder during the rest of the document.\nYou can create your own repository using one of our provided templates or start prototyping via digital.auto.\nUsing Template Velocitas CLI create digital.auto Create your own repository copy from the template repository of your choice:\nPython C++ by clicking the green button Use this template. You don’t have to include all branches. For more information on Template Repositories take a look at this GitHub Tutorial .\nCreate your Vehicle App project via our Velocitas CLI create command from within vehicle-app-template’s devcontainer:\nvelocitas create interactive mode. velocitas create -n MyApp -l python for a skeleton vehicle application. velocitas create -n MyApp -l python -e seat-adjuster for a vehicle application based on the seat adjuster example . To learn how to start prototyping with the playground of digital.auto and integrate it into Velocitas please take a look here .\nHow to start developing? In this section you will learn different possibilities to start developing based on your repository. Basically you can work on your own machine using VS Code’s DevContainer or you can set up the environment on a remote agent, using GitHub Codespaces .\nVS Code GitHub Codespaces The VS Code DevContainer makes it possible to package a complete Vehicle App development environment, including VS Code extensions, Vehicle App SDK , Vehicle App Runtimes and all other development and testing tools into a container which is started directly in VS Code.\nProxy Configuration\nA non proxy configuration is used by default. If you are working behind a corporate proxy you will need to specify proxy settings: Working behind a proxy\nWith following steps you will clone and set up your development environment on your own machine using VS Code.\nClone created MyOrg/MyFirstVehicleApp repository locally using your favorite Git tool Switch the directory to the cloned repository folder, e.g. $ cd MyFirstVehicleApp Open the repository in VS Code via $ code . or via VS Code user interface . A popup appears in the lower right corner with the button Reopen in Container. Click on Reopen in Container. If the popup does not appear, you can also hit F1 and perform the command Dev-Containers: Reopen in Container Wait for the container to be set up The first initializing of the container will take some minutes to build the image and provision all the integrated tools.\nIf the DevContainer build process fails, press F1 and run the command Dev-Containers: Rebuild Container Without Cache. The DevContainer is using the docker-in-docker feature to run docker containers within the container.\nOne of the possibilities to use your newly created repository is to use it inside a GitHub Codespace . You can either try it out directly in the browser or also use it inside VS Code. The main thing to remember is that everything is executed on a remote agent and the browser or VS Code just acts as a “thin-client”.\nTo get started with GitHub Codespaces, you just have to follow a few steps:\nOpen your repository on GitHub (e.g. https://github.com/MyOrg/MyFirstVehicleApp ) Click on the green Code button and select Codespaces on the top Configure your Codespace if needed (defaults to the main branch and a standard agent) Click on create A new window will open where you can see logs for setting up the container. On this window you could now also choose to work with VS Code. The environment remains on a remote agent and VS Code establishes a connection to this machine.\nOnce everything is set up in the Codespace, you can work with it in the same way as with the normal DevContainer inside VS Code.\nBe careful with using GitHub Codespaces in a browser and VS Code locally at the same time: Tasks that are started using a browser session will not show in VS Code environment and vice versa. This might lead to problems.\nYou can find more information about the Vehicle App development in the respective pages .\nHow to start the runtime services? The runtime services (like KUKSA Databroker or Vehicle Services) are required to develop Vehicle Apps and run integration tests.\nCurrently, the supported options to run these services is either locally or via the Kanto runtime .\nLocal Runtime Kanto Runtime A VS Code task called Local Runtime - Up is available to start all necessary services in the correct order.\nPress F1 Select command Tasks: Run Task Select Local Runtime - Up You should see the task Local Runtime - Up being executed on a separate VS Code terminal with the following content:\n$ velocitas exec runtime-local up Hint: Log files can be found in your workspace's logs directory \u003e mqtt-broker running \u003e vehicledatabroker running \u003e seatservice running \u003e feedercan running ✅ Runtime is ready to use! To stop the runtime simply press Ctrl + C.\nA VS Code task called Kanto Runtime - Up is available to start all necessary services in the correct order.\nPress F1 Select command Tasks: Run Task Select Kanto Runtime - Up You should see the task Kanto Runtime - Up being executed on a separate VS Code terminal with the following content:\n$ velocitas exec runtime-kanto up Hint: Log files can be found in your workspace's logs directory \u003e Checking Kanto registry... registry already exists. \u003e Checking Kanto registry... starting registry. \u003e Checking Kanto registry... started. ✅ Configuring controlplane for Kanto... ⠇ Starting Kanto...waiting ✅ Kanto is ready to use! To stop the runtime simply press Ctrl + C or execute the task Kanto Runtime - Down.\nMore information about the runtimes are available here .\nHow to debug your Vehicle App? Warning Debugging functionality is only available when using the Local Runtime . Both given examples are available as part of template.\nNow that the runtime services are all up and running, let’s start a debug session for the Vehicle App.\nPython C++ Open the main source file /app/src/main.py and set a breakpoint in the given method on_get_speed_request_received Press F5 to start a debug session of the Vehicle App and see the log output on the DEBUG CONSOLE To trigger this breakpoint, let’s send a message to the Vehicle App using the mqtt broker that is running in the background.\nOpen VSMqtt extension in VS Code and connect to mosquitto (local) Set Subscribe Topic = sampleapp/getSpeed/response and click subscribe Set Publish Topic = sampleapp/getSpeed Press publish with an empty payload field. Open the main source file /app/src/VehicleApp.cpp and set a breakpoint in the given method onSetPositionRequestReceived Press F5 to start a debug session of the Vehicle App and see the log output on the DEBUG CONSOLE To trigger this breakpoint, let’s send a message to the Vehicle App using the mqtt broker that is running in the background.\nOpen VSMqtt extension in VS Code and connect to mosquitto (local) Set Subscribe Topic = seatadjuster/setPosition/response and click subscribe Set Subscribe Topic = seatadjuster/currentPosition and click subscribe Set Publish Topic = seatadjuster/setPosition/request Set and publish a dummy payload: { \"position\": 300, \"requestId\": 123 } Now your breakpoint in the Vehicle App gets hit and you can inspect everything in your debug session. After resuming execution (F5), a response from your Vehicle App is published to the response topic. You can see the response in the MQTT window.\nHow to trigger the CI Workflow? The provided GitHub workflows are used to build the container image for the Vehicle App, run unit and integration tests and collect the test results.\nThe CI Workflow will be triggered by pushing a change to the main branch of your repository:\nMake modification in any of your files\nNavigate in your terminal to your repository\nCommit and push your change\ngit add . git commit -m \"\u003cexplain your changes\u003e\" git push origin To see the results open the Actions page of your repository on GitHub, go to CI Workflow and check the workflow output.\nHow to release your Vehicle App? Now that the CI Workflow was successful, you are ready to build your first release. The goal is to build a ready-to-deploy container image that is published in the GitHub container registry.\nOpen the Code page of your repository on GitHub Click on Create a new release in the Releases section on the right side Enter a version (e.g. v1.0.0) and click on Publish release GitHub will automatically create a tag using the version number The provided release workflow will be triggered by the release. It creates a release documentation and publishes the container image of the Vehicle App to the GitHub container registry. A detailed description of the workflow can be found here .\nHow to deploy your Vehicle App? After releasing the Vehicle App to the GitHub container registry you might ask how to bring the Vehicle App and the required runtime stack on a device. Here, Eclipse Leda comes into the game.\nPlease read the documentation of Eclipse Leda to get more information.\nNext steps Tutorial: Creating a Vehicle Model Tutorial: Create a Vehicle App Tutorial: Develop and run integration tests for a Vehicle App ","categories":"","description":"Learn how to setup and explore the provided development environment.\n","excerpt":"Learn how to setup and explore the provided development environment.\n","ref":"/velocitas-docs/docs/tutorials/quickstart/quickstart/","tags":"","title":"Quickstart"},{"body":"In the scenario of a car sharing company, the goal is to provide the functionality of automatically adjusting the driver’s seat position based on their preferred settings stored in their profile. When the driver unlocks the car, a request is sent to the vehicle to retrieve the preferred seat position. This is where your implementation begins.\nThe Seat Adjuster Vehicle App receives a MQTT message containing the seat position, which then triggers a seat adjustment command through the Seat Service to change the seat position. Additionally, to ensure convenience for future trips, the car sharing company saves the driver’s preferred seat position and utilizes it accordingly. The Seat Adjuster Vehicle App subscribes to the seat position, receiving updates from the Databroker, which streams data from the Seat Service.\nRequesting new seat position The Customer requests the change of the seat position as MQTT message on the topic seatadjuster/setPosition/request with the payload:\n{\"requestId\": 42, \"position\": 300} The Seat Adjuster Vehicle App that has subscribed to this topic, receives the request to change the seat position as a MQTT message.\nThe Seat Adjuster Vehicle App gets the current vehicle speed from the Databroker, which is fed by the CAN Provider (KUKSA CAN Provider).\nWith the support of the Vehicle App SDK, the Seat Adjuster Vehicle App triggers a seat adjustment command of the Seat Service via gRPC in the event that the speed is equal to zero. Hint: This is a helpful convenience check but not a safety check.\nThe Seat Service moves the seat to the new position via CAN messages.\nThe Seat Service returns OK or an error code as gRPC status to the Seat Adjuster Vehicle App.\nIf everything went well, the Seat Adjuster Vehicle App returns a success message for the topic seatadjuster/setPosition/response with the payload:\n{\"requestId\": 42, \"status\": 0 } Otherwise, an error message will be returned:\n{\"requestId\": 42, \"status\": 1, \"message\": \"\u003cerror message\u003e\" } This success or error message will be returned to the Customer.\nPublishing current seat position If the seat position will be changed by the driver, the new seat position will be sent to the Seat Service via CAN.\nThe Seat Service streams the seat position via gRPC to the KUKSA Databroker since it was registered beforehand.\nThe Seat Adjuster Vehicle App that subscribed to the seat position receives the new seat position from the KUKSA Databroker as a result.\nThe Seat Adjuster Vehicle App publishes this on topic seatadjuster/currentPosition with the payload:\n{\"position\": 350} The Customer who has subscribed to this topic retrieves the new seat position and can store this position to use it for the next trip.\nExample Code You can find an example implementation of a Seat Adjuster Vehicle App here: Seat Adjuster ","categories":"","description":"Provides option to request a new seat position and to publish the current seat position\n","excerpt":"Provides option to request a new seat position and to publish the …","ref":"/velocitas-docs/docs/about/use_cases/seat_adjuster/","tags":"","title":"Seat Adjuster"},{"body":"Overview After you have set up the .velocitas.json for your project configuration , using packages is pretty straight forward.\nCurrently, the packages provided by the Velocitas team are the following: name description devenv-runtimes Containing scripts and configuration for Local and Kanto Runtime Services devenv-devcontainer-setup Basic configuration for the devcontainer, like proxy configuration, post create scripts, entry points for the lifecycle management. devenv-github-workflows Containing github workflow files used by velocitas repositories devenv-github-templates Containing github templates used by velocitas repositories devenv-runtime-local Central configuration for local runtime execution (deprecated) devenv-runtime-k3d Central configuration for k3d runtime execution (deprecated) To see how these provided packages are used inside a .velocitas.json you can use the Python template repository as a reference.\nInstallation The Velocitas CLI - acting as a package manager for Vehicle App repositories - is installed inside our devcontainer-base-images . After creation of a devcontainer a postCreateCommand is configured to be executed which runs:\nvelocitas init which will initialize all packages referenced in your .velocitas.json. That means, it will download them and run their respective onPostInit programs, if any. (e.g, automated model generation ) velocitas sync to sync files provided by some packages. Check the section about our Velocitas CLI to learn more about the background and usage of it.\nVelocitas Home Directory The packages will be downloaded by the Velocitas CLI to ~/.velocitas/packages/\u003cpackage_name\u003e. More Information: VELOCITAS_HOME .\nNext steps Lifecycle Management: Development of Packages Lifecycle Management: Velocitas CLI ","categories":"","description":"Learn how to use velocitas packages.\n","excerpt":"Learn how to use velocitas packages.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/packages/usage/","tags":"","title":"Usage"},{"body":"Velocitas offers a scalable and modular development toolchain for creating containerized Vehicle Apps that offers an easy to use, fast and efficient development experience to increase the velocity of your development team.\nVehicle Apps are implemented on top of a Vehicle Model (which is generated from the underlying semantic models like VSS for a concrete programming language) and its underlying language-specific SDK to provide headless comfort functions or connected application functions like Seat Adjuster, Dog Mode, Trunk Delivery or Data Logging \u0026 triggering.\nExamples ","categories":"","description":"Is Velocitas for me? How does Velocitas help?\n","excerpt":"Is Velocitas for me? How does Velocitas help?\n","ref":"/velocitas-docs/docs/about/use_cases/","tags":"","title":"Use Cases"},{"body":"This guide will help you to import examples provided by the SDK package into your template repository.\nA Visual Studio Code task called Import example app from SDK is available in the /.vscode/tasks.json which can replace your /app directory in your template repository with some example Vehicle Apps from the SDK package.\nTo avoid overwriting existing changes in your /app directory, commit or stash changes before importing the example app. Press F1 Select command Tasks: Run Task Select Import example app from SDK Choose Continue without scanning the output Select seat-adjuster Run the Vehicle App from SDK example The launch settings are already prepared for the VehicleApp in the template repository /.vscode/launch.json. The configuration is meant to be as generic as possible to make it possible to run all provided example apps.\nEvery example app comes with its own /app/AppManifest.json to see which Vehicle Services are configured and needed as a dependency.\nTo start the app: Just press F5 to start a debug session of the example Vehicle App.\nTo debug example, please check How to debug Vehicle App? ","categories":"","description":"Learn how to import examples provided by the _Vehicle App_ SDK.\n","excerpt":"Learn how to import examples provided by the _Vehicle App_ SDK.\n","ref":"/velocitas-docs/docs/tutorials/quickstart/import_examples/","tags":"","title":"Import examples"},{"body":"The Dog Mode Vehicle App consists of the following key features:\nRequest the vehicle’s Heating, Ventilation, and Air Conditioning (HVAC) service to turn the Air Conditioning (AC) ON/OFF The driver can adjust the temperature for a specific degree The Vehicle App observe the current temperature and the battery’s state of charge and react accordingly The driver/owner will be notified whenever the state of the charge drops below a certain value Example Code You can find an example implementation of a dog mode Vehicle App here: Dog Mode ","categories":"","description":"Climate control app that allows drivers to leave their vehicles while keeping the air conditioning system of the vehicle active for their pets.\n","excerpt":"Climate control app that allows drivers to leave their vehicles while …","ref":"/velocitas-docs/docs/about/use_cases/dog_mode/","tags":"","title":"Dog Mode"},{"body":"In the past the recommended runtime would for sure be Docker Desktop . But since Docker Inc. changed their license model it is fair enough for an open source project to look for free alternatives.\nLinux The obvious (and our recommended) “alternative” to Docker Desktop on Linux is to just use the Docker Engine (without Docker Desktop), a pure CLI-based solution available for most popular Linux distributions licensed under the Apache License, version 2.0. Installation instructions can be found here .\nMacOS Since the Docker Engine is not working out of the box on MacOS, a virtualizations tool which helps emulating linux is needed. Fortunately there are several solutions on the market. Good results could be achieved using Colima .\nSetup Colima Please uninstall or at least quit Docker Desktop if you already used it, before starting the setup.\nFor Colima to work properly you need Colima itself and a container client e.g. the Docker client, which is still free to use:\nbrew install colima brew install docker After the installation you need to start the runtime:\ncolima start --cpu x --memory y For M1 Macs it might be necessary to add --arch aarch64\nDocker Desktop uses 5 cores and 12 GB of RAM by default on an M1 MacBook Pro. The equivalent in Colima can be achieved with\ncolima start --cpu 5 --memory 12 That’s all you have to do. After these few steps you can go on with the devcontainer setup.\nMicrosoft Windows There is currently no recommended alternative for Windows except using GitHub codespaces, a cloud-based development environment.\nAn option would be to setup a VM (e.g. with VirtualBox or VMWare) running a Linux system with Docker Engine (see above).\nOther alternatives Besides our recommendations above, there are further alternatives, which are not yet evaluated by this project or have some other drawbacks, blocking a recommendation.\nFor example, you could try Podman / Buildah , which can replace docker run and docker build, respectively. Podman is available for MacOS, Windows, and several Linux distributions. Buildah seems just being available for several Linux distributions.\n","categories":"","description":"Overview about the setup of tested container runtimes\n","excerpt":"Overview about the setup of tested container runtimes\n","ref":"/velocitas-docs/docs/tutorials/quickstart/container_runtime/","tags":"","title":"Install a working container runtime"},{"body":"We know what a pain and how time consuming it can be to setup your environment behind a cooperate proxy. This guide will help you to set it up correctly.\nBe aware that correct proxy configuration depends on the setup of your organization and of course of your personal development environment (hardware, OS, virtualization setup, …). So, we most probably do not cover all issues out there in the developers world. So, we encourage you to share hints and improvements with us.\nHTTP(s) proxy server Install and configure the proxy server as recommended or required by your company. For example you could use PX , which is a HTTP(s) proxy server that allows applications to authenticate through an NTLM or Kerberos proxy server, typically used in corporate deployments, without having to deal with the actual handshake. Px leverages Windows SSPI or single sign-on and automatically authenticates using the currently logged in Windows user account. It is also possible to run Px on Windows, Linux and MacOS without single sign-on by configuring the domain, username and password to authenticate with. (Source: PX )\nInstall your HTTP(s) proxy server Start your HTTP(s) proxy server Docker Desktop You need to install Docker Desktop using the right version. As we recognized a proxy issue in Docker Desktop #12672 we strongly recommend to use a Docker Desktop version \u003e= 4.8.2. In case you have an older version on your machine please update to the current version.\nIn the next step you need to enter your proxy settings:\nOpen Docker Desktop and go to the Settings From Resources, select Proxies Enable Manual proxy configuration Enter your proxy settings, this depends on the configuration you did while setting up your proxy tool e.g.: Web Server (HTTP): http://localhost:3128 Secure Web Server (HTTPS): http://localhost:3128 Bypass: localhost,127.0.0.1 Apply \u0026 Restart. Docker daemon You also have to configure the Docker daemon, which is running the containers basically, to forward the proxy settings. For this you have to add the proxy configuration to the ~/.docker/config.json. Here is an example of a proper config (Port and noProxy settings might differ for your setup):\nWindows MacOS Linux { \"proxies\":{ \"default\":{ \"httpProxy\":\"http://host.docker.internal:3128\", \"httpsProxy\":\"http://host.docker.internal:3128\", \"noProxy\":\"host.docker.internal,localhost,127.0.0.1\" } } } { \"proxies\":{ \"default\":{ \"httpProxy\":\"http://host.docker.internal:3128\", \"httpsProxy\":\"http://host.docker.internal:3128\", \"noProxy\":\"host.docker.internal,localhost,127.0.0.1\" } } } { \"proxies\":{ \"default\":{ \"httpProxy\":\"http://172.17.0.1:3128\", \"httpsProxy\":\"http://172.17.0.1:3128\", \"noProxy\":\"host.docker.internal,localhost,127.0.0.1\" } } } For more details see: Docker Documentation Environment Variables It is required to set the following environment variables:\nHTTP_PROXY - proxy server, e.g. http://localhost:3128 HTTPS_PROXY - secure proxy server, e.g. http://localhost:3128 Windows MacOS Linux set setx HTTP_PROXY \"http://localhost:3128\" setx HTTPS_PROXY \"http://localhost:3128\" echo \"export HTTP_PROXY=http://localhost:3128\" \u003e\u003e ~/.bash_profile echo \"export HTTPS_PROXY=http://localhost:3128\" \u003e\u003e ~/.bash_profile source ~/.bash_profile echo \"export HTTP_PROXY=http://localhost:3128\" \u003e\u003e ~/.bash_profile echo \"export HTTPS_PROXY=http://localhost:3128\" \u003e\u003e ~/.bash_profile source ~/.bash_profile Troubleshooting Solving issues with TLS (SSL) certificate validation using https connections from containers If you are behind a so-called intercept proxy (which you most probably are), you can run into certificate issues: Your corporate proxy works as a “man-in-the-middle” to be able to check the transferred data for malicious content. Means, there is a protected connection between the application in your local runtime environment and the proxy and another from the proxy to the external server your application wants to interact with.\nFor the authentication corporate proxies often use self-signed certificates (certificates which are not signed by a (well-known official) certificate authority. Those kind of certificates need to be added to the database of trusted certificates of your local runtime environment. This task is typically handled by the IT department of your corporation (if the OS and software installed on it is managed by them) and you will not run into problems, normally.\nIf it comes to executing containers, those are typically not managed by your IT department and the proxy certificate(s) is/are missing. So, you need to find a way to install those into the (dev) container you want to execute.\nSee (one of) those articles to get how to achieve that:\nOvercoming Proxy Issues with Docker Containers Docker behind SSL intercepting proxy Initial DevContainer build issue If you experience issues during initial DevContainer build, clean all images and volumes otherwise cache might be used:\nOpen Docker Desktop From Troubleshooting choose Clean / Purge data GitHub rate limit exceeded How to fix can be found at Lifecycle Management Troubleshooting .\n","categories":"","description":"Learn how to setup your docker desktop and Visual Studio Code behind a corporate proxy.\n","excerpt":"Learn how to setup your docker desktop and Visual Studio Code behind a …","ref":"/velocitas-docs/docs/tutorials/quickstart/behind_proxy/","tags":"","title":"Working behind proxy"},{"body":" We recommend that you make yourself familiar with the Vehicle App SDK first, before going through this tutorial.\nThe following information describes how to develop and test the sample Vehicle App that is included in the C++ template repository . You will learn how to use the Vehicle App C++ SDK and how to interact with the Vehicle Model.\nOnce you have completed all steps, you will have a solid understanding of the development workflow and you will be able to reuse the template repository for your own Vehicle App development project.\nDevelop your first Vehicle App This section describes how to develop your first Vehicle App. Before you start building a new Vehicle App, make sure you have already read this manual:\nQuickstart For this tutorial, you will recreate the Vehicle App that is included in the template repository : The Vehicle App allows you to change the position of the driver’s seat in the car and also provides its current positions to other applications. A detailed explanation of the use case and the example is available here .\nSetting up the basic skeleton of your app At first, you have to create the main C++ file which we will call App.cpp in /app/src. All the relevant code for your new Vehicle App goes there. Afterwards, there are several steps you need to consider when developing the app:\nManage your includes Initialize your class Define the entry point of your app Manage your includes Before you start development in the App.cpp you just created, it will be necessary to include all required header files, which you will understand better later through the development:\n#include \"sdk/VehicleApp.h\" #include \"sdk/IPubSubClient.h\" #include \"sdk/IVehicleDataBrokerClient.h\" #include \"sdk/Logger.h\" #include \"vehicle/Vehicle.hpp\" #include \u003cmemory\u003e using namespace velocitas; Initialize your class The main class of your new Vehicle App needs to inherit the VehicleApp provided by the C++ SDK .\nclass MyVehicleApp : public VehicleApp { public: // \u003cremaining code in this tutorial goes here\u003e private: vehicle::Vehicle Vehicle; // this member exists to provide simple access to the vehicle model } In your constructor, you have to choose which implementations to use for the VehicleDataBrokerClient and the PubSubClient. By default we suggest you use the factory methods to generate the default implementations: IVehicleDataBrokerClient::createInstance and IPubSubClient::createInstance. These will create a VehicleDataBrokerClient which connects to the VAL via gRPC and an MQTT-based pub-sub client.\nMyVehicleApp() : VehicleApp(IVehicleDataBrokerClient::createInstance(\"vehicledatabroker\"), // this is the app-id of the KUKSA Databroker in the VAL. IPubSubClient::createInstance(\"MyVehicleApp\")) // the clientId identifies the client at the pub/sub broker {} {} Note The URI of the MQTT broker is by default localhost:1883 and can be set to another address via the environment variable SDV_MQTT_ADDRESS (beginning with C++ SDK v0.3.3) or MQTT_BROKER_URI (SDKs before v0.3.3). Now, you have initialized the app and can continue developing relevant methods.\nEntry point of your app Here’s an example of an entry point to the MyVehicleApp that we just developed:\nint main(int argc, char** argv) { MyVehicleApp app; app.run(); return 0; } With this your app can now be started. In order to provide some meaningful behaviour of the app, we will enhance it with more features in the next sections.\nVehicle Model Access In order to facilitate the implementation, the whole set of vehicle signals is abstracted into model classes. Please check the tutorial about creating models for more details. In this section, the focus is on using the model.\nThe first thing you need to do is to get access to the Vehicle Model. If you derived your project repository from our template, we already provide a generated model as a Conan source package. The library is already referenced as “include folder” in the CMake files. Hence, in most cases no additional setup is necessary. How to tailor the model to your needs or how you could get access to vehicle services is described in the tutorial linked above. In your source code the model is included via #include \"vehicle/Vehicle.hpp\" (as shown above).\nIf you want to read a single signal/data point e.g. for the vehicle speed, the simplest way is to do it via a blocking call and directly accessing the value of the speed:\nauto vehicleSpeed = Vehicle.Speed.get()-\u003eawait().value(); Lets have a look, what this line contains:\nThe term Vehicle.Speed addresses the signal we like to query, i.e. the current speed of the vehicle. The term .get() tells that we want to get/read the current state of that signal from the Data Broker. Behind the scenes this triggers a request-response flow via IPC with the Data Broker. The term -\u003eawait() blocks the execution until the response was received. Finally, the term .value() tries to access the returned speed value. The get() returns a shared_ptr to an AsyncResult which, as the name implies, is the result of an asynchronous operation. We have two options to access the value of the asynchronous result. First we can use await() and block the calling thread until a result is available or use onResult(...) which allows us to inject a function pointer or a lambda which is called once the result is available:\nVehicle.Speed.get() -\u003eonResult([](auto vehicleSpeed){ logger().info(\"Got speed!\"); }) -\u003eonError(auto status){ logger().info(\"Something went wrong communicating to the data broker!\"); }); If you want to get deeper inside to the vehicle, to access a single seat for example, you just have to go the model-chain down:\nauto driverSeatPosition = Vehicle.Cabin.Seat.Row1.Pos1.Position.get()-\u003eawait(); Class TypedDataPointValue If you have a detailed look at the AsyncResult class, you will observe that the object returned by the await() or passed to the onResult callback is not directly the current value of the signal, but instead an object of type TypedDataPointValue. This object does not only contain the current value of the signal but also some additional metadata accessible via these functions:\ngetPath() provides the signal name, i.e. the complete path, getType() provides the data type of the signal, getTimeStamp() provides the timestamp when the current state was received by the data broker, isValid() returns true if the current state represents a valid value of the signal or false otherwise, getFailure() returns the reason, why the current state does not represent a valid value (it returns NONE if the value is valid), getValue() returns the a valid current value. It will throw an InvalidValueException if the current value is invalid for whatever reason. The latter three points lead us to the next chapter.\nFailure Handling As indicated above, there might be reasons/situations why the get operation is not able to deliver a valid value for the requested signal. Those shall be handled properly by any application (that wants “to be more” than a prototype).\nThere are two ways to handle the failure situations:\nEither you can catch the exception thrown by the .value() function: try { auto vehicleSpeed = Vehicle.Speed.get()-\u003eawait().value(); // use the speed value } catch (AsyncException\u0026 e) { // thrown by the await(): Something went wrong on communication level with the data broker } catch (InvalidValueException\u0026 e) { // thrown by .value(): The vehicle speed signal does not contain a valid value, currently } Throwing the InvalidValueException can be avoided if you first check that .isValid() returns true before calling .value(): auto vehicleSpeed = Vehicle.Speed.get()-\u003eawait(); if (vehicleSpeed.isValid()) // Accessing .value() now wont throw an exception auto speed = vehicleSpeed.value() ... } else { // Do your failure handling here switch (vehicleSpeed.getFailure()) { case Failure::INVALID_VALUE: ... break; case ... default: ... } } (isValid() is a convenience function for checking .getFailure() == Failure::NONE.)\nNote If you use the asynchroneous variant, the callback passed to onError is just called to report errors on communication level with the data broker. The validity of the returned signal’s/data point’s value needs to be checked separatly (e.g. via ‘isValid()’)! Failure Reasons There are two levels where errors accessing signal/data points might occure.\nCommunication with the Data Broker (IPC Level) The data broker might be (temporarly) unavailable because\nit’s not yet started up, temporary “stopped” due to a crash or a “live update”, some temporary network issues (if running on a different hardware node), … Errors on the IPC level between the application and the data broker will be reported either via\nan AsyncException thrown by the await() function of the AsyncResult class or calling the function passed to the onError function of the AsyncResult/AsyncSubscription class. Errors on this level always make the overall call fail: If getting/setting multiple data points in a single call, the overall operation will fail. In case of setting multiple signals/data points, this means that none of the signals/data points are set. In case of an error on a subscription, this means that the overall subscription could not be established or is terminated now.\nSignal / Data Point Level Failures on signal/data point level are always reported individually per signal/data point. If accessing multiple signals/data points in a single call, getting or setting some certain signal might be successfully done but another one will report an error or failure.\nThe reasons why a valid value of signal/data point can be missing are explained here: Reported failure Reason Explanation Failure::UNKNOWN_DATAPOINT The addressed signal/data point is “unknown” on the system. This can be a hint for a misconfiguration of the overall system, because no provider is installed in that system which will provide this signal. It can be acceptable, if an application does just “optionally” require access to that signal and would work properly without it being present. Failure::ACCESS_DENIED The application does not have the necessary access rights to the addressed signal/data point. This can be a hint for a misconfiguration of the overall system, but could be also a “normal” situation if the user of the vehicle blocks access to certain signals for that application. Failure::NOT_AVAILABLE The addressed signal/data point is temporary not available. This is a normal situation which will arise, while the provider of that signal is - not yet started up or has not yet passed a value to the data broker, - temporary “stopped” due to a crash or a “live update”, - some temporary network issues (e.g. if the provider is running on a different hardware node), - … Failure::INVALID_VALUE The addressed signal/data point might currently not represent a valid value. This situation means, that the signal is currently provided but just the value itself is not representable, e.g. because the hardware sensor delivers implausible values. Failure::INTERNAL_ERROR The value is missing because of some internal issue in the data broker. This typically points out some misbehaviour within the broker’s implementation - call it “bug”. Failure::NONE No failure state - a valid value is provided. This “failure” reason is used to represent a signal state where a valid value is provided. It is the application developer’s decision if it makes sense to distinguish between the different failure reasons or if some or all of them can be handled as “just one”.\nSubscription to DataPoints If you want to get notified about changes of a specific DataPoint, you can subscribe to this event, e.g. as part of the onStart() method in your app:\nvoid onStart() override { subscribeDataPoints(QueryBuilder::select(Vehicle.Cabin.Seat.Row1.Pos1.Position).build()) -\u003eonItem([this](auto\u0026\u0026 item) { onSeatPositionChanged(std::forward\u003cdecltype(item)\u003e(item)); }) -\u003eonError([this](auto\u0026\u0026 status) { onError(std::forward\u003cdecltype(status)\u003e(status)); }); } void onSeatPositionChanged(const DataPointsResult\u0026 result) { const auto dataPoint = result.get(Vehicle.Cabin.Seat.Row1.Pos1.Position); logger().info(dataPoint-\u003evalue()); // do something with the data point value } The VehicleApp class provides the subscribeDataPoints() method which allows to listen for changes on one or multiple data points. Once a change in any of the data points is registered, the callback registered via AsyncSubscription::onItem() is called. Conversely, the callback registered via AsyncSubscription::onError() is called once there is an error during communication with the KUKSA Databroker.\nThe result passed to the callback registered via onItem() is an object of type DataPointsResult which holds the current state of all data points that were part of the respective subscription. The state of individual data points can be accessed by their reference: result.get(Vehicle.Cabin.Seat.Row1.Pos1.Position))\nNote If you select multiple signals/data points in a single subscription be aware that:\nThe update notification will not only contain those data points whose states were updated, but the state of all data points selected in the belonging subscription. If you don’t want this behaviour, you must subscribe to change notifications for each signal/data point separately. A possible failure state will be reported individually per signal/data point. The reason is, that each signal/data point might come from a different provider, has individual access rights and individual reasons to become invalid. This is also true, if requesting multiple signal/data point states via a single get call. Services Services are used to communicate with other parts of the vehicle via remote procedure calls (RPC). Please read the basics about them here .\nNote This description is outdated!\nServices were not supported by our automated vehicle model lifecycle for some time and could be made available via the\ndescription how you can create a model and add services to it manually.\nIn-between we provide a way to refer gRPC based services by referencing the required proto files from the AppManifest and auto-generated the language-specific stubs. The necessary steps need being described here.\nThe following code snippet shows how to use the moveComponent() method of the SeatService from the vehicle model:\nvehicle::cabin::SeatService::SeatLocation location{1, 1}; Vehicle.Cabin.SeatService.moveComponent( location, vehicle::cabin::SeatService::Component::Base, 300 )-\u003eawait(); In order to define which seat you like to move, you have to pass a SeatLocation object as the first parameter. The second argument specifies the component of the seat to be moved. The possible components are defined in the proto-files. The last parameter to be passed into the method is the final position of the component.\nMake sure to call the await() method when calling service methods or register a callback via onResult() otherwise you don’t know when your asynchronous call will finish.\nMQTT Interaction with other Vehicle Apps or with the cloud is enabled by using the Mosquitto MQTT Broker. When using the provided template repository you can start a MQTT Broker as part the local runtime. More information can be found here .\nIn the quickstart section about the Vehicle App, you already tested sending MQTT messages to the app. In the previous sections, you generally saw how to use Vehicle Models, DataPoints and GRPC Services. In this section, you will learn how to combine them with MQTT.\nIn order to receive and process MQTT messages inside your app, simply use the VehicleApp::subscribeTopic(\u003ctopic\u003e) method provided by the SDK:\nvoid onStart() override { subscribeTopic(\"seatadjuster/setPosition/request\") -\u003eonItem([this](auto\u0026\u0026 item){ onSetPositionRequestReceived(std::forward\u003cdecltype(item)\u003e(item);)}); } void onSetPositionRequestReceived(const std::string\u0026 data) { const auto jsonData = nlohmann::json::parse(data); const auto responseTopic = \"seatadjuster/setPosition/response\"; nlohmann::json respData({{\"requestId\", jsonData[\"requestId\"]}, {\"result\", {}}}); } The onSetPositionRequestReceived method will now be invoked every time a message is created on the subscribed topic seatadjuster/setPosition/response. The message data is provided as a string parameter. In the example above the data is parsed to json (data = json.loads(data_str)).\nIn order to publish data to other subscribers, the SDK provides the appropriate convenience method: VehicleApp::publishToTopic(...)\nvoid MyVehicleApp::onSeatPositionChanged(const DataPointsResult\u0026 result): const auto responseTopic = \"seatadjuster/currentPosition\"; nlohmann::json respData({\"position\": result.get(Vehicle.Cabin.Seat.Row1.Pos1.Position)-\u003evalue()}); publishToTopic( responseTopic, respData.dump(), ); The above example illustrates how one can easily publish messages. In this case, every time the seat position changes, the new position is published to seatadjuster/currentPosition\nSee the results Once the implementation is done, it is time to run and debug the app.\nBuild your App Before you can run the Vehicle App you need to build it first. To do so, simply run the provided build.sh script found in the root of the SDK. It does accept some arguments, but that is out of scope for this tutorial.\nWarning If this is your first time building, you might have to run install_dependencies.sh first. Run your App In order to run the app make sure the devenv-runtimes package is part of your .velocitas.json (which should be the default) and the runtime is up and running. Read more about it in the run runtime services section.\nNow chose one of the options to start the VehicleApp under development:\nPress F5 or:\nPress F1 Select command Tasks: Run Task Select Local Runtime - Run VehicleApp Debug your Vehicle App In the introduction about debugging , you saw how to start a debugging session. In this section, you will learn what is happening in the background.\nThe debug session launch settings are already prepared for the VehicleApp.\n{ \"configurations\": [ { \"name\": \"VehicleApp - Debug (Native)\", \"type\": \"cppdbg\", \"request\": \"launch\", \"program\": \"${workspaceFolder}/build/bin/app\", \"args\": [ ], \"stopAtEntry\": false, \"cwd\": \"${workspaceFolder}\", \"environment\": [ { \"name\": \"SDV_MIDDLEWARE_TYPE\", \"value\": \"native\" }, { \"name\": \"SDV_VEHICLEDATABROKER_ADDRESS\", \"value\": \"127.0.0.1:55555\" }, { \"name\": \"SDV_MQTT_ADDRESS\", \"value\": \"127.0.0.1:1883\" } ], \"externalConsole\": false, \"MIMode\": \"gdb\", \"setupCommands\": [ ], } ] } We specify which binary to run using the program key. In the environment you can specify all needed environment variables. You can adapt the JSON to your needs (e.g., change the ports, add new tasks) or even add a completely new configuration for another Vehicle App.\nOnce you are done, you have to switch to the debugging tab (sidebar on the left) and select your configuration using the dropdown on the top. You can now start the debug session by clicking the play button or F5. Debugging is now as simple as in every other IDE, just place your breakpoints and follow the flow of your Vehicle App.\nNext steps Concept: SDK Overview Concept: Deployment Model Tutorial: Deploy runtime services in Kanto Tutorial: Start runtime services locally Tutorial: Creating a Vehicle Model Tutorial: Develop and run integration tests for a Vehicle App ","categories":"","description":"Learn how to develop and test a _Vehicle App_ using C++.\n","excerpt":"Learn how to develop and test a _Vehicle App_ using C++.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_app_development/cpp_development/","tags":"","title":"C++ Vehicle App Development"},{"body":"Getting started First thing you need to do is to create a repository at e.g., https://github.com/my-organisation/my-velocitas-package. The URL needs to be referenced in the .velocitas.json of your Vehicle App repository.\nGeneral configuration of Packages Every Package repository needs a manifest.json at their root. The manifest.json is the package configuration and holds package relevant information and its behaviour.\nHere are examples of this configuration:\ndevenv-runtimes manifest devenv-devcontainer-setup manifest The manifest of a package describes a list of components. They are a collection of programs or files that serve a similar purpose or are inheritly connected. I.e. they provide a single runtime, a deployment for a runtime or add configuration required for Github Workflows or the devcontainer. More detailed information and explanation about configuration fields of the manifest.json and package development can be found here .\nConfiguration of Runtime Packages If you want to add a new service, adapt runtime.json and manifest.json . In order to use a newly created or updated service, new changes on devenv-runtimes need to be tagged and referenced inside .velocitas.json of the respective package version via a tag or branch name of the repository. When a version is changed in your .velocitas.json you have to initialize it through velocitas init from the terminal so the new package version will be installed. A new service can be started by using velocitas cli command velocitas exec runtime-local \u003cservice_id\u003e \u003cargs\u003e which can be also configured inside your ./.vscode/tasks.json.\nIf you plan to develop a Package with the purpose of managing the runtime used together with your Vehicle App the package needs a runtime.json at their root. The runtime.json is the runtime configuration containing all information for the relevant service dependencies with the following three required attributes:\nProperty Description id unique service id interfaces used for dependency resolution between Vehicle App and runtime config configurations in form of Key/Value pair with specific pre–defined keys and corresponding values Supported config keys of a service Key Value Description image URI of a container image port port number port-forward port mapping for forwarding env environment variable used by the service: \u003cenv_key\u003e=\u003cenv_value\u003e mount path for mounting files: \u003csource_path\u003e:\u003ctarget_path\u003e arg argument for starting the service start-pattern optional start pattern for identifying if the service starts correctly Runtime configuration helper { \"id\": \"\u003cservice_id\u003e\", \"interfaces\": [ \"\u003cinterface\u003e\" ], \"config\": [ { \"key\": \"image\", \"value\": \"\u003cimage\u003e:\u003ctag\u003e\" }, { \"key\": \"port\", \"value\": \"\u003cport_number\u003e\" }, { \"key\": \"port-forward\", \"value\": \"\u003csource_port\u003e:\u003ctarget_port\u003e\" }, { \"key\": \"env\", \"value\": \"\u003cenv_key\u003e=\u003cenv_value\u003e\" }, { \"key\": \"mount\", \"value\": \"\u003csource_path\u003e:\u003ctarget_path\u003e\" }, { \"key\": \"arg\", \"value\": \"\u003carg\u003e\" }, { \"key\": \"start-pattern\", \"value\": \".*Listening on \\\\d+\\\\.\\\\d+\\\\.\\\\d+\\\\.\\\\d+:\\\\d+\" } ] } In order to use a newly created or updated service, changes on the respective Package need to be tagged and referenced inside the .velocitas.json of your Vehicle App repository via a tag or branch name of the repository. More info about installation: Usage .\nNote A new service can be started manually and/or configured inside your ./.vscode/tasks.json with: velocitas exec runtime-\u003cruntime\u003e \u003cservice_id\u003e \u003cargs\u003e Next steps Lifecycle Management: Velocitas CLI ","categories":"","description":"Learn how to develop an own package.\n","excerpt":"Learn how to develop an own package.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/packages/development/","tags":"","title":"Development"},{"body":"Services can make sure, that when you write a VSS data point, something is actually happening. Eclipse Velocitas has an example seat or hvac service. If your Vehicle App makes use of e.g. Vehicle.Cabin.Seat.Row1.Pos1.Position or other seat/hvac specific data points you are in for some real action. To learn more, visit Vehicle Services .\nOur maintained devenv-runtimes package ( Velocitas Lifecycle Management ) comes with the support of adding further Vehicle Services to the runtime.json of a package. More information here .\nModify existing services For more advanced usage you can also try to modify existing services. Check out the seat service for example, modify it and integrate it into your Vehicle App repository.\nCreate your own services If you want to create your own service the KUKSA Incubation repository contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to KUKSA listening to changes of a target value of some VSS data point and then do whatever you want. You can achieve this by using the KUKSA gRPC API with any programming language of your choice (learn more about gRPC ).\nMock Provider and Mock Provider Integration The Vehicle Mock Provider is a dummy service allowing to control all specified actuator- and sensor-signals via a configuration file. These configuration files are expressed in a Python-based domain-specific language (DSL). The default behavior is predefined in mock.py The Mock Provider is already integrated in all our Vehicle Runtimes . To be able to configure it, you need to add a custom mock.py in the root of your Vehicle App Project. The Mock Provider Container will pick it up automatically.\n","categories":"","description":"Learn how to integrate a _Vehicle Service_ that executes the request of your _Vehicle App_ on vehicle side\n","excerpt":"Learn how to integrate a _Vehicle Service_ that executes the request …","ref":"/velocitas-docs/docs/tutorials/prototyping/service_integration/","tags":"","title":"Service Integration"},{"body":"The Velocitas development model is centered around what are known as Vehicle Apps . Automation allows engineers to make high-impact changes frequently and deploy Vehicle Apps through cloud backends as over-the-air updates. The Vehicle App development model is about speed and agility paired with state-of-the-art software quality.\nDevelopment Architecture Velocitas provides a flexible development architecture for Vehicle Apps . The following diagram shows the major components of the Velocitas stack.\nVehicle Apps The Vehicle Applications (Vehicle Apps) contain the business logic that needs to be executed on a vehicle. A Vehicle App is implemented on top of a Vehicle Model and its underlying language-specific SDK . Many concepts of cloud-native and twelve-factor applications apply to Vehicle Apps as well and are summarized in the next chapter.\nVehicle Models A Vehicle Model makes it possible to easily get vehicle data from the Databroker and to execute remote procedure calls over gRPC against Vehicle Services and other Vehicle Apps . It is generated from the underlying semantic models for a concrete programming language as a graph-based, strongly-typed, intellisense-enabled library. The elements of the vehicle models are defined by the SDKs .\nSDKs Our SDKs, available for different programming languages, are the foundation for the vehicle abstraction provided by the vehicle model Furthermore, they offer abstraction from the underlying middleware and communication protocols, besides providing the base classes and utilities for the Vehicle Apps. SDKs are available for Python and C++, currently. Further SDKs for Rust and C are planned.\nVehicle Services Vehicle Services provide service interfaces to control actuators or to trigger (complex) actions. E.g. they communicate with the vehicle internal networks like CAN or Ethernet, which are connected to actuators, electronic control units (ECUs) and other vehicle computers (VCs). They may provide a simulation mode to run without a network interface. Vehicle services may feed data to the Databroker and may expose gRPC endpoints, which can be invoked by Vehicle Apps over a Vehicle Model .\nKUKSA Databroker Vehicle data is stored in the KUKSA Databroker conforming to an underlying Semantic Model like VSS . Vehicle Apps can either pull this data or subscribe for updates. In addition, it supports rule-based access to reduce the number of updates sent to the Vehicle App.\nSemantic models The Vehicle Signal Specification ( VSS ) provides a domain taxonomy for vehicle signals and defines the vehicle data semantically, which is exchanged between Vehicle Apps and the Databroker.\nThe Velocitas SDK is using VSS as the semantic model for the Vehicle Model. Vehicle Service models can be defined with Protobuf service definitions .\nCommunication Protocols Asynchronous communication between Vehicle Apps and other vehicle components, as well as cloud connectivity, is facilitated through MQTT messaging. Direct, synchronous communication between Vehicle Apps , Vehicle Services and the Databroker is based on the gRPC protocol.\nMiddleware Abstraction Velocitas basically provides middleware abstraction interfaces for service discovery, pubsub messaging, and other cross-cutting functionalites. At the moment, Velocitas just offers a (what we call) “native middleware” implementation, which does not provide (gRPC) service discovery. Instead, addresses and port number of services need to be provided via environment variables to an app; e.g. SDV_VEHICLEDATABROKER_ADDRESS=grpc://localhost:55555. The support of Dapr as middleware has recently been removed.\nVehicle Edge Operating System Vehicle Apps are expected to run on a Linux -based operating system. An OCI-compliant container runtime is required to host the Vehicle App containers. For publish/subscribe messaging a MQTT broker must be available (e.g., Eclipse Mosquitto ).\nVehicle App Characteristics The following aspects are important characteristics for Vehicle Apps :\nCode base: Every Vehicle App is stored in its own repository. Tracked by version control, it can be deployed to multiple environments.\nPolyglot: Vehicle Apps can be written in any programming language. System-level programming languages like Rust and C/C++ are particularly relevant for limited hardware resources found in vehicles, but higher-level languages like Python and JavaScript are also considered for special use cases.\nOCI-compliant containers: Vehicle Apps are deployed as OCI-compliant containers. The size of these containers should be minimal to fit on constrained devices.\nIsolation: Each Vehicle App should execute in its own process and should be self-contained with its interfaces and functionality exposed on its own port.\nConfigurations: Configuration information is separated from the code base of the Vehicle App, so that the same deployment can propagate across environments with their respective configuration applied.\nDisposability: Favor fast startup and support graceful shutdowns to leave the system in a correct state.\nObservability: Vehicle Apps provide traces, metrics and logs of every part of the application using Open Telemetry.\nOver-the-air update capability: Vehicle Apps can be deployed via cloud backends like Pantaris and updated in vehicles frequently over the air through NextGen OTA updates .\nDevelopment Process The starting point for developing Vehicle Apps is a Semantic Model of the vehicle data and vehicle services. Based on the Semantic Model, language-specific Vehicle Models are generated. Vehicle Models are then distributed as packages to the respective package manager of the chosen programming language (e.g. pip, cargo, npm, …).\nAfter a Vehicle Model is available for the chosen programming language, the Vehicle App can be developed using the generated Vehicle Model and its SDK.\nFurther information ","categories":"","description":"Learn more about provided development model for _Vehicle Apps_.\n","excerpt":"Learn more about provided development model for _Vehicle Apps_.\n","ref":"/velocitas-docs/docs/concepts/development_model/","tags":"","title":"Development Model"},{"body":"The Velocitas project provides a two-stage process for development, continuous integration, and release of a new version of a Vehicle App.\nStage 1 - Build \u0026 Test On every new push to the main branch or every update to a pull request, a GitHub workflow is automatically executed to build your application as a container (optionally for different platforms), runs automated tests and code quality checks, and stores all results as GitHub artifacts for future reference with a default retention period of 90 days .\nThe workflow provides a quick feedback during development and improves efficient collaboration.\nStage 2 - Release Once the application is ready to be released in a new version, a dedicated release workflow is automatically executed as soon as you create a new release via GitHub.\nThe release workflow bundles all relevant images and artifacts into one tagged set of files and pushes it to the GitHub Container Registry. In addition, all the information needed for quality assurance and documentation are published as release artifacts on GitHub. The image pushed to the GitHub Container Registry can afterwards be deployed on your target system using the Over-The-Air (OTA) update system of your choice.\nThe drawing below illustrates the different workflows, actions and artifacts that are automatically created for you. All workflows are intended as a sensible baseline and can be extended and adapted to the needs of your own project.\nCI Workflow ( ci.yml ) The Continuous Integration (CI) workflow is triggered on every commit to the main branch or when creating/updating a pull request and contains a set of actions to achieve the following objectives:\nBuilding a container for the Vehicle App - actions create a containerized version of the Vehicle App. Scanning for vulnerabilities - actions scan your code and container for vulnerabilities and in case of findings the workflow will be marked as “failed”. Running integration tests - actions provision a runtime instance and deploy all required services as containers together with your containerized application to allow for automatically executing integration test cases. In case the test cases fail, the workflow will be marked as “failed”. Running unit tests \u0026 code coverage - actions run unit tests and calculate code coverage for your application, in case of errors or unsatisfactory code coverage, the workflow will be marked as “failed”. Storing scan \u0026 test results as GitHub action artifacts - actions store results from the previously mentioned actions for further reference or download as Github Action Artifacts. Check out the example GitHub workflows in our template repository for Python Build multi-arch image Workflow ( build-multiarch-image.yml ) The Build multi-arch image workflow is triggered on every commit to the main branch and contains a set of actions to achieve the following objectives:\nBuilding a multi-arch container for the app - actions create a containerized version of the Vehicle App for multiple architectures (currently AMD64 and ARM64). Scanning for vulnerabilities - actions scan your code and container for vulnerabilities and in case of findings the workflow will be marked as “failed”. Storing container images to GitHub action artifacts - at the end of the workflow, the container image created is stored in a Github Action Artifacts so that it can be referenced by the Release Workflow later. Release Workflow ( release.yml ) The Release workflow is triggered as soon as the main branch is ready for release and the Vehicle App developer creates a new GitHub release. This can be done manually through the GitHub UI.\nOn creating a new release with a specific new version, GitHub creates a tag and automatically runs the Release workflow defined in .github/workflows/release.yml, given that CI workflow has run successfully for the current commit on the main branch.\nThe set of actions included in the Release workflow cover the objective:\nGenerating and publishing QA information - actions load the QA information from GitHub artifacts stored for the same commit reference and verify it. Additionally, release documentation is generated and added to the GitHub release. If there is no information available for the current commit, the release workflow will fail. Publish as GitHub pages - all information from the release together with the project documentation is built as a static page using hugo. The result is pushed to a separate branch and can be published as a GitHub page in your repository. Pull \u0026 label container image - actions pull the Vehicle App container image based on the current commit hash from the GitHub artifacts and label it with the specified tag version. If the image cannot be found, the workflow will fail. Push container image to ghcr.io - finally the labeled container image is pushed to the GitHub container registry and can be used as a deployment source. GitHub Actions artifacts GitHub Actions artifacts are used for storing data, which is generated by the CI workflow and referenced by the Release workflow. This saves time during workflow runs because we don’t have to create artifacts multiple times.\nGitHub Actions artifacts always have a retention period, which is 90 days by default. This may be configured differently in the specific GitHub organization. After this period, the QA info gets purged automatically. In this case, a re-run of the CI workflow would be required to regenerate all QA info needed for creating a release.\nContainer Registry The GitHub container registry is used for storing container images pushed by the Release workflow. These images can easily be used for a deployment and don’t have a retention period. Since the registry does not have an automatic cleanup, it keeps container images as long as they are not deleted. It is recommended that you automate the removal of older images to limit storage size and costs.\nVersioning Vehicle App image versions are set to the Git tag name during release. Though any versioning scheme can be adopted, the usage of semantic versions is recommended.\nIf the tag name contains a semantic version, the leading v will be trimmed. Example: A tag name of v1.0.0 will lead to version 1.0.0 of the Vehicle App container.\nMaintaining multiple versions If there is a need to maintain multiple versions of a Vehicle App, e.g., to hotfix the production version while working on a new version at the same time or to support multiple versions in production, create and use release branches.\nThe release process would be the same as described in the overview, except that a release branch (e.g., release/v1.0) is created before the release step and the GitHub release is based on the release branch rather than the main branch. For hotfixes, release branches may be created retroactively from the release tag, if needed.\nFurther information Tutorial: How to write integration tests ","categories":"","description":"Learn more about the provided continuous integration, and release process of a _Vehicle App_.\n","excerpt":"Learn more about the provided continuous integration, and release …","ref":"/velocitas-docs/docs/concepts/deployment_model/vehicle_app_releases/","tags":"","title":"Build and Release Process"},{"body":"The Velocitas project uses a common deployment model. It uses OCI-compliant containers to increase the flexibility for the support of different programming languages and runtimes, which accelerates innovation and development. OCI-compliant containers also allow for a standardized yet flexible deployment process, which increases the ease of operation. Using OCI-compliant is portable to different architectures as long as there is support for OCI-compliant containers on the desired platform (e.g., like a container runtime for arm32, arm64 or amd64).\nGuiding principles The deployment model is guided by the following principles\nApplications are provided as OCI-compliant container images. The container runtime offers a control plane and API to manage the container lifecycle. The template projects provided come with a pre-configured developer toolchain that accelerates the development process. The developer toolchain ensures an easy creation through a high-degree of automation of all required artifacts needed to follow the Velocitas principles.\nTesting your container during development The Velocitas project provides for developers a repository template and devcontainer that contains everything to build a containerized version of your app locally and test it. Check out our tutorial e.g., for the Python template to learn more.\nAutomated container image builds Velocitas uses GitHub workflows to automate the creation of your containerized application. A workflow is started with every increment of your application code that you push to your GitHub repository. The workflow creates a containerized version of your application and stores this container image in a registry. Further actions are carried out using this container (e.g., integration tests).\nThe workflows are set up to support multi-platform container creation and generate container images for amd64 and arm64 out of the box. This provides a great starting point for developers and lets you add additional support for further platforms easily.\nFurther information ","categories":"","description":"Learn more about our deployment model and guiding principles.\n","excerpt":"Learn more about our deployment model and guiding principles.\n","ref":"/velocitas-docs/docs/concepts/deployment_model/","tags":"","title":"Deployment Model"},{"body":"\nRepository Description vehicle-app-python-template GitHub Template repository contains an exemplary Vehicle App that uses an exemplary SDK to provide access to vehicle data points and methods. The sample SDK extends the sdv-vehicle-app-python-sdk. In addition the template repository contains the development environment for Visual Studio Code for a Vehicle App as well as the CI/CD workflows that can be used as blueprint for your own Vehicle App written in Python. vehicle-app-python-sdk Provides basic functionality to write a SDK to allow access to vehicle data points and method. This includes publishing \u0026 subscribe messaging, VehicleApp API, vehicle data model ontology and function-based query \u0026 rule support. vehicle-model-python Basic vehicle model for Python is generated from VSS with addition of some specialized vehicle services. vehicle-app-cpp-template GitHub Template repository contains an exemplary Vehicle App that uses an exemplary SDK to provide access to vehicle data points and methods. The sample SDK extends the sdv-vehicle-app-cpp-sdk. In addition the template repository contains the development environment for Visual Studio Code for a Vehicle App as well as the CI/CD workflows that can be used as blueprint for your own Vehicle App written in C++. vehicle-app-cpp-sdk Provides basic functionality to write a SDK to allow access to vehicle data points and method. This includes publishing \u0026 subscribe messaging, VehicleApp API, vehicle data model ontology and function-based query \u0026 rule support. vehicle-model-cpp Basic vehicle model for C++ is generated from VSS with addition of some specialized vehicle services. kuksa-databroker Is a part of the Vehicle Abstraction Layer (VAL) of the Eclipse KUKSA project and provides the KUKSA Databroker. The KUKSA Databroker offers data points available in the vehicle to the Vehicle Apps semantically aligned to a data model like the Vehicle Signal Specification (VSS) . kuksa-can-provider The KUKSA CAN Provider is a generic data feeder that reads data from the vehicle’s CAN bus defined by a DBC file, maps them to a set of data points (e.g. according to the VSS) and feeds it into the Databroker. kuksa-incubation Provides exemplary vehicle services and respective implementations that illustrates how to interact with in-vehicle components and services via an unified access. release-documentation-action GitHub Action to generate a release documentation from the CI workflow output by rendering it to markdown files so that this can be easily published with GitHub Pages. license-check GitHub Action to collect the licenses of the used components and can be configured to fail with an error message on invalid licenses. vehicle-model-generator Provides basic functionality to create a vehicle model from the given vspec specification for the target programming cli The CLI implements Velocitas lifecyle management concept of the development environment of a Vehicle App. It allows us to take care of the development environment while you focus on the business logic of your Vehicle App. devcontainer-base-images Central configuration to create base docker images for specific languages to be used in devcontainer Package Repositories Repository Description devenv-runtimes Central configuration for maintained runtime services devenv-devcontainer-setup Central configuration for setting up devcontainer environment devenv-github-workflows Central configuration for syncing github workflows devenv-github-templates Central configuration for syncing github templates devenv-runtime-local Central configuration for local runtime execution (deprecated) devenv-runtime-k3d Central configuration for k3d runtime execution (deprecated) ","categories":"","description":"The repositories of the Eclipse _Velocitas_ and their relations between each other\n","excerpt":"The repositories of the Eclipse _Velocitas_ and their relations …","ref":"/velocitas-docs/docs/about/repository-overview/","tags":"","title":"Repository Overview"},{"body":" Providing CLI package Interface type-key devenv-devcontainer-setup vehicle-signal-interface The Vehicle Signal Interface formerly known as Vehicle Model interface type creates an interface to a signal interface described by the VSS spec. This interface will generate a source code package equivalent to the contents of your VSS JSON automatically upon devContainer creation.\nIf a Vehicle App requires a vehicle-signal-interface, it will act as a consumer of datapoints already available in the system. If, on the other hand, a Vehicle App provides a vehicle-signal-interface, it will act as a provider (formerly feeder in KUKSA terms) of the declared datapoints.\nFurthermore, in the source code generated by this functional interface, a connection to KUKSA Databroker will be established via the configured Velocitas middleware. It uses the broker.proto if provided by the KUKSA Databroker to connect via gRPC. A seperate declaration of a grpc-interface for the databroker is NOT required.\nMore information: Vehicle Model Creation Configuration structure Attribute Type Example value Description src string \"https://github.com/COVESA/vehicle_signal_specification/releases/download/v3.0/vss_rel_3.0.json\" URI of the used COVESA Vehicle Signal Specification JSON export. URI may point to a local file or to a file provided by a server. unit_src string [\"abs_path_unit_file_1\", \"abs_path_unit_file_2\", \"uri_unit_file_3\"] An array of URI’s/absolute path’s of the used COVESA Vehicle Signal Specification unit file(s) in yaml format. URI may point to a local file or to a file provided by a server. If none is provided a default one will be used ( https://github.com/COVESA/vehicle_signal_specification/blob/v4.0/spec/units.yaml) . datapoints object Object containing both required and provided datapoints. datapoints.required array Array of required datapoints. datapoints.required.[].path string Vehicle.Speed Path of the VSS datapoint. datapoints.required.[].optional boolean? true, false Is the datapoint optional, i.e. can the Vehicle App work without the datapoint being present in the system. Defaults to false. datapoints.required.[].access string read, write What kind of access to the datapoint is needed by the application. datapoints.provided array Array of provided datapoints. datapoints.provided.[].path string Vehicle.Cabin.Seat.Row1.Pos1.Position Path of the VSS datapoint. Example { \"type\": \"vehicle-signal-interface\", \"config\": { \"src\": \"https://github.com/COVESA/vehicle_signal_specification/releases/download/v3.0/vss_rel_3.0.json\", \"datapoints\": { \"required\": [ { \"path\": \"Vehicle.Speed\", \"access\": \"read\" }, { \"path\": \"Vehicle.Body.Horn.IsActive\", \"optional\": true, \"access\": \"write\" } ], \"provided\": [ { \"path\": \"Vehicle.Cabin.Seat.Row1.Pos1.Position\" } ] } } } Different VSS versions The model generation is supported for VSS versions up to v4.0. There are some changes for some paths from v3.0 to v4.0. For example Vehicle.Cabin.Seat.Row1.Pos1.Position in v3.0 is Vehicle.Cabin.Seat.Row1.DriverSide.Position in v4.0. If you are using the mock provider you would need to take that into account when you sepcify your mock.py.\n","categories":"","description":"The functional interface for providing vehicle signal access via VSS specification.\n","excerpt":"The functional interface for providing vehicle signal access via VSS …","ref":"/velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/interfaces/vehicle_signal_interface/","tags":"","title":"Vehicle Signal Interface"},{"body":"","categories":"","description":"Learn more about logical interfaces.\n","excerpt":"Learn more about logical interfaces.\n","ref":"/velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/interfaces/","tags":"","title":"Interfaces"},{"body":" Info This article describes our new model lifecycle approach released on Friday, 2023-03-03. With that, the model is now automatically generated with the instantiation of the devContainer. It is generated from the vehicle model source file referenced in the AppManifest.\nFor the time being, the integration of services is not supported by the new approach.\nThe previous approach, using pre-generated model repositories, is now deprecated. But it is still available and described here .\nThis tutorial will show you how:\nthe vehicle API used as the source to generate the model is referenced in the app manifest, the automatic generation of the model works, you can trigger manual recreation of the model (after adding extensions to the API required by your project) How to Reference a Model Specification The model specification defines the vehicle API to be used by your project. It is referenced in the AppManifest.json via a URI or local file path like this:\nURI reference Local file reference \"vehicleModel\": { \"src\": \"\u003chttps://github.com/COVESA/vehicle_signal_specification/releases/download/v3.0/vss_rel_3.0.json\u003e\" } \"vehicleModel\": { \"src\": \"./my_model/my_model.json\" } Info The reference must point to a JSON file containing the model specification as VSS vspec. References to a VSS .vspec file hierarchy are not supported as of now. Model Creation The generation of the model is taking place:\nthrough a onPostInit hook when velocitas init is called: either triggered manually or automatically during the instantiation of the devContainer through our Velocitas Lifecycle Management , or when you trigger the VS Code task (Re-)generate vehicle model explicitly. The model generation is a three step process:\nThe model generator is installed as a Python package (if not already present) The referenced model specification is downloaded (if no local reference) The model code is generated and installed. The model is generated using our Velocitas vehicle-model-generator . The used version and also the repository of the generator can be altered via the variables section of the project configuration in the .velocitas.json. The default values for those are defined in the manifest.json of the devContainer setup package . Also, the target folder for the generated model source code is specified here:\n{ \"variables\": { \"modelGeneratorGitRepo\": \"https://github.com/eclipse-velocitas/vehicle-model-generator.git\", \"modelGeneratorGitRef\": \"v0.3.0\", \"generatedModelPath\": \"./gen/vehicle_model\" } } In Python template based projects the generated model is finally installed in the site-packages folder, while in C++ projects it is made available as a CMake include folder.\nFurther information Concept: SDK Overview Tutorial: Quickstart Tutorial: Create a Vehicle App ","categories":"","description":"Learn how to refer a model source and how the automated model lifecycle is working.\n","excerpt":"Learn how to refer a model source and how the automated model …","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/automated_model_lifecycle/","tags":"","title":"Automated Vehicle Model Lifecycle"},{"body":"Every Vehicle App repo comes with a .velocitas.json which is the project configuration of your app. It holds references to the packages and their respective versions as well as components you are using in your project.\nHere is an example of this configuration:\n{ \"packages\": { \"devenv-runtimes\": \"v3.1.0\", \"devenv-devcontainer-setup\": \"v2.1.0\" }, \"components\": [ \"runtime-local\", \"devcontainer-setup\", \"vehicle-signal-interface\", \"sdk-installer\", \"grpc-interface-support\" ], \"variables\": { \"language\": \"python\", \"repoType\": \"app\", \"appManifestPath\": \"app/AppManifest.json\", \"githubRepoId\": \"eclipse-velocitas/vehicle-app-python-template\", \"generatedModelPath\": \"./gen/vehicle_model\" }, \"cliVersion\": \"v0.9.0\" } More detailed information and explanation about the project configuration and fields of the .velocitas.json can be found here .\nNext steps Lifecycle Management: Usage of Packages Lifecycle Management: Development of Packages ","categories":"","description":"Learn everything about Velocitas project configuration.\n","excerpt":"Learn everything about Velocitas project configuration.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/project_configuration/","tags":"","title":"Project Configuration"},{"body":"Problem Currently, the development of in-vehicle applications (Vehicle Apps) can be excessively complex and challenging:\nMany time-consuming steps involved from setting up the development environment to the deployment of a Vehicle App.\nUnderstanding the vehicle’s E/E architecture details and specific API requires expert knowledge.\nPorting a Vehicle App to another vehicle platform is complex.\nSpecific processes, methods, and tools within each company creates challenges for effective collaboration.\nSolution The solution would be a development toolchain for creating vehicle-independent applications with:\nUsage of standardized vehicle APIs.\nEnabling portability through containerized Vehicle Apps with no dependencies to E/E architecture.\nPre-configured project setup​.\nSpeeding up the development by reducing complexity focus on differentiating business logic to innovate quickly.\nProduct Eclipse Velocitas™ is an open source project providing an end-to-end, scalable and modular development tool chain to create containerized Vehicle Apps, offering a comfortable, fast and efficient development experience to increase the speed of a development team (velocity).\nFeatures Project lifecycle management to update Vehicle App repositories via CLI. Vehicle abstraction support helps to focus on business logic by using a generated vehicle model on code level with type safety and auto-completion. The vehicle model is generated from a standardized API that hides the details of vehicle-specific signals and E/E architecture, allowing Vehicle Apps to be portable across different electronics and software architectures. Microsoft Visual Studio Code integration with DevContainer helps to install everything required to start the local development immediately, while tasks and launch configurations help to launch runtime services, other apps, and tests. Vehicle App skeleton and examples helps to understand easily how to write a Vehicle App using the KUKSA runtime services. Ready-to-use CI/CD workflows that build (for multi architectures), test, document and deploy a containerized Vehicle App with no dependencies to E/E architecture help saving setup time. Language Support Feature Python C++ Project lifecycle management + + Vehicle abstraction support + + Visual Studio Code integration + + Vehicle App skeleton and examples + + CI/CD workflows + + Unit test support + + Integration test support + digital.auto integration + Concepts ","categories":"","description":"Explore the goal, benefits and basic concepts of Eclipse _Velocitas™_\n","excerpt":"Explore the goal, benefits and basic concepts of Eclipse _Velocitas™_\n","ref":"/velocitas-docs/docs/about/","tags":"","title":"About Velocitas"},{"body":"This provides a style guide for .proto files. By following these conventions, you’ll make your protocol buffer message definitions and their corresponding classes consistent and easy to read. Unless otherwise indicated, this style guide is based on the style guide from google protocol-buffers style under Apache 2.0 License \u0026 Creative Commons Attribution 4.0 License.\nNote that protocol buffer style can evolve over time, so it is likely that you will see .proto files written in different conventions or styles. Please respect the existing style when you modify these files. Consistency is key. However, it is best to adopt the current best style when you are creating a new .proto file.\nStandard file formatting Keep the line length to 80 characters. Use an indent of 2 spaces. Prefer the use of double quotes for strings. File structure Files should be named lower_snake_case.proto\nAll files should be ordered in the following manner:\nLicense header File overview Syntax Package Imports (sorted) File options Everything else Directory Structure Files should be stored in a directory structure that matches their package sub-names. All files in a given directory should be in the same package. Below is an example based on the proto files in the kuksa.-databroker repository.\n| proto/ | └── sdv | └── databroker | └── v1 // package sdv.databroker.broker.v1 | ├── broker.proto // service Broker in sdv.databroker.broker.v1 | ├── collector.proto // service Collector in sdv.databroker.broker.v1 | └── types.proto // type definition and import of in sdv.databroker.broker.v1 The proposed structure shown above is adapted from Uber Protobuf Style Guide V2 under MIT License.\nPackages Package names should be in lowercase. Package names should have unique names based on the project name, and possibly based on the path of the file containing the protocol buffer type definitions.\nMessage and field names Use PascalCase (CamelCase with an initial capital) for message names – for example, SongServerRequest. Use underscore_separated_names for field names (including oneof field and extension names) – for example, song_name.\nmessage SongServerRequest { optional string song_name = 1; } Using this naming convention for field names gives you accessors like the following:\nC++:\nconst string\u0026 song_name() { ... } void set_song_name(const string\u0026 x) { ... } If your field name contains a number, the number should appear after the letter instead of after the underscore. For example, use song_name1 instead of song_name_1 Repeated fields\nUse pluralized names for repeated fields.\nrepeated string keys = 1; ... repeated MyMessage accounts = 17; Enums Use PascalCase (with an initial capital) for enum type names and CAPITALS_WITH_UNDERSCORES for value names:\nenum FooBar { FOO_BAR_UNSPECIFIED = 0; FOO_BAR_FIRST_VALUE = 1; FOO_BAR_SECOND_VALUE = 2; } Each enum value should end with a semicolon, not a comma. The zero value enum should have the suffix UNSPECIFIED.\nServices If your .proto defines an RPC service, you should use PascalCase (with an initial capital) for both the service name and any RPC method names:\nservice FooService { rpc GetSomething(GetSomethingRequest) returns (GetSomethingResponse); rpc ListSomething(ListSomethingRequest) returns (ListSomethingResponse); } GRPC Interface Versioning All API interfaces must provide a major version number, which is encoded at the end of the protobuf package. If an API introduces a breaking change, such as removing or renaming a field, it must increment its API version number to ensure that existing user code does not suddenly break. Note: The use of the term “major version number” above is taken from semantic versioning. However, unlike in traditional semantic versioning, APIs must not expose minor or patch version numbers. For example, APIs use v1, not v1.0, v1.1, or v1.4.2. From a user’s perspective, minor versions are updated in place, and users receive new functionality without migration.\nA new major version of an API must not depend on a previous major version of the same API. An API may depend on other APIs, with an expectation that the caller understands the dependency and stability risk associated with those APIs. In this scenario, a stable API version must only depend on stable versions of other APIs.\nDifferent versions of the same API should preferably be able to work at the same time within a single client application for a reasonable transition period. This time period allows the client to transition smoothly to the newer version. An older version must go through a reasonable, well-communicated deprecation period before being shut down.\nFor releases that have alpha or beta stability, APIs must append the stability level after the major version number in the protobuf package.\nRelease-based versioning An individual release is an alpha or beta release that is expected to be available for a limited time period before its functionality is incorporated into the stable channel, after which the individual release will be shut down. When using release-based versioning strategy, an API may have any number of individual releases at each stability level.\nAlpha and beta releases must have their stability level appended to the version, followed by an incrementing release number. For example, v1beta1 or v1alpha5. APIs should document the chronological order of these versions in their documentation (such as comments). Each alpha or beta release may be updated in place with backwards-compatible changes. For beta releases, backwards-incompatible updates should be made by incrementing the release number and publishing a new release with the change. For example, if the current version is v1beta1, then v1beta2 is released next.\nAdapted from google release-based_versioning under Apache 2.0 License \u0026 Creative Commons Attribution 4.0 License\nBackwards compatibility The gRPC protocol is designed to support services that change over time. Generally, additions to gRPC services and methods are non-breaking. Non-breaking changes allow existing clients to continue working without changes. Changing or deleting gRPC services are breaking changes. When gRPC services have breaking changes, clients using that service have to be updated and redeployed.\nMaking non-breaking changes to a service has a number of benefits:\nExisting clients continue to run. Avoids work involved with notifying clients of breaking changes, and updating them. Only one version of the service needs to be documented and maintained. Non-breaking changes These changes are non-breaking at a gRPC protocol level and binary level.\nAdding a new service Adding a new method to a service Adding a field to a request message - Fields added to a request message are deserialized with the default value on the server when not set. To be a non-breaking change, the service must succeed when the new field isn’t set by older clients. Adding a field to a response message - Fields added to a response message are deserialized into the message’s unknown fields collection on the client. Adding a value to an enum - Enums are serialized as a numeric value. New enum values are deserialized on the client to the enum value without an enum name. To be a non-breaking change, older clients must run correctly when receiving the new enum value. Binary breaking changes The following changes are non-breaking at a gRPC protocol level, but the client needs to be updated if it upgrades to the latest .proto contract. Binary compatibility is important if you plan to publish a gRPC library.\nRemoving a field - Values from a removed field are deserialized to a message’s unknown fields. This isn’t a gRPC protocol breaking change, but the client needs to be updated if it upgrades to the latest contract. It’s important that a removed field number isn’t accidentally reused in the future. To ensure this doesn’t happen, specify deleted field numbers and names on the message using Protobuf’s reserved keyword. Renaming a message - Message names aren’t typically sent on the network, so this isn’t a gRPC protocol breaking change. The client will need to be updated if it upgrades to the latest contract. One situation where message names are sent on the network is with Any fields, when the message name is used to identify the message type. Nesting or unnesting a message - Message types can be nested. Nesting or unnesting a message changes its message name. Changing how a message type is nested has the same impact on compatibility as renaming. Protocol breaking changes The following items are protocol and binary breaking changes:\nRenaming a field - With Protobuf content, the field names are only used in generated code. The field number is used to identify fields on the network. Renaming a field isn’t a protocol breaking change for Protobuf. However, if a server is using JSON content, then renaming a field is a breaking change. Changing a field data type - Changing a field’s data type to an incompatible type will cause errors when deserializing the message. Even if the new data type is compatible, it’s likely the client needs to be updated to support the new type if it upgrades to the latest contract. Changing a field number - With Protobuf payloads, the field number is used to identify fields on the network. Renaming a package, service or method - gRPC uses the package name, service name, and method name to build the URL. The client gets an UNIMPLEMENTED status from the server. Removing a service or method - The client gets an UNIMPLEMENTED status from the server when calling the removed method. Behavior breaking changes When making non-breaking changes, you must also consider whether older clients can continue working with the new service behavior. For example, adding a new field to a request message:\nIsn’t a protocol breaking change. Returning an error status on the server if the new field isn’t set makes it a breaking change for old clients. Behavior compatibility is determined by your app-specific code.\nAdapted from Versioning gRPC services under Creative Commons Attribution 4.0 License\ngRPC Error Handling In gRPC, a large set of error codes has been defined As a general rule, SDV should use relevant gRPC error codes, as described in this thread return grpc::Status(grpc::StatusCode::NOT_FOUND, \"error details here\"); Available constructor:\ngrpc::Status::Status ( StatusCode code, const std::string \u0026 error_message, const std::string \u0026 error_details The framework for drafting error messages could be useful as a later improvement. This could e.g., be used to specify which unit created the error message and to assure the same structure on all messages. The latter two may e.g., depend on debug settings, e.g., error details only in debug-builds to avoid leaks of sensitive information. A global function like below or similar could handle that and also possibly convert between internal error codes and gRPC codes.\ngrpc::Status status = CreateStatusMessage(PERMISSION_DENIED,\"DataBroker\",\"Rule access rights violated\"); SDV error handling for gRPC interfaces (e.g., VAL vehicles services) Use gRPC error codes as base Document in proto files (as comments) which error codes that the service implementation can emit and the meaning of them. (Errors that only are emitted by the gRPC framework do not need to be listed.) Do not - unless there are special reasons - add explicit error/status fields to rpc return messages. Additional error information can be given by free text fields in gRPC error codes. Note, however, that sensitive information like Given password ABCD does not match expected password EFGH should not be passed in an unprotected/unencrypted manner. SDV handling of gRPC error codes The table below gives error code guidelines for each gRPC on:\nIf it is relevant for a client to retry the call or not when receiving the error code. Retry is only relevant if the error is of a temporary nature. When to use the error code when implementing a service. gRPC error code Retry Relevant? Recommended SDV usage OK No Mandatory error code if operation succeeded. Shall never be used if operation failed. CANCELLED No No explicit use case on server side in SDV identified UNKNOWN No To be used in default-statements when converting errors from e.g., Broker-errors to SDV/gRPC errors INVALID_ARGUMENT No E.g., Rule syntax with errors DEADLINE_EXCEEDED Yes Only applicable for asynchronous services, i.e. services which wait for completion before the result is returned. The behavior if an operation cannot finish within expected time must be defined. Two options exist. One is to return this error after e.g., X seconds. Another is that the server never gives up, but rather waits for the client to cancel the operation. NOT_FOUND No Long term situation that likely not will change in the near future. Example: SDV can not find the specified resource (e.g., no path to get data for specified seat) ALREADY_EXISTS No No explicit use case on server side in SDV identified PERMISSION_DENIED No Operation rejected due to permission denied RESOURCE_EXHAUSTED Yes Possibly if e.g., malloc fails or similar errors. FAILED_PRECONDITION Yes Could be returned if e.g., operation is rejected due to safety reasons. (E.g., vehicle moving) ABORTED Yes Could e.g., be returned if service does not support concurrent requests, and there is already either a related operation ongoing or the operation is aborted due to a newer request received. Could also be used if an operation is aborted on user/driver request, e.g., physical button in vehicle pressed. OUT_OF_RANGE No E.g., Arguments out of range UNIMPLEMENTED No To be used if certain use-cases of the service are not implemented, e.g., if recline cannot be adjusted INTERNAL No Internal errors, like exceptions, unexpected null pointers and similar UNAVAILABLE Yes To be used if the service is temporarily unavailable, e.g., during system startup. DATA_LOSS No No explicit use case identified on server side in SDV. UNAUTHENTICATED No No explicit use case identified on server side in SDV. Other references Pattern for rich error handling in gRPC Advanced gRPC Error Usage ","categories":"","description":"","excerpt":"This provides a style guide for .proto files. By following these …","ref":"/velocitas-docs/docs/concepts/development_model/val/grpc_style_guide/","tags":"","title":"GRPC Interface Style Guide"},{"body":"Not yet done for C++\n","categories":"","description":"Learn how to create a Vehicle Model manually for C++\n","excerpt":"Learn how to create a Vehicle Model manually for C++\n","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_cpp/","tags":"","title":"C++ Manual Vehicle Model Creation"},{"body":"","categories":"","description":"Learn how to setup and explore the provided development environment.\n","excerpt":"Learn how to setup and explore the provided development environment.\n","ref":"/velocitas-docs/docs/tutorials/quickstart/","tags":"","title":"Getting Started"},{"body":"Introduction The Vehicle App SDK consists of the following building blocks:\nVehicle Model Ontology : The SDK provides a set of model base classes for the creation of vehicle models.\nMiddleware integration : Vehicle Models can contain gRPC stubs to communicate with Vehicle Services. gRPC communication is integrated natively.\nFluent query \u0026 rule construction : Based on a concrete Vehicle Model, the SDK is able to generate queries and rules against the KUKSA Databroker to access the real values of the data points that are defined in the vehicle model.\nPublish \u0026 subscribe messaging : The SDK supports publishing messages to a MQTT broker and subscribing to topics of a MQTT broker.\nVehicle App abstraction : Last but not least the SDK provides a VehicleApp base class, which every Vehicle App derives from.\nAn overview of the Vehicle App SDK and its dependencies is depicted in the following diagram:\nVehicle Model Ontology The Vehicle Model is a tree-based model where every branch in the tree, including the root, is derived from the Model base class provided by the SDK.\nThe Vehicle Model Ontology consists of the following classes:\nModel A model contains data points (leaves) and other models (branches).\nModelCollection Info The ModelCollection is deprecated since SDK v0.4.0. The generated vehicle model must reflect the actual representation of the data points. Please use the Model base class instead. Specifications like VSS support a concept that is called Instances . It makes it possible to describe repeating definitions. In DTDL, such kind of structures may be modeled with Relationships . In the SDK, these structures are mapped with the ModelCollection class. A ModelCollection is a collection of models, which make it possible to reference an individual model either by a NamedRange (e.g., Row [1-3]), a Dictionary (e.g., “Left”, “Right”) or a combination of both.\nService Direct asynchronous communication between Vehicle Apps and Vehicle Services is facilitated via the gRPC protocol.\nThe SDK has its own Service base class, which provides a convenience API layer to access the exposed methods of exactly one gRPC endpoint of a Vehicle Service or another Vehicle App. Please see the Middleware Integration section for more details.\nDataPoint DataPoint is the base class for all data points. It corresponds to sensors/actuators/attributes in VSS or telemetry/properties in DTDL.\nData points are the signals that are typically emitted by Vehicle Services or Data Providers.\nThe representation of a data point is a path starting with the root model, e.g.:\nVehicle.Speed Vehicle.FuelLevel Vehicle.Cabin.Seat.Row1.Pos1.Position Data points are defined as attributes of the model classes. The attribute name is the name of the data point without its path.\nTyped DataPoint classes Every primitive datatype has a corresponding typed data point class, which is derived from DataPoint (e.g., DataPointInt32, DataPointFloat, DataPointBool, DataPointString, etc.).\nExample An example of a Vehicle Model created with the described ontology is shown below:\nPython C++ ## import ontology classes from sdv import ( DataPointDouble, Model, Service, DataPointInt32, DataPointBool, DataPointArray, DataPointString, ) class Seat(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Position = DataPointBool(\"Position\", self) self.IsOccupied = DataPointBool(\"IsOccupied\", self) self.IsBelted = DataPointBool(\"IsBelted\", self) self.Height = DataPointInt32(\"Height\", self) self.Recline = DataPointInt32(\"Recline\", self) class Cabin(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.DriverPosition = DataPointInt32(\"DriverPosition\", self) self.Seat = SeatCollection(\"Seat\", self) class SeatCollection(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Row1 = self.RowType(\"Row1\", self) self.Row2 = self.RowType(\"Row2\", self) def Row(self, index: int): if index \u003c 1 or index \u003e 2: raise IndexError(f\"Index {index} is out of range\") _options = { 1 : self.Row1, 2 : self.Row2, } return _options.get(index) class RowType(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Pos1 = Seat(\"Pos1\", self) self.Pos2 = Seat(\"Pos2\", self) self.Pos3 = Seat(\"Pos3\", self) def Pos(self, index: int): if index \u003c 1 or index \u003e 3: raise IndexError(f\"Index {index} is out of range\") _options = { 1 : self.Pos1, 2 : self.Pos2, 3 : self.Pos3, } return _options.get(index) class VehicleIdentification(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.VIN = DataPointString(\"VIN\", self) self.Model = DataPointString(\"Model\", self) class CurrentLocation(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Latitude = DataPointDouble(\"Latitude\", self) self.Longitude = DataPointDouble(\"Longitude\", self) self.Timestamp = DataPointString(\"Timestamp\", self) self.Altitude = DataPointDouble(\"Altitude\", self) class Vehicle(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Speed = DataPointFloat(\"Speed\", self) self.CurrentLocation = CurrentLocation(\"CurrentLocation\", self) self.Cabin = Cabin(\"Cabin\", self) vehicle = Vehicle(\"Vehicle\") #include \"sdk/DataPoint.h\" #include \"sdk/Model.h\" using namespace velocitas; class Seat : public Model { public: Seat(std::string name, Model* parent) : Model(name, parent) {} DataPointBoolean Position{\"Position\", this}; DataPointBoolean IsOccupied{\"IsOccupied\", this}; DataPointBoolean IsBelted{\"IsBelted\", this}; DataPointInt32 Height{\"Height\", this}; DataPointInt32 Recline{\"Recline\", this}; }; class CurrentLocation : public Model { public: CurrentLocation(Model* parent) : Model(\"CurrentLocation\", parent) {} DataPointDouble Latitude{\"Latitude\", this}; DataPointDouble Longitude{\"Longitude\", this}; DataPointString Timestamp{\"Timestamp\", this}; DataPointDouble Altitude{\"Altitude\", this}; }; class Cabin : public Model { public: class SeatCollection : public Model { public: class RowType : public Model { public: using Model::Model; Seat Pos1{\"Pos1\", this}; Seat Pos2{\"Pos2\", this}; }; SeatCollection(Model* parent) : Model(\"Seat\", parent) {} RowType Row1{\"Row1\", this}; RowType Row2{\"Row2\", this}; }; Cabin(Model* parent) : Model(\"Cabin\", parent) {} DataPointInt32 DriverPosition{\"DriverPosition\", this}; SeatCollection Seat{this}; }; class Vehicle : public Model { public: Vehicle() : Model(\"Vehicle\") {} DataPointFloat Speed{\"Speed\", this}; ::CurrentLocation CurrentLocation{this}; ::Cabin Cabin{this}; }; Middleware integration gRPC Services Vehicle Services are expected to expose their public endpoints over the gRPC protocol. The related protobuf definitions are used to generate method stubs for the Vehicle Model to make it possible to call the methods of the Vehicle Services.\nModel integration Info Please be aware that the integration of Vehicle Services into the overall model is not supported by automated model lifecycle , currently.\nBased on the .proto files of the Vehicle Services, the protocol buffer compiler generates descriptors for all rpcs, messages, fields etc. for the target language. The gRPC stubs are wrapped by a convenience layer class derived from Service that contains all the methods of the underlying protocol buffer specification.\nInfo The convenience layer of C++ is a bit more extensive than in Python. The complexity of gRPC’s async API is hidden behind individual AsyncGrpcFacade implementations which need to be implemented manually. Have a look at the SeatService of the SeatAdjusterApp example and its SeatServiceAsyncGrpcFacade. Python C++ class SeatService(Service): def __init__(self): super().__init__() self._stub = SeatsStub(self.channel) async def Move(self, seat: Seat): response = await self._stub.Move( MoveRequest(seat=seat), metadata=self.metadata ) return response class SeatService : public Service { public: // nested classes/structs omitted SeatService(Model* parent) : Service(\"SeatService\", parent) , m_asyncGrpcFacade(grpc::CreateChannel(\"localhost:50051\", grpc::InsecureChannelCredentials())) { } AsyncResultPtr_t\u003cVoidResult\u003e move(Seat seat) { auto asyncResult = std::make_shared\u003cAsyncResult\u003cVoidResult\u003e\u003e(); m_asyncGrpcFacade-\u003eMove( toGrpcSeat(seat), [asyncResult](const auto\u0026 reply){ asyncResult-\u003einsertResult(VoidResult{})}), [asyncResult](const auto\u0026 status){ asyncResult-\u003einsertError(toInternalStatus(status))}; return asyncResult; } private: std::shared_ptr\u003cSeatServiceAsyncGrpcFacade\u003e m_asyncGrpcFacade; }; Fluent query \u0026 rule construction A set of query methods like get(), where(), join() etc. are provided through the Model and DataPoint base classes. These functions make it possible to construct SQL-like queries and subscriptions in a fluent language, which are then transmitted through the gRPC interface to the KUKSA Databroker.\nQuery examples The following examples show you how to query data points.\nGet single data point Python C++ driver_pos: int = vehicle.Cabin.DriverPosition.get() # Call to broker # GetDataPoint(rule=\"SELECT Vehicle.Cabin.DriverPosition\") auto driverPos = getDataPoints({Vehicle.Cabin.DriverPosition})-\u003eawait(); // Call to broker: // GetDataPoint(rule=\"SELECT Vehicle.Cabin.DriverPosition\") Get data points from multiple branches Python C++ vehicle_data = vehicle.CurrentLocation.Latitude.join( vehicle.CurrentLocation.Longitude).get() print(f' Latitude: {vehicle_data.CurrentLocation.Latitude} Longitude: {vehicle_data.CurrentLocation.Longitude} ') # Call to broker # GetDataPoint(rule=\"SELECT Vehicle.CurrentLocation.Latitude, CurrentLocation.Longitude\") auto datapoints = getDataPoints({Vehicle.CurrentLocation.Latitude, Vehicle.CurrentLocation.Longitude})-\u003eawait(); // Call to broker: // GetDataPoint(rule=\"SELECT Vehicle.CurrentLocation.Latitude, CurrentLocation.Longitude\") Subscription examples Subscribe and Unsubscribe to a single data point Python C++ self.rule = ( await self.vehicle.Cabin.Seat.Row(2).Pos(1).Position .subscribe(self.on_seat_position_change) ) def on_seat_position_change(self, data: DataPointReply): position = data.get(self.vehicle.Cabin.Seat.Row2.Pos1.Position).value print(f'Seat position changed to {position}') # Call to broker # Subscribe(rule=\"SELECT Vehicle.Cabin.Seat.Row2.Pos1.Position\") # If needed, the subscription can be stopped like this await self.rule.subscription.unsubscribe() auto subscription = subscribeDataPoints( velocitas::QueryBuilder::select(Vehicle.Cabin.Seat.Row(2).Pos(1).Position).build()) -\u003eonItem( [this](auto\u0026\u0026 item) { onSeatPositionChanged(std::forward\u003cdecltype(item)\u003e(item)); }); // If needed, the subscription can be stopped like this: subscription-\u003ecancel(); void onSeatPositionChanged(const DataPointMap_t datapoints) { logger().info(\"SeatPosition has changed to: \"+ datapoints.at(Vehicle.Cabin.Seat.Row(2).Pos(1).Position)-\u003easFloat().get()); } Subscribe to a single data point with a filter Python C++ Vehicle.Cabin.Seat.Row(2).Pos(1).Position.where( \"Cabin.Seat.Row2.Pos1.Position \u003e 50\") .subscribe(on_seat_position_change) def on_seat_position_change(data: DataPointReply): position = data.get(Vehicle.Cabin.Seat.Row2.Pos1.Position).value print(f'Seat position changed to {position}') # Call to broker # Subscribe(rule=\"SELECT Vehicle.Cabin.Seat.Row2.Pos1.Position WHERE Vehicle.Cabin.Seat.Row2.Pos1.Position \u003e 50\") auto query = QueryBuilder::select(Vehicle.Cabin.Seat.Row(2).Pos(1).Position) .where(vehicle.Cabin.Seat.Row(2).Pos(1).Position) .gt(50) .build(); subscribeDataPoints(query)-\u003eonItem([this](auto\u0026\u0026 item){onSeatPositionChanged(std::forward\u003cdecltype(item)\u003e(item));})); void onSeatPositionChanged(const DataPointMap_t datapoints) { logger().info(\"SeatPosition has changed to: \"+ datapoints.at(Vehicle.Cabin.Seat.Row(2).Pos(1).Position)-\u003easFloat().get()); } // Call to broker: // Subscribe(rule=\"SELECT Vehicle.Cabin.Seat.Row2.Pos1.Position WHERE Vehicle.Cabin.Seat.Row2.Pos1.Position \u003e 50\") Publish \u0026 subscribe messaging The SDK supports publishing messages to a MQTT broker and subscribing to topics of a MQTT broker. Using the Velocitas SDK, the low-level MQTT communication is abstracted away from the Vehicle App developer. Especially the physical address and port of the MQTT broker is no longer configured in the Vehicle App itself, but rather is set as an environment variable, which is outside of the Vehicle App.\nPublish MQTT Messages MQTT messages can be published easily with the publish_event() method, inherited from VehicleApp base class:\nPython C++ await self.publish_event( \"seatadjuster/currentPosition\", json.dumps(req_data)) publishToTopic(\"seatadjuster/currentPosition\", \"{ \\\"position\\\": 40 }\"); Subscribe to MQTT Topics In Python subscriptions to MQTT topics can be easily established with the subscribe_topic() annotation. The annotation needs to be applied to a method of the VehicleApp base class. In C++ the subscribeToTopic() method has to be called. Callbacks for onItem and onError can be set. The following examples provide some more details.\nPython C++ @subscribe_topic(\"seatadjuster/setPosition/request\") async def on_set_position_request_received(self, data: str) -\u003e None: data = json.loads(data) logger.info(\"Set Position Request received: data=%s\", data) #include \u003cfmt/core.h\u003e #include \u003cnlohmann/json.hpp\u003e subscribeToTopic(\"seatadjuster/setPosition/request\")-\u003eonItem([this](auto\u0026\u0026 item){ const auto jsonData = nlohmann::json::parse(item); logger().info(fmt::format(\"Set Position Request received: data={}\", jsonData)); }); Vehicle App abstraction Vehicle Apps are inherited from the VehicleApp base class. This enables the Vehicle App to use the Publish \u0026 Subscribe messaging and to connect to the KUKSA Databroker.\nThe Vehicle Model instance is passed to the constructor of the VehicleApp class and should be stored in a member variable (e.g. self.vehicle for Python, std::shared_ptr\u003cVehicle\u003e m_vehicle; for C++), to be used by all methods within the application.\nFinally, the run() method of the VehicleApp class is called to start the Vehicle App and register all MQTT topic and Databroker subscriptions.\nImplementation detail In Python, the subscriptions are based on asyncio, which makes it necessary to call the run() method with an active asyncio event_loop. A typical skeleton of a Vehicle App looks like this:\nPython C++ class SeatAdjusterApp(VehicleApp): def __init__(self, vehicle: Vehicle): super().__init__() self.vehicle = vehicle async def main(): # Main function logger.info(\"Starting seat adjuster app...\") seat_adjuster_app = SeatAdjusterApp(vehicle) await seat_adjuster_app.run() LOOP = asyncio.get_event_loop() LOOP.add_signal_handler(signal.SIGTERM, LOOP.stop) LOOP.run_until_complete(main()) LOOP.close() #include \"sdk/VehicleApp.h\" #include \"vehicle/Vehicle.hpp\" using namespace velocitas; class SeatAdjusterApp : public VehicleApp { public: SeatAdjusterApp() : VehicleApp(IVehicleDataBrokerClient::createInstance(\"vehicledatabroker\")), IPubSubClient::createInstance(\"localhost:1883\", \"SeatAdjusterApp\")) {} private: ::Vehicle Vehicle; }; int main(int argc, char** argv) { SeatAdjusterApp app; app.run(); return 0; } Further information Tutorial: Quickstart Tutorial: Vehicle Model Creation Tutorial: Vehicle App Development Tutorial: Develop and run integration tests for a Vehicle App ","categories":"","description":"Learn more about the provided _Vehicle App_ SDK.\n","excerpt":"Learn more about the provided _Vehicle App_ SDK.\n","ref":"/velocitas-docs/docs/concepts/development_model/vehicle_app_sdk/","tags":"","title":"Vehicle App SDK"},{"body":" Providing CLI package Interface type-key devenv-devcontainer-setup grpc-interface Description This interface type introduces a dependency to a gRPC service. It is used to generate either client stubs (in case your application requires the interface) or server stubs (in case your application provides the interface). The result of the generation is a language specific and package manager specific source code package, integrated with the Velocitas SDK core.\nIf a Vehicle App requires a grpc-interface - a client stub embedded into the Velocitas framework will be generated and added as a build-time dependency of your application. It enables you to access your service from your Vehicle App without any additional effort.\nIf a Vehicle App provides a grpc-interface - a server stub embedded into the Velocitas framework will be generated and added as a build-time dependency of your application. It enables you to quickly add the business logic of your application.\nConfiguration structure Attribute Type Example value Description src string \"https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto\" URI of the used protobuf specification of the service. URI may point to a local file or to a file provided by a server. It is generally recommended that a stable proto file is used. I.e. one that is already released under a proper tag rather than an in-development proto file. required.methods array Array of service’s methods that are accessed by the application. In addition to access control the methods attribute may be used to determine backward or forward compatibility i.e. if semantics of a service’s interface did not change but methods were added or removed in a future version. required.methods.[].name string \"Move\", \"MoveComponent\" Name of the method that the application would like to access provided object {} Reserved object indicating that the interface is provided. Might be filled with further configuration values. Execution velocitas init or velocitas exec grpc-interface-support generate-sdk\nProject configuration { \"type\": \"grpc-interface\", \"config\": { \"src\": \"https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto\", \"required\": { \"methods\": [ \"Move\", \"MoveComponent\" ] }, \"provided\": { } } } You need to specify devenv-devcontainer-setup \u003e= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:\n{ \"packages\": { \"devenv-devcontainer-setup\": \"v2.4.2\" }, \"components\": [ { \"id\": \"grpc-interface-support\", } ], } To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2\n","categories":"","description":"The functional interface for supporting remote procedure calls via gRPC.\n","excerpt":"The functional interface for supporting remote procedure calls via …","ref":"/velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/interfaces/grpc_interface/","tags":"","title":"gRPC Service Interface"},{"body":" Providing CLI package Interface type-key devenv-runtimes pubsub Description This interface type introduces a dependency to a publish and subscribe middleware. While this may change in the future due to new middlewares being adopted, at the moment this will always indicate a dependency to MQTT.\nIf a Vehicle App requires pubsub - this will influence the generated deployment specs to include a publish and subscribe broker (i.e. an MQTT broker).\nIf a Vehicle App provides pubsub - this will influence the generated deployment specs to include a publish and subscribe broker (i.e. an MQTT broker).\nConfiguration structure Attribute Type Example value Description reads array[string] [ \"sampleapp/getSpeed\" ] Array of topics which are read by the application. writes array[string] [ \"sampleapp/currentSpeed\", \"sampleapp/getSpeed/response\" ] Array of topics which are written by the application. Example { \"type\": \"pubsub\", \"config\": { \"reads\": [ \"sampleapp/getSpeed\" ], \"writes\": [ \"sampleapp/currentSpeed\", \"sampleapp/getSpeed/response\" ] } } ","categories":"","description":"The functional interface for supporting communication via publish and subscribe.\n","excerpt":"The functional interface for supporting communication via publish and …","ref":"/velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/interfaces/pubsub/","tags":"","title":"Publish Subscribe"},{"body":"To be filled.\nTemplate based creation flow Bootstrapping creation flow Resulting Velocitas CLI and Velocitas Package changes velocitas create command shall be introduced\nit will guide through the project creation process, allowing the developer to add APIs and services at creation time which will reference the correct Velocitas CLI packages (either provided by Velocitas or by a 3rd party). in addition to an interactive mode where create is invoked without arguments, there shall be a CLI mode where all of the arguments shall be passable as arguments Packages need to be available in a central registry (i.e. a new git repository) otherwise step 3 (depicted below) is not possible.\nPackages need to expose which dependency types they are providing in their manifest. For each dependency type a human readable name for the type shall be exposed.\nInteraction mockup \u003e velocitas create ... Creating a new Velocitas project! \u003e What is the name of your project? MyApp \u003e 1. Which programming language would you like to use for your project? [ ] Python [x] C++ \u003e 2. Which integrations would you like to use? (multiple selections possible) [x] Github [x] Gitlab [ ] Gitee \u003e 3. Which API dependencies does your project have? [x] gRPC service [ ] uProtocol service \u003e 4. Add an API dependency (y/n)? y \u003e 5. What type of dependency? [x] gRPC-IF \u003e 6. URI of the .proto file? https://some-url/if.proto \u003e 7. Add an(other) API dependency (y/n)? n ... Project created! Arguments mockup:\n$ velocitas create \\ --name MyApp \\ --lang cpp \\ --package grpc-service-support \\ --require grpc-interface:https://some-url/if.proto \u003e Project created! ","categories":"","description":"To be filled\n","excerpt":"To be filled\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/phases/create/","tags":"","title":"Create"},{"body":"","categories":"","description":"Overview of Velocitas Concepts.\n","excerpt":"Overview of Velocitas Concepts.\n","ref":"/velocitas-docs/docs/concepts/","tags":"","title":"Concepts"},{"body":"Introduction Once a repository has been created from one of our Vehicle App templates, basically the only way to receive updates into your derived repository is to manually pull changes, which would be quite tedious and error prone. This is where our Lifecycle Management comes to the rescue!\nAll of our main components of the development environment, like\ntools runtimes devcontainer configuration and setup build systems CI workflows are (or will be) provided as versioned packages which can be updated individually, if required.\nThe driver for this is our Velocitas CLI which is our package manager for Vehicle App repositories.\nOverview Here we can see how the MyVehicleApp repository references package repositories by Velocitas, customer specific packages and some packages from a totally different development platform (Gitee).\nIf you want to learn more about how to reference and use packages check the sections for project configuration and packages .\nLifecycle Management flow ","categories":"","description":"Learn more about our lifecycle management.\n","excerpt":"Learn more about our lifecycle management.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/","tags":"","title":"Lifecycle Management"},{"body":"Background Our Velocitas CLI is introduced to support the process of the lifecycle of a Vehicle App as a project manager.\nCommands You can find all information about available commands here .\nCLI Flow examples velocitas create Create a new Velocitas Vehicle App project. Note velocitas create needs to be executed inside our generic vehicle-app-template (inside the devcontainer) where a so called\npackage-index.json is located for now, which is a central place of defining our extension and core packages with their respective exposed interfaces.\nvscode ➜ /workspaces/vehicle-app-template (main) $ velocitas create Interactive project creation started \u003e What is the name of your project? MyApp \u003e Which programming language would you like to use for your project? (Use arrow keys) ❯ python cpp \u003e Would you like to use a provided example? No \u003e Which functional interfaces does your application have? (Press \u003cspace\u003e to select, \u003ca\u003e to toggle all, \u003ci\u003e to invert selection, and \u003center\u003e to proceed) ❯◉ Vehicle Signal Interface based on VSS and KUKSA Databroker ◯ gRPC service contract based on a proto interface description ... Config 'src' for interface 'vehicle-signal-interface': URI or path to VSS json (Leave empty for default: v3.0) ... velocitas init Download packages configured in your .velocitas.json to VELOCITAS_HOME vscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas init Initializing Velocitas packages ... ... Downloading package: 'devenv-runtimes:v1.0.1' ... Downloading package: 'devenv-github-workflows:v2.0.4' ... Downloading package: 'devenv-github-templates:v1.0.1' ... Downloading package: 'devenv-devcontainer-setup:v1.1.7' Running post init hook for model-generator Running 'install-deps' ... Single Package Init Single packages can also easily be initialized or re-initialized using the package parameter -p / --package and the specifier parameter -s / --specifier. The specifier parameter can be either a git tag or a git hash. If the specifier parameter is omitted either the version defined in .velocitas.json resp. the latest version of the specified package will be used automatically. After initialisation the package and it’s resolved version will be written to .velocitas.json. If the package already exists in .velocitas.json, however the versions differ it will be automatically updated to the specified version. If no components from the specified package are added to .velocitas.json all components from this package are automatically written to it.\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas init -p devenv-runtimes -s v3.0.0 Initializing Velocitas packages ... ... Package 'devenv-runtimes:v3.0.0' added to .velocitas.json ... Downloading package: 'devenv-runtimes:v3.0.0' ... \u003e Running post init hook for ... ... velocitas sync If any package provides files they will be synchronized into your repository. Note This will overwrite any changes you have made to the files manually! Affected files are prefixed with an auto generated notice: vscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas sync Syncing Velocitas components! ... syncing 'devenv-github-workflows' ... syncing 'devenv-github-templates' ... syncing 'devenv-devcontainer-setup' velocitas upgrade Updates Velocitas components.\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas upgrade --dry-run [--ignore-bounds] Checking .velocitas.json for updates! ... devenv-devcontainer-setup:vx.x.x → up to date! ... devenv-runtimes:vx.x.x → vx.x.x ... devenv-github-templates:vx.x.x → up to date! ... devenv-github-workflows:vx.x.x → up to date! velocitas package Prints information about packages.\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas package devenv-devcontainer-setup devenv-devcontainer-setup version: v1.1.7 components: - id: devcontainer-setup type: setup variables: language type: string description: The programming language of the project. Either 'python' or 'cpp' required: true repoType type: string description: The type of the repository: 'app' or 'sdk' required: true appManifestPath type: string description: Path of the AppManifest file, relative to the .velocitas.json required: true vscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas package devenv-devcontainer-setup -p /home/vscode/.velocitas/packages/devenv-devcontainer-setup/v1.1.7 velocitas exec Executes a script contained in one of your installed components.\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas exec runtime-local run-vehicledatabroker ####################################################### ### Running Databroker ### ####################################################### ... More detailed usage can be found at the Velocitas CLI README .\nAdditional Information Cache Usage The Velocitas CLI supports caching data for a Vehicle App project. The cache data makes it easy for any script/program of a component to read from or write to. More detailed information about the Project Cache can be found here .\nBuilt-In Variables The Velocitas CLI also creates default environment variables which are available to every script/program.\nvariable description VELOCITAS_WORKSPACE_DIR Current working directory of the Vehicle App VELOCITAS_CACHE_DIR Vehicle App project specific cache directory. e.g, ~/.velocitas/cache/\u003cgeneratedMd5Hash\u003e VELOCITAS_CACHE_DATA JSON string of ~/.velocitas/cache/\u003cgeneratedMd5Hash\u003e/cache.json VELOCITAS_APP_MANIFEST JSON string of the Vehicle App AppManifest More detailed information about Built-In Variables can be found here .\nNext steps Lifecycle Management: Troubleshooting ","categories":"","description":"Learn everything about the Velocitas CLI.\n","excerpt":"Learn everything about the Velocitas CLI.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/velocitas_cli/","tags":"","title":"Velocitas CLI"},{"body":"","categories":"","description":"Learn how to start your _Vehicle App_ development with a prototype created in the playground of digital.auto and how to set up and customize _Vehicle Services_/_Data Providers_.\n","excerpt":"Learn how to start your _Vehicle App_ development with a prototype …","ref":"/velocitas-docs/docs/tutorials/prototyping/","tags":"","title":"Prototyping"},{"body":"Introduction The Vehicle Abstraction Layer (VAL) enables access to the systems and functions of a vehicle via a unified - or even better - a standardized Vehicle API abstracting from the details of the end-to-end architecture of the vehicle. The unified API enables Vehicle Apps to run on different vehicle architectures of a single OEM. Vehicle Apps can be even implemented OEM-agnostic, if using an API based on a standard like the COVESA Vehicle Signal Specification (VSS) . The Vehicle API eliminates the need to know the source, destination, and format of signals for the vehicle system.\nThe Eclipse Velocitas project is using the Eclipse KUKSA project . KUKSA does not provide a concrete VAL. That’s up to you as an OEM (vehicle manufacturer) or as a supplier. But KUKSA provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an Vehicle App or Service.\nKUKSA provides you with ready-to-use generic components for the signal-based access to the vehicle, like the KUKSA Databroker and the generic Data Providers (aka Data Feeders). It also provides you reference implementations of certain Vehicle Services, like the Seat Service and the HVAC Service.\nArchitecture The image below shows the main components of the VAL and its relation to the Velocitas Development Model .\nKUKSA Databroker The KUKSA Databroker is a gRPC service acting as a broker of vehicle data / signals also called data points in the following. It provides central access to vehicle data points arranged in a - preferably standardized - vehicle data model like the COVESA VSS or others. But this is not a must, it is also possible to use your own (proprietary) vehicle model or to extend the COVESA VSS with your specific extensions via VSS overlays .\nData points represent certain states of a vehicle, like the current vehicle speed or the currently applied gear. Data points can represent sensor values like the vehicle speed or engine temperature, actuators like the wiper mode, and immutable attributes of the vehicle like the needed fuel type(s) of the vehicle, engine displacement, maximum power, etc.\nData points factually belonging together are typically arranged in branches and sub-branches of a tree structure (like this example on the COVESA VSS site).\nThe KUKSA Databroker is implemented in Rust, can run in a container and provides services to get data points, update data points and for subscribing to automatic notifications on data point changes. Filter- and rule-based subscriptions of data points can be used to reduce the number of updates sent to the subscriber.\nData Providers / Data Feeders Conceptually, a data provider is the responsible to take care for a certain set of data points: It provides updates of sensor data from the vehicle to the Databroker and forwards updates of actuator values to the vehicle. The set of data points a data provider maintains may depend on the network interface (e.g. CAN bus) via that those data is accessible or it can depend on a certain use case the provider is responsible for (like seat control).\nEclipse KUKSA provides several generic Data Providers for different datasources. As of today, Eclipse Velocitas only utilizes the generic CAN Provider (KUKSA CAN Provider) implemented in Python, which reads data from a CAN bus based on mappings specified in e.g. a CAN network description (dbc) file. The feeder uses a mapping file and data point metadata to convert the source data to data points and injects them into the Databroker using its Collector gRPC interface. The feeder automatically reconnects to the Databroker in the event that the connection is lost.\nVehicle Services A vehicle service offers a Vehicle App to interact with the vehicle systems on a RPC-like basis. It can provide service interfaces to control actuators or to trigger (complex) actions, or provide interfaces to get data. It communicates with the Hardware Abstraction to execute the underlying services, but may also interact with the Databroker.\nThe KUKSA Incubation repository contains examples illustrating how such kind of vehicle services can be built.\nHardware Abstraction Data feeders rely on hardware abstraction. Hardware abstraction is project/platform specific. The reference implementation relies on SocketCAN and vxcan, see KUKSA CAN Provider . The hardware abstraction may offer replaying (e.g., CAN) data from a file (can dump file) when the respective data source (e.g., CAN) is not available.\nOverview of the VAL architecture Information Flow The VAL offers an information flow between vehicle networks and vehicle services. The data that can flow is ultimately limited to the data available through the Hardware Abstraction, which is platform/project-specific. The KUKSA Databroker offers read/subscribe access to data points based on a gRPC service. The data points which are actually available are defined by the set of feeders providing the data into the broker. Services (like the seat service ) define which CAN signals they listen to and which CAN signals they send themselves, see documentation . Service implementations may also interact as feeders with the Databroker.\nData flow when a Vehicle App uses the KUKSA Databroker Architectural representation of the KUKSA Databroker data flow Data flow when a Vehicle App uses a Vehicle Service Architectural representation of the vehicle service data flow Source Code Source code and build instructions are available in the respective KUKSA repositories:\nKUKSA Databroker KUKSA CAN Provider KUKSA example providers GRPC Interface Style Guide A style guide is available in the GRPC Interface Style Guide ","categories":"","description":"Learn about the main concepts and components of the vehicle abstraction and how it relates to the [Eclipse KUKSA project](https://github.com/eclipse-kuksa).\n","excerpt":"Learn about the main concepts and components of the vehicle …","ref":"/velocitas-docs/docs/concepts/development_model/val/","tags":"","title":"Vehicle Abstraction Layer (VAL)"},{"body":"Now that you have created your own Vehicle Model, we can distribute it to make use of it in Vehicle Apps.\nCopying the folder to your Vehicle App repo The easiest way to get started quickly is to copy the created model, presumably stored in vehicle_model into your Vehicle App repository to use it. To do so, simply copy and paste the directory into the \u003csdk_root\u003e/app directory and replace the existing model.\nUsing a git submodule A similar approach to the one above but a bit more difficult to set up is to create a git repository for the created model. The advantage of this approach is that you can share the same model between multiple Vehicle Apps without any manual effort.\nCreate a new git repository on i.e. Github Clone it locally, add the created vehicle_model folder to the git repository Commit everything and push the branch In your Vehicle App repo, add a new git submodule via\ngit submodule add \u003ccheckout URL of your new repo\u003e app/vehicle_model git submodule init Now you are ready to develop new Vehicle Apps with your custom Vehicle Model!\n","categories":"","description":"Learn how to distribute a Vehicle Model written in C++.\n","excerpt":"Learn how to distribute a Vehicle Model written in C++.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_cpp/","tags":"","title":"C++ Vehicle Model Distribution"},{"body":" Info With the release of our new model lifecycle approach on Friday, 2023-03-03, the model is now automatically generated with the instantiation of the devContainer from a model source referenced in the app manifest.\nThe approach described here, using pre-generated model repositories, is deprecated as of now. But it is still available and must be used if you need access to vehicle services. Please be aware, that you would either have to use template versions before the above mentioned release, or you need to adapt the newer versions of the template using the old approach.\nThis tutorial will show you how to:\nCreate a Vehicle Model Add a Vehicle Service to the Vehicle Model Distribute your Python Vehicle Model Note A Vehicle Model should be defined in its own package. This makes it possible to distribute the Vehicle Model later as a standalone package and to use it in different Vehicle App projects.\nThe creation of a new vehicle model is only required if the vehicle signals (like sensors and actuators) defined in the current version of the COVESA Vehicle Signal Specification (VSS) is not sufficient for the definition of your vehicle API. Otherwise you could use the default vehicle model we already generated for you, see\nPython Vehicle Model and\nC++ Vehicle Model .\nCreate a Vehicle Model from VSS specification A Vehicle Model can be generated from a COVESA Vehicle Signal Specification (VSS). VSS introduces a domain taxonomy for vehicle signals, in the sense of classical attributes, sensors and actuators with the raw data communicated over vehicle buses and data. The Velocitas vehicle-model-generator creates a Vehicle Model from the given specification and generates a package for use in Vehicle App projects.\nFollow the steps to generate a Vehicle Model.\nClone the vehicle-model-generator repository in a container volume.\nIn this container volume, clone the vehicle-signal-specification repository and if required checkout a particular branch:\ngit clone https://github.com/COVESA/vehicle_signal_specification cd vehicle_signal_specification git checkout \u003cbranch-name\u003e In case the VSS vspec doesn’t contain the required signals, you can create a vspec using the VSS Rule Set .\nExecute the command\npython3 gen_vehicle_model.py -I ./vehicle_signal_specification/spec ./vehicle_signal_specification/spec/VehicleSignalSpecification.vspec -l \u003clang\u003e -T sdv_model -N sdv_model or if you want to generate it from a .json file\npython3 gen_vehicle_model.py \u003cpath_to_your_json_file\u003e -l \u003clang\u003e -T sdv_model Depending on the value of lang, which can assume the values python and cpp, this creates a sdv_model directory in the root of repository along with all generated source files for the given programming language.\nHere is an overview of what is generated for every available value of lang:\nlang output python Python sources and a setup.py ready to be used as Python package cpp C++ sources, headers and a CMakeLists.txt ready to be used as a CMake project To have a custom model name, refer to README of vehicle-model-generator repository.\nFor Python: Change the version of package in setup.py manually (defaults to 0.1.0).\nNow the newly generated sdv_model can be used for distribution. (See Distributing your Vehicle Model )\nCreate a Vehicle Model Manually Alternative to the generation from a VSS specification you could create the Vehicle Model manually. The following sections describing the required steps.\nPython Distributing your Vehicle Model Once you have created your Vehicle Model either manually or via the Vehicle Model Generator, you need to distribute your model to use it in an application. Follow the links below for language specific tutorials on how to distribute your freshly created Vehicle Model.\nPython C++ Further information Concept: SDK Overview Tutorial: Quickstart Tutorial: Create a Vehicle App ","categories":"","description":"Learn how to manually create a vehicle model to access vehicle data or execute remote procedure calls.\n","excerpt":"Learn how to manually create a vehicle model to access vehicle data or …","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/","tags":"","title":"Manual Vehicle Model Creation"},{"body":"","categories":"","description":"Learn about the different phases within the lifecycle of your project.\n","excerpt":"Learn about the different phases within the lifecycle of your project. …","ref":"/velocitas-docs/docs/concepts/lifecycle_management/phases/","tags":"","title":"Phases"},{"body":"Versions v1 v2 v3 (current) Introduction The AppManifest defines the properties of your Vehicle App and its functional interfaces (FIs).\nFIs may be:\nrequired service interfaces (e.g. a required gRPC service interface) the used vehicle model and accessed data points. an arbitrary abstract interface description used by 3rd parties In addition to required FIs, provided FIs can (and need) to be specified as well.\nThese defined interfaces are then used by the Velocitas toolchain to:\ngenerate service stubs for either a client implementation (required IF) or a server implementation (provided IF) (i.e. for gRPC) generate a source code equivalent of the defined vehicle model Overview The image below depicts the interaction between App Manifest and DevEnv Configuration at -development time- The responsibilities are clearly separated; the App Manifest describes the application and its interfaces whereas DevEnv Configuration (or .velocitas.json) defines the configuration of the development environment and all the packages used by the Velocitas toolchain.\nContext To fully understand the AppManifest, let’s have a look at who interacts with it:\nPurpose Define the requirements of a Vehicle App in an abstract way to avoid dependencies on concrete Runtime and Middleware configurations. Description of your applications functional interfaces(VehicleModel, services, APIs, …) Enable loose coupling of functional interface descriptions and the Velocitas toolchain. Some parts of the toolchain are responsible for reading the file and acting upon it, depending on the type of functional interface Providing an extendable syntax to enable custom functional interface types which may not provided by the Velocitas toolchain itself, but by a third party Providing a single source of truth for generation of deployment specifications (i.e. Kanto spec, etc…) Example // AppManifest.json { \"manifestVersion\": \"v3\", \"name\": \"SampleApp\", \"interfaces\": [ { \"type\": \"vehicle-signal-interface\", \"config\": { \"src\": \"https://github.com/COVESA/vehicle_signal_specification/releases/download/v3.0/vss_rel_3.0.json\", \"datapoints\": { \"required\": [ { \"path\": \"Vehicle.Speed\", \"optional\": \"true\", \"access\": \"read\", } ], \"provided\": [ { \"path\": \"Vehicle.Cabin.Seat.Row1.Pos1.Position\", } ] } } }, { \"type\": \"grpc-interface\", \"config\": { \"src\": \"https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto\", \"required\": { \"methods\": [ \"Move\", \"MoveComponent\" ] }, } }, { \"type\": \"pubsub\", \"config\": { \"reads\": [ \"sampleapp/getSpeed\" ], \"writes\": [ \"sampleapp/currentSpeed\", \"sampleapp/getSpeed/response\" ] } } ] } The VehicleApp above has an:\ninterface towards our generated Vehicle Signal Interface based on the COVESA Vehicle Signal Specification . In particular, it requires read access to the vehicle signal Vehicle.Speed since the signal is marked as optional the application will work, even if the signal is not present in the system. Additionally, the application acts as a provider for the signal Vehicle.Cabin.Seat.Row1.Pos1.Position meaning that it will take responsibility of reading/writing data directly to vehicle networks for the respective signal.\ninterface towards gRPC based on the seats.proto file. Since the direction is required a service client for the seats service will be generated who interacts with the Velocitas middleware.\ninterface towards the pubsub middleware and is reading to the topic sampleapp/getSpeed and writing the topics sampleapp/currentSpeed, sampleapp/getSpeed/response.\nThe example has no provided interfaces.\nStructure Describes all external properties and interfaces of a Vehicle Application.\nProperties Property Type Required Description manifestVersion string Yes The version of the App Manifest. name string Yes The name of the Vehicle Application. interfaces object [] No Array of all provided or required functional interfaces. Interfaces Properties Property Type Required Description type string Yes The type of the functional interface. config object No The configuration of the functional interface type. Content may vary between all types. Config The configuration of the functional interface type. Content may vary between all types.\nRefer to the JSON Schema of the current AppManifest here .\nVisualization graph TD manifest(AppManifest.json) manifest --\u003e manifestVersion[manifestVersion] manifest --\u003e name[name] manifest -.-\u003e interfaces[interfaces] interfaces -- \"0..n\" --\u003e interfaces.item(object) interfaces.item --\u003e interfaces.item.type[type] interfaces.item -.-\u003e interfaces.item.config[config] Functional interface types supported by Velocitas Here is a list of functional interface types directly supported by the Velocitas toolchain and which Velocitas CLI packages are exposing the support:\nVehicle Signal Interface gRPC interface Publish and subscribe Support for additional interface types may be added by providing a 3rd party CLI package .\nPlanned, but not yet available features Some FIs are dependent on used classes, methods or literals in your Vehicle App’s source code. For example the vehicle-model FI requires you to list required or provided datapoints. At the moment, these attributes need to be filled manually. There are ideas to auto-generate these attributes by analyzing the source code, but nothing is planned for that, yet.\nFurther information Tutorial: Quickstart Tutorial: Vehicle Model Creation Tutorial: Vehicle App Development Concept: Lifecycle Management ","categories":"","description":"Learn more about the _Vehicle App_ Manifest.\n","excerpt":"Learn more about the _Vehicle App_ Manifest.\n","ref":"/velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/","tags":"","title":"Vehicle App Manifest"},{"body":"Now you a have a Python package containing your first Python Vehicle Model and it is time to distribute it. There is nothing special about the distribution of this package, since it is just an ordinary Python package. Check out the Python Packaging User Guide to learn more about packaging and package distribution in Python.\nDistribute to single Vehicle App If you want to distribute your Python Vehicle Model to a single Vehicle App, you can do so by copying the entire folder my_vehicle_model under the /app/src folder of your Vehicle App repository and treat it as a sub-package of the Vehicle App.\nCreate a new folder my_vehicle_model under /app/src in your Vehicle App repository. Copy the my_vehicle_model folder to the /app/src folder of your Vehicle App repository. Import the package my_vehicle_model in your Vehicle App: from \u003cmy_app\u003e.my_vehicle_model import vehicle ... my_app = MyVehicleApp(vehicle) Distribute inside an organization If you want to distribute your Python Vehicle Model inside an organization and use it to develop multiple Vehicle Apps, you can do so by creating a dedicated Git repository and copying the files there.\nCreate new Git repository called my_vehicle_model\nCopy the content under my_vehicle_model to the repository.\nRelease the Vehicle Model by creating a version tag (e.g., v1.0.0).\nInstall the Vehicle Model package to your Vehicle App:\npip3 install git+https://github.com/\u003cyourorg\u003e/my_vehicle_model.git@v1.0.0 Import the package my_vehicle_model in your Vehicle App and use it as shown in the previous section.\nDistribute publicly as open source If you want to distribute your Python Vehicle Model publicly, you can do so by creating a Python package and distributing it on the Python Package Index (PyPI) . PyPi is a repository of software for the Python programming language and helps you find and install software developed and shared by the Python community. If you use the pip command, you are already using PyPI.\nDetailed instructions on how to make a Python package available on PyPI can be found here .\n","categories":"","description":"Learn how to distribute a Vehicle Model written in Python.\n","excerpt":"Learn how to distribute a Vehicle Model written in Python.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_python/","tags":"","title":"Python Vehicle Model Distribution"},{"body":"\n","categories":"","description":"Learn how to get started with Eclipse Velocitas™, including setting up the development environment, creating a Vehicle Model as well as developing, testing and deploying a _Vehicle App_.\n","excerpt":"Learn how to get started with Eclipse Velocitas™, including setting up …","ref":"/velocitas-docs/docs/tutorials/","tags":"","title":"Tutorials"},{"body":"Please visit first Getting Started page if you don’t know where to start.\n","categories":"","description":"Learn how to develop a new _Vehicle App_.\n","excerpt":"Learn how to develop a new _Vehicle App_.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_app_development/","tags":"","title":"Vehicle App Development"},{"body":" Info On Friday, 2023-03-03 we released our new model lifecycle approach . With the update of the documentation the previous content of this page can be found in the section\nManual Vehicle Model Creation now.\nA Vehicle Model makes it possible to easily get vehicle data from the KUKSA Databroker and to execute remote procedure calls over gRPC against Vehicle Services and other Vehicle Apps. It is generated from the underlying semantic models based e.g. on the COVESA Vehicle Signal Specification (VSS) . The model is generated for a concrete programming language as a graph-based, strongly-typed, intellisense-enabled library providing vehicle abstraction “on code level”.\nBy default our app templates now generate the vehicle model during the devContainer initialization - managed by the Velocitas life cycle management. The respective VSS-based model source is referenced in the app manifest allowing to freely choose the model being used in your project. You will find more details about this in section Automated Model Lifecycle .\nThe previous approach, using pre-generated model repositories, is deprecated as of now. But is still available and is described in section Manual Vehicle Model Creation . Please be aware, that you would either have to use template versions before the above mentioned release, or you need to adapt the newer versions of the template using the old approach.\n","categories":"","description":"Learn how creation of vehicle models work and how to adapt it to your needs.\n","excerpt":"Learn how creation of vehicle models work and how to adapt it to your …","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/","tags":"","title":"Vehicle Model Creation"},{"body":"","categories":"","description":"Learn everything about Velocitas packages.\n","excerpt":"Learn everything about Velocitas packages.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/packages/","tags":"","title":"Packages"},{"body":"Thanks for thinking about contributing to Eclipse Velocitas. We really appreciate the time and effort you want to spend helping to improve Eclipse Velocitas.\nHowever, in order to get you started as fast as possible, we need to go through some organizational issues first.\nEclipse Contributor Agreement Before your contribution can be accepted by the project team, contributors must electronically sign the Eclipse Contributor Agreement (ECA).\nhttp://www.eclipse.org/legal/ECA.php Commits that are provided by non-committers must have a Signed-off-by field in the footer indicating that the author is aware of the terms by which the contribution has been provided to the project. The non-committer must additionally have an Eclipse Foundation account and must have a signed Eclipse Contributor Agreement (ECA) on file.\nFor more information, please see the Eclipse Committer Handbook: https://www.eclipse.org/projects/handbook/#resources-commit Making Your Changes Fork the repository on GitHub. Create a new branch for your changes. Make your changes following the code style guide (see Code Style Guide section above). When you create new files, make sure you include a proper license header at the top of the file (see License Header section below). Make sure you include test cases for non-trivial features. Make sure test cases provide sufficient code coverage (see GitHub actions for minimal accepted coverage). Make sure the test suite passes after your changes. Commit your changes into that branch. Use descriptive and meaningful commit messages. Start the first line of the commit message with the issue number and title e.g., [#9865] Add token-based authentication. Squash multiple commits that are related to each other semantically into a single one. Make sure you use the -s flag when committing as explained above. Push your changes to your branch in your forked repository. Adding Documentation to Hugo Add the markdown document to the appropriate folder in the path velocitas-docs/hugo/hugo/content. Add the front-matter --- title: \"title of the file\" date: 2022-05-09T13:43:25+05:30 --- Additional front matter that can be added – url : \"specifying a definite url to the file\" weight : 10 (used for ordering your content in lists. Lower weight gets higher precedence.) The images need to be put in path velocitas-docs/hugo/hugo/static/assets. The image reference should be /assets/image.jpg in the markdown file. (Note: Do not use relative paths or url) In case you are creating a new folder, create _index.md file with the front matter only. Running Locally Install hugo version 0.98.0 extended Release v0.98.0 · gohugoio/hugo (github.com) Install docsy theme in the path velocitas-docs/hugo/hugo/theme – #Run this command from the root directory of velocitas-docs git clone https://github.com/google/docsy.git hugo/hugo/themes/docsy Install pre-requisites cd themes/docsy/userguide/ npm install npm install --save-dev postcss Run the command hugo server visit localhost:1313 from the velocitas-docs/hugo/hugo directory to see the rendered static site. Submitting the Changes Submit a pull request via the normal GitHub UI.\nAfter Submitting Do not use your branch for any other development, otherwise further changes that you make will be visible in the PR. License Header Please make sure any file you newly create contains a proper license header like this:\n# Copyright (c) \u003cyear\u003e 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 You should, of course, adapt this header to use the specific mechanism for comments pertaining to the type of file you create.\nImportant\nPlease do not forget to add your name/organization to the /legal/legal/NOTICE.md file’s Copyright Holders section. If this is not the first contribution you make, then simply update the time period contained in the copyright entry to use the year of your first contribution as the lower boundary and the current year as the upper boundary, e.g.,\nCopyright 2017, 2018 ACME Corporation\nBuild A pipeline run will be triggered on every PR merge. This run will trigger the hugo docs build Hugo v0.98.0 extended is set up for the runner docsy theme is setup for beautification of static site Then dependencies are installed for the theme Static site is generated and stored in a folder \"public\" The contents of public are committed to gh_pages branch which is exposed to host the GitHub pages ","categories":"","description":"Read how you can contribute to Eclipse Velocitas.\n","excerpt":"Read how you can contribute to Eclipse Velocitas.\n","ref":"/velocitas-docs/docs/contribution-guidelines/","tags":"","title":"Contribution Guidelines"},{"body":"","categories":"","description":"Learn how to run the _Vehicle App_ Runtime Services locally or in Kanto.\n","excerpt":"Learn how to run the _Vehicle App_ Runtime Services locally or in …","ref":"/velocitas-docs/docs/tutorials/vehicle_app_runtime/","tags":"","title":"Vehicle App Runtime"},{"body":"App configuration { \"type\": \"grpc-interface\", \"config\": { \"src\": \"https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto\", // \"required\" indicates you are trying to write a client for the service \"required\": { \"methods\": [ \"Move\", \"CurrentPosition\" ] }, } } Project configuration You need to specify devenv-devcontainer-setup \u003e= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:\n{ \"packages\": { \"devenv-devcontainer-setup\": \"v2.4.2\" }, \"components\": [ { \"id\": \"grpc-interface-support\", } ], } To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2\nExample code To create a client we use the generated SeatsServiceClientFactory.h and seats.grpc.pb.h. These define request and response types and the operations that are available. An example implementation for the SeatService follows:\nmain.cpp #include \u003csdk/middleware/Middleware.h\u003e #include \u003cservices/seats/SeatsServiceClientFactory.h\u003e #include \u003cservices/seats/seats.grpc.pb.h\u003e #include \u003ciostream\u003e using namespace velocitas; int main(int argc, char** argv) { auto serviceClient = SeatsServiceClientFactory::create(Middleware::getInstance()); ::grpc::ClientContext context; ::sdv::edge::comfort::seats::v1::MoveRequest request; ::sdv::edge::comfort::seats::v1::MoveReply response; ::sdv::edge::comfort::seats::v1::Seat seat; ::sdv::edge::comfort::seats::v1::SeatLocation seat_location; seat_location.set_row(1); seat_location.set_index(1); ::sdv::edge::comfort::seats::v1::Position seat_position; // we only set base here to keep the example simple // extend here if yu want to set lumbar etc. seat_position.set_base(1000); seat.set_allocated_location(\u0026seat_location); seat.set_allocated_position(\u0026seat_position); request.set_allocated_seat(\u0026seat); auto status = serviceClient-\u003eMove(\u0026context, request, \u0026response); std::cout \u003c\u003c \"gRPC Server returned code: \" \u003c\u003c status.error_code() \u003c\u003c std::endl; std::cout \u003c\u003c \"gRPC error message: \" \u003c\u003c status.error_message().c_str() \u003c\u003c std::endl; if (status.error_code() == ::grpc::StatusCode::UNIMPLEMENTED) { return 1; } else { ::grpc::ClientContext context; ::sdv::edge::comfort::seats::v1::CurrentPositionRequest request; ::sdv::edge::comfort::seats::v1::CurrentPositionReply response; request.set_row(1); request.set_index(1); auto status_curr_pos = seatService-\u003eCurrentPosition(\u0026context, request, \u0026response); std::cout \u003c\u003c \"current Position:\" \u003c\u003c response.seat().position().base() \u003c\u003c std::endl; std::cout \u003c\u003c \"gRPC Server returned code: \" \u003c\u003c status_curr_pos.error_code() \u003c\u003c std::endl; std::cout \u003c\u003c \"gRPC error message: \" \u003c\u003c status_curr_pos.error_message().c_str() \u003c\u003c std::endl; return 0; } } ","categories":"","description":"Learn how to create a client for a service definition.\n","excerpt":"Learn how to create a client for a service definition.\n","ref":"/velocitas-docs/docs/tutorials/grpc_service_generation/create_client/","tags":"","title":"Create a client"},{"body":"App configuration { \"type\": \"grpc-interface\", \"config\": { \"src\": \"https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto\", // \"provided\" indicates you want to implement the server business logic for the service \"provided\": { } } } Project configuration You need to specify devenv-devcontainer-setup \u003e= v2.4.2 in your project configuration. Therefore your .veloitas.json should look similair to this example:\n{ \"packages\": { \"devenv-devcontainer-setup\": \"v2.4.2\" }, \"components\": [ { \"id\": \"grpc-interface-support\", } ], } To do that you can run velocitas component add grpc-interface-support when your package is above or equal to v2.4.2\nTo create a server that is providing the gRPC service we are leveraging the generated SeatsServiceImpl.h and SeatsServiceServerFactory.h. The SeatsServiceImpl.cpp needs to be filled with the actual implementation of the service. A quick example for a SeatService is described in the following:\nmain.cpp #include \u003csdk/middleware/Middleware.h\u003e #include \u003cservices/seats/SeatsServiceServerFactory.h\u003e #include \"SeatsServiceImpl.h\" #include \u003cmemory\u003e using namespace velocitas; int main(int argc, char** argv) { auto seatsImpl = std::make_shared\u003cSeatsService\u003e(); velocitas::VehicleModelContext::getInstance().setVdbc( velocitas::IVehicleDataBrokerClient::createInstance(\"vehicledatabroker\")); auto seatServer = SeatsServiceServerFactory::create(Middleware::getInstance(), seatsImpl); seatServer-\u003eWait(); return 0; } SeatsServiceImpl.cpp #include \"SeatsServiceImpl.h\" #include \u003csdk/VehicleApp.h\u003e #include \u003csdk/VehicleModelContext.h\u003e #include \u003csdk/vdb/IVehicleDataBrokerClient.h\u003e #include \u003cvehicle/Vehicle.hpp\u003e #include \u003cgrpc/grpc.h\u003e #include \u003cservices/seats/seats.grpc.pb.h\u003e namespace velocitas { ::grpc::Status SeatsService::Move(::grpc::ServerContext* context, const ::sdv::edge::comfort::seats::v1::MoveRequest* request, ::sdv::edge::comfort::seats::v1::MoveReply* response) { (void)context; (void)response; vehicle::Vehicle Vehicle; auto seat = request-\u003eseat(); auto location = seat.location(); auto row = location.row(); auto pos = location.index(); // you would need to extend this to add support for lumbar etc. // Vehicle.Cabin.Seat.Row(row).Pos(pos).Position.set(seat-\u003eposition()-\u003exxxxxx())-\u003eawait(); auto status = Vehicle.Cabin.Seat.Row1.DriverSide.Position.set(seat.position().base())-\u003eawait(); if (status.ok()) { return ::grpc::Status(::grpc::StatusCode::OK, \"\"); } else { return ::grpc::Status(::grpc::StatusCode::CANCELLED, status.errorMessage()); } } ::grpc::Status SeatsService::MoveComponent(::grpc::ServerContext* context, const ::sdv::edge::comfort::seats::v1::MoveComponentRequest* request, ::sdv::edge::comfort::seats::v1::MoveComponentReply* response) { (void)context; (void)request; (void)response; return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\"); } ::grpc::Status SeatsService::CurrentPosition( ::grpc::ServerContext* context, const ::sdv::edge::comfort::seats::v1::CurrentPositionRequest* request, ::sdv::edge::comfort::seats::v1::CurrentPositionReply* response) { (void)context; (void)request; vehicle::Vehicle Vehicle; auto seat = response-\u003emutable_seat(); auto seat_position = seat-\u003emutable_position(); auto seatPos = Vehicle.Cabin.Seat.Row1.DriverSide.Position.get()-\u003eawait().value(); // we only set base here to keep the example simple // extend here if yu want to set lumbar etc. seat_position-\u003eset_base(seatPos); return ::grpc::Status(::grpc::StatusCode::OK, \"\"); } } // namespace velocitas ","categories":"","description":"Learn how to create a server for a service definition.\n","excerpt":"Learn how to create a server for a service definition.\n","ref":"/velocitas-docs/docs/tutorials/grpc_service_generation/create_server/","tags":"","title":"Create a server"},{"body":"This tutorial shows how to generate a basic gRPC service like a seat service. For this example the proto file under https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto is taken.\nAll files included from services/seats are auto-generated and added to the app project as Conan dependency. For writing a complete gRPC service you need two velocitas apps/projects. One is implementing a client and the other one is for providing the server. To complete the server implementation you have to fill the generated *ServiceImpl.cpp. Have a look at the linked content beneath for a tutorial how it would be done for a SeatService leveraging https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto .\nTo run the example you need to start the velocitas app for the server first and then the second velocitas app for the client.\n","categories":"","description":"Learn how to generate and fill your own gRPC services.\n","excerpt":"Learn how to generate and fill your own gRPC services.\n","ref":"/velocitas-docs/docs/tutorials/grpc_service_generation/","tags":"","title":"gRPC service generation"},{"body":"See the Kanto container configuration for details how to write Kanto deployment files.\n","categories":"","description":"Learn how to deploy the _Vehicle App_ to currently supported infrastructure targets.\n","excerpt":"Learn how to deploy the _Vehicle App_ to currently supported …","ref":"/velocitas-docs/docs/tutorials/vehicle_app_deployment/","tags":"","title":"Vehicle App Deployment"},{"body":"To be sure that a newly created Vehicle App will run together with the KUKSA Databroker and potentially other dependant Vehicle Services or Vehicle Apps, it’s essential to write integration tests along with developing the app.\nTo execute an integration test, the dependant components need to be running and be accessible from the test runner. This guide will describe how integration tests can be written and integrated in the CI pipeline so that they are executed automatically when building the application.\nNote This guide is currently only available for development of integration tests with Python. Writing Test Cases To write an integration test, you should check the sample that comes with the template ( /app/tests/integration/integration_test.py ). To support interacting with the MQTT broker and the KUKSA Databroker (to get and set values for data points), there are two classes present in Python SDK that will help:\nMqttClient: this class provides methods for interacting with the MQTT broker. Currently, the following methods are available:\npublish_and_wait_for_response: publishes the specified payload to the given request topic and waits (till timeout) for a message to the response topic. The payload of the first message that arrives in the response topic will be returned. If the timeout expires before, an empty string (\"\") is returned.\npublish_and_wait_for_property: publishes the specified payload to the given request topic and waits (till timeout) until the given property value is found in an incoming message to the response topic. The path describes the property location within the response message, the value the property value to look for.\nExample:\n{ \"status\": \"success\", \"result\": { \"responsecode\": 10 } } If the responsecode property should be checked for the value 10, the path would be [\"result\", \"responsecode\"], property value would be 10. When the requested value has been found in a response message, the payload of that message will be returned. If the timeout expires before receiving a matching message, an empty string (\"\") is returned.\nThis class can be initialized with a given port. If no port is specified, the environment variable MQTT_PORT will be checked. If this is not possible either, the default value of 1883 will be used. It’s recommended to specify no port when initializing that class as it will locally use the default port 1883 and in CI the port is set by the environment variable MQTT_PORT. This will prevent a check-in in the wrong port during local development.\nIntTestHelper: this class provides functionality to interact with the KUKSA Databroker.\nregister_datapoint: registers a new data point with given name and type ( here you can find more information about the available types) set_..._datapoint: set the given value for the data point with the given name (with given type). If the data point does not exist, it will be registered. This class can be initialized with a given port. If no port is specified, the environment variable VDB_PORT will be checked. If this is not possible either, the default value of 55555 will be used. It’s recommended to specify no port when initializing that class as it will locally use the default port 55555 and in CI the port is set by the environment variable VDB_PORT. This will prevent a check-in in the wrong port during local development.\nRuntime components To be able to test the Vehicle App in an integrated way, the following components should be running:\nMosquitto Databroker Vehicle Mock Provider We distinguish between two environments for executing the Vehicle App and the runtime components:\nLocal execution: components are running locally in the development environment Kanto execution: components (and application) are deployed and running in a Kanto control plane Local execution First, make sure that the runtime services are configured and running like described here .\nThe application itself can be executed by using a Visual Studio Launch Config (by pressing F5) or by executing the provided task Local Runtime - Run VehicleApp.\nWhen the runtime services and the application are running, integration tests can be executed locally via\npytest ./app/tests/integration or using the testing tab in the sidebar to the left.\nKanto runtime First, make sure that the runtime and the services are up and running, like described here .\nThe application itself can be deployed by executing the provided task Kanto Runtime - Deploy VehicleApp or Kanto Runtime - Deploy VehicleApp (without rebuild). Depending on whether your app is already available as a container or not.\nWhen the runtime services and the application are running, integration tests can be executed locally via\npytest ./app/tests/integration or using the testing tab in the sidebar to the left.\nIntegration Tests in CI pipeline The tests will be discovered and executed automatically in the provided CI pipeline . The job Run Integration Tests contains all steps to set up and execute all integration tests in the Kanto runtime. Basically it is doing the same steps as you saw above:\nstart the Kanto runtime deploy the Vehicle App container set the correct MQTT and Databroker ports execute the integration tests Finally the test results are collected and published as artifacts of the workflow.\nTroubleshooting Troubleshoot IntTestHelper Make sure that the KUKSA Databroker is up and running by checking the task log. Make sure that you are using the right ports. Make sure that you installed the correct version of the SDK (SDV-package). Troubleshoot Mosquitto (MQTT Broker) Make sure that Mosquitto is up and running by checking the task log. Make sure that you are using the right ports. Use VsMqtt extension to connect to MQTT broker locally (localhost:1883) to monitor topics in MQTT broker by subscribing to all topics using #. Next steps Concept: Deployment Model Concept: Build and release process ","categories":"","description":"Learn how to test that a _Vehicle App_ together with the KUKSA Databroker and potentially other dependant Vehicle Services or _Vehicle Apps_ runs as expected.\n","excerpt":"Learn how to test that a _Vehicle App_ together with the KUKSA …","ref":"/velocitas-docs/docs/tutorials/vehicle_app_development/integration_tests/","tags":"","title":"Vehicle App Integration Testing"},{"body":"Setup a Python Package manually A Vehicle Model should be defined in its own Python Package. This allows to distribute the Vehicle Model later as a standalone package and to use it in different Vehicle App projects.\nThe name of the Vehicle Model package will be my_vehicle_model for this walkthrough.\nStart Visual Studio Code\nSelect File \u003e Open Folder (File \u003e Open… on macOS) from the main menu.\nIn the Open Folder dialog, create a my_vehicle_model folder and select it. Then click Select Folder (Open on macOS).\nCreate a new file setup.py under my_vehicle_model:\nfrom setuptools import setup setup(name='my_vehicle_model', version='0.1', description='My Vehicle Model', packages=['my_vehicle_model'], zip_safe=False) This is the Python package distribution script.\nCreate an empty folder my_vehicle_model under my_vehicle_model.\nCreate a new file __init__.py under my_vehicle_model/my_vehicle_model.\nAt this point the source tree of the Python package should look like this:\nmy_vehicle_model ├── my_vehicle_model │ └── __init__.py └── setup.py To verify that the package is created correctly, install it locally:\npip3 install . The output of the above command should look like this:\nDefaulting to user installation because normal site-packages is not writeable Processing /home/user/projects/my-vehicle-model Preparing metadata (setup.py) ... done Building wheels for collected packages: my-vehicle-model Building wheel for my-vehicle-model (setup.py) ... done Created wheel for my-vehicle-model: filename=my_vehicle_model-0.1-py3-none-any.whl size=1238 sha256=a619bc9fbea21d587f9f0b1c1c1134ca07e1d9d1fdc1a451da93d918723ce2a2 Stored in directory: /home/user/.cache/pip/wheels/95/c8/a8/80545fb4ff73c974ac1716a7bff6f7f753f92022c41c2e376f Successfully built my-vehicle-model Installing collected packages: my-vehicle-model Successfully installed my-vehicle-model-0.1 Finally, uninstall the package again:\npip3 uninstall my_vehicle_model Add Vehicle Models manually Install the Python Vehicle App SDK:\npip3 install git+https://github.com/eclipse-velocitas/vehicle-app-python-sdk.git The output of the above command should end with:\nSuccessfully installed sdv-x.y.z Now it is time to add some Vehicle Models to the Python package. At the end of this section you will have a Vehicle Model, that contains a Cabin model, a Seatmodel and has the following tree structure:\nVehicle └── Cabin └── Seat (Row, Pos) Create a new file Seat.py under my_vehicle_model/my_vehicle_model:\nfrom sdv.model import Model class Seat(Model): def __init__(self, parent): super().__init__(parent) self.Position = DataPointFloat(\"Position\", self) This creates the Seat model with a single data point of type float named Position.\nCreate a new file Cabin.py under my_vehicle_model/my_vehicle_model:\nfrom sdv.model import Model class Cabin(Model): def __init__(self, parent): super().__init__(parent) self.Seat = SeatCollection(\"Seat\", self) class SeatCollection(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Row1 = self.RowType(\"Row1\", self) self.Row2 = self.RowType(\"Row2\", self) def Row(self, index: int): if index \u003c 1 or index \u003e 2: raise IndexError(f\"Index {index} is out of range\") _options = { 1 : self.Row1, 2 : self.Row2, } return _options.get(index) class RowType(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Pos1 = Seat(\"Pos1\", self) self.Pos2 = Seat(\"Pos2\", self) self.Pos3 = Seat(\"Pos3\", self) def Pos(self, index: int): if index \u003c 1 or index \u003e 3: raise IndexError(f\"Index {index} is out of range\") _options = { 1 : self.Pos1, 2 : self.Pos2, 3 : self.Pos3, } return _options.get(index) This creates the Cabin model, which contains a set of six Seat models, referenced by their names or by rows and positions:\nrow=1, pos=1 row=1, pos=2 row=1, pos=3 row=2, pos=1 row=2, pos=2 row=2, pos=3 Create a new file vehicle.py under my_vehicle_model/my_vehicle_model:\nfrom sdv.model import Model from my_vehicle_model.Cabin import Cabin class Vehicle(Model): \"\"\"Vehicle model\"\"\" def __init__(self, name): super().__init__() self.name = name self.Speed = DataPointFloat(\"Speed\", self) self.Cabin = Cabin(\"Cabin\", self) vehicle = Vehicle(\"Vehicle\") The root model of the Vehicle Model tree should be called Vehicle by convention and is specified, by setting parent to None. For all other models a parent model must be specified as the 2nd argument of the Model constructor, as can be seen by the Cabin and the Seat models above.\nA singleton instance of the Vehicle Model called vehicle is created at the end of the file. This instance is supposed to be used in the Vehicle Apps. Creating multiple instances of the Vehicle Model should be avoided for performance reasons.\nAdd a Vehicle Service Vehicle Services provide service interfaces to control actuators or to trigger (complex) actions. E.g. they communicate with the vehicle internal networks like CAN or Ethernet, which are connected to actuators, electronic control units (ECUs) and other vehicle computers (VCs). They may provide a simulation mode to run without a network interface. Vehicle Services may feed data to the Databroker and may expose gRPC endpoints, which can be invoked by Vehicle Apps over a Vehicle Model.\nIn this section, we add a Vehicle Service to the Vehicle Model.\nCreate a new folder proto under my_vehicle_model/my_vehicle_model.\nCopy your proto file under my_vehicle_model/my_vehicle_model/proto\nAs example you could use the protocol buffers message definition seats.proto provided by the KUKSA services which describes a seat control service .\nInstall the grpcio tools including mypy types to generate the Python classes out of the proto-file:\npip3 install grpcio-tools mypy_protobuf Generate Python classes from the SeatService message definition:\npython3 -m grpc_tools.protoc -I my_vehicle_model/proto --grpc_python_out=./my_vehicle_model/proto --python_out=./my_vehicle_model/proto --mypy_out=./my_vehicle_model/proto my_vehicle_model/proto/seats.proto This creates the following gRPC files under the proto folder:\nseats_pb2.py seats_pb2_grpc.py seats_pb2.pyi Create the SeatService class and wrap the gRPC service:\nfrom sdv.model import Service from my_vehicle_model.proto.seats_pb2 import ( CurrentPositionRequest, MoveComponentRequest, MoveRequest, Seat, SeatComponent, SeatLocation, ) from my_vehicle_model.proto.seats_pb2_grpc import SeatsStub class SeatService(Service): \"SeatService model\" def __init__(self): super().__init__() self._stub = SeatsStub(self.channel) async def Move(self, seat: Seat): response = await self._stub.Move(MoveRequest(seat=seat), metadata=self.metadata) return response async def MoveComponent( self, seatLocation: SeatLocation, component: SeatComponent, position: int, ): response = await self._stub.MoveComponent( MoveComponentRequest( seat=seatLocation, component=component, # type: ignore position=position, ), metadata=self.metadata, ) return response async def CurrentPosition(self, row: int, index: int): response = await self._stub.CurrentPosition( CurrentPositionRequest(row=row, index=index), metadata=self.metadata, ) return response Some important remarks about the wrapping SeatService class shown above:\nThe SeatService class must derive from the Service class provided by the Python SDK. The SeatService class must use the gRPC channel from the Service base class and provide it to the _stub in the __init__ method. This allows the SDK to manage the physical connection to the gRPC service and use service discovery of the middleware. Every method needs to pass the metadata from the Service base class to the gRPC call. This is done by passing the self.metadata argument to the metadata of the gRPC call. ","categories":"","description":"Learn how to create a Vehicle Model manually for Python\n","excerpt":"Learn how to create a Vehicle Model manually for Python\n","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_python/","tags":"","title":"Python Manual Vehicle Model Creation"},{"body":"GitHub rate limit exceeded To avoid exceeding GitHubs rate limit we suggest to generate a personal access token in your GitHub settings and set it as an environment variable:\nMac/Linux Windows export GITHUB_API_TOKEN=\u003cyour_api_token\u003e\nset GITHUB_API_TOKEN=\u003cyour_api_token\u003e or Set environment variable via system settings GITHUB_API_TOKEN=\u003cyour_api_token\u003e\nAfter you have set the ENV consider to restart VS Code.\nIt is important that VS Code has access to this ENV during the postCreateCommand inside the devcontainer. If you experienced this error and the devcontainer still has started correctly please run either:\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ ./.devcontainer/scripts/postCreateCommand.sh or\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas init vscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas sync Debugging inside installed packages Open up a seperate VScode window where you can debug installed toolchain packages.\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ code ~/.velocitas/packages Solution to (almost) all problems The following would clean up the VELOCITAS_HOME but afterwards a new project initialization is required.\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ rm -rf ~/.velocitas vscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas init ","categories":"","description":"Known issues and fixes.\n","excerpt":"Known issues and fixes.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/troubleshooting/","tags":"","title":"Troubleshooting"},{"body":"","categories":"","description":"Learn how to distribute a Vehicle Model.\n","excerpt":"Learn how to distribute a Vehicle Model.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/","tags":"","title":"Vehicle Model Distribution"},{"body":"Rationale: Logging application behavior is absolutely necessary for monitoring applications and also track down possible issues.\nLevels In Velocitas, we establish the following log levels, ordered from lowest to highest priority:\nLevel Purpose Examples Debug Display of information to aid debugging of live systems like resolved values, executed lines of code, taken branches etc… \"variable=5\", \"executing branch debug==false\" Info Display of regular, user friendly messages to indicate the current state of the application. \"Startup successful\", \"Application ready\" Warning Deviation from optimal program flow which is tolerable by the application, but not recommended. \"Memory usage exceeding upper bounds!\",\"Usage of deprecated API\" Error Display of a type of failure that is not expected and can lead to unexpected or degraded behavior which may lead to program termination. \"Memory allocation failed!\", \"Unable to persist data\" Critical Display of a failure which leads to system unavailablity due to a missing feature, i.e. a database connection. \"Database not available\",\"Unable to establish connection to server!\" Destination of log levels Historically On *nix systems the philosophy is for programs to be as silent as possible by default. stdout is reserved for regular program output. Logging is never regular program output, it is there for diagnostic reasons\nSee the ls program as an example:\nls integration logs requirements.txt Regular output is written to stdout and should not be poluted by logging because it is designed to be pipeable into other programs.\nWhat does this mean for Vehicle Apps/Services? An app or a service is a long running, self-contained application which is inheritly not designed to execute and terminate quickly such that its output may be piped into other programs. Therefore, stdout would be free to be used for log levels, since there is no “regular output”.\nHowever, due to the inherent nature of logs not being regular problem output and the issue of potentially re-ordering messages when they are directed to different files, in Velocitas we chose to output all logs to stderr:\nHere the overview in table form: Level Target file Debug stderr Info stderr Warning stderr Error stderr Critical stderr References https://julienharbulot.com/python-cli-streams.html https://sematext.com/blog/logging-levels/ https://softwareengineering.stackexchange.com/questions/439462/log-levels-and-stdout-vs-stderr ","categories":"","description":"How logging shall be handled by Vehicle Applications.\n","excerpt":"How logging shall be handled by Vehicle Applications.\n","ref":"/velocitas-docs/docs/concepts/logging/","tags":"","title":"Logging guidelines"},{"body":"Traditionally, the automotive industry was and still is centered around vehicle hardware and the corresponding hardware development and life-cycle management. Software, however, is gaining more and more importance in vehicle development and over the entire vehicle lifetime. Thus, the vehicle and its value to the customer is increasingly defined by software. This transition towards what are termed as software-defined vehicles changes the way in which we innovate, code, deliver and work together. It is a change across the whole mobility value chain and life-cycle: from development and production to delivery and operations of the vehicle.\n","categories":"","description":"","excerpt":"Traditionally, the automotive industry was and still is centered …","ref":"/velocitas-docs/docs/","tags":"","title":"Velocitas"},{"body":"Besides starting the vehicle runtime components locally , another way is to deploy them as containers using Kanto . To start the runtime, we provide VS Code Tasks, a feature of Visual Studio Code. Additional information on tasks can be found here .\nQuick Start: Each step has a task that is defined in /.vscode/tasks.json:\nCore tasks (dependent on each other in the given order):\nKanto - Runtime Up: Starts up the Kanto runtime and deploys the runtime components. Kanto - Build VehicleApp: Builds the VehicleApp. Kanto - Deploy VehicleApp: Deploys the VehicleApp as container in the Kanto runtime. Optional helper tasks:\nKanto - Deploy VehicleApp (without rebuild): Deploys the VehicleApp as container in the Kanto runtime but does not build it upfront. That requires, that the task Kanto - Build VehicleApp has been executed once before. Kanto - Runtime Down: Stops the Kanto runtime and all deployed containers. Run as Bundle: To orchestrate these tasks, you can use the task Kanto - Deploy VehicleApp. This task runs the other tasks in the correct order. You can run this task by clicking F1 and choose Tasks: Run task, then select Kanto - Deploy VehicleApp.\nTasks Management: Visual Studio Code offers various other commands concerning tasks like Start/Terminate/Restart/… You can access them by pressing F1 and typing task. A list with available task commands will appear.\nLogging: Running tasks appear in the Terminals View of Visual Studio Code. From there, you can see the logs of each running task. More detailed logs can be found inside your workspace’s logs directory ./logs/*\nKantUI The Leda team developed a tool to easily work with Kanto. It is similar to K9S for Kubernetes. You can find more details about KantUI in the documentation of Leda .\nIn the devcontainer KantUI is already installed and it can be started via:\nsudo kantui After starting the Kanto runtime with the mentioned tasks above, you will directly see all the running containers in KantUI. Now you could also take a look at the logs, delete or stop single containers. After you deployed your application to Kanto, this container will also show up and can be handled with KantUI.\nMounting folders for FeederCAN Some applications (e.g. FeederCAN) might make it necessary to load custom files from a mounted volume. All the files that are located in [./config/feedercan](https://github.com/eclipse-velocitas/devenv-runtimes/tree/main/config/feedercan) will be automatically mounted into the container. In order to mount files to the directory that is accessible by the application, please refer to the deployment configuration file: runtime-kanto/src/runtime/deployment/feedercan.json .\nUploading custom candump file to FeederCAN FeederCAN requires a candump file. A pre-defined candump file is already part of our delivery, however, if necessary, there is an option to upload a custom file by:\nCreating/updating candump file with the name candumpDefault.log in ./config/feedercan Restarting Kanto (execute the tasks Kanto - Runtime Down and Kanto - Runtime Up) More information about the CAN Provider can be found here Next steps Concept: Deployment Model Concept: Build and release process Tutorial: Start runtime services locally Tutorial: Quickstart ","categories":"","description":"Learn how to run the _Vehicle App_ Runtime Services in Kanto.\n","excerpt":"Learn how to run the _Vehicle App_ Runtime Services in Kanto.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_app_runtime/kanto_runtime/","tags":"","title":"Kanto Runtime"},{"body":" Eclipse Velocitas™ Toolchain for creating containerized in-vehicle applications\nQuickstart Concepts Tutorials The Eclipse project Velocitas™ provides an end-to-end, scalable and modular development toolchain to create containerized in-vehicle applications (Vehicle Apps) that offers a comfortable, fast and efficient development experience to increase the velocity of a development team. Vehicle App Project Template Quick setup of a Vehicle App project with the help of GitHub templates for the supported programming languages including a sample Vehicle App and GitHub Actions workflow, and comfortable setup of the development environment e.g. in Microsoft Visual Studio Code.\nRead more …\nVehicle App Development Model Simplify coding and debugging of Vehicle Apps that access vehicle data points and call vehicle functions using the provided SDK for the different programming languages that delegates to the Vehicle Abstraction Layer.\nRead more …\nVehicle Abstraction Layer Abstracts vehicle make \u0026 model specific properties and capabilities to a common representation. This makes it possible for Vehicle Apps to be portable across different electric and electronic vehicle architectures e.g. the Vehicle Apps do not care whether the seat is controlled via CAN, LIN or some other physical interface.\nRead more …\nGitHub Actions Workflow Blueprint Providing ready-to-use GitHub workflows to check the Vehicle App, build images for multi architectures, scan it, execute integration tests and release the Vehicle App to allow the developer to focus on the development of the Vehicle App.\nRead more …\nAutomated Release Process Providing a release workflow to generate release artifacts and documentation out of the CI workflow results and push it to the GitHub container registry to be used by a deployment system.\nRead more …\nDeployment Model Running and deploying Vehicle App as OCI-compliant container to increase the flexibility to support different programming languages and runtimes to accelerate innovation and development.\nRead more …\n","categories":"","description":"","excerpt":" Eclipse Velocitas™ Toolchain for creating containerized in-vehicle …","ref":"/velocitas-docs/","tags":"","title":""},{"body":" --- title: Community menu: main: weight: 40 --- ","categories":"","description":"","excerpt":" --- title: Community menu: main: weight: 40 --- ","ref":"/velocitas-docs/community/","tags":"","title":""},{"body":"","categories":"","description":"","excerpt":"","ref":"/velocitas-docs/categories/","tags":"","title":"Categories"},{"body":"","categories":"","description":"","excerpt":"","ref":"/velocitas-docs/tags/","tags":"","title":"Tags"}] \ No newline at end of file diff --git a/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json b/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json deleted file mode 100644 index b8f90a52..00000000 --- a/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json +++ /dev/null @@ -1 +0,0 @@ -[{"body":"The open and web based digital.auto offers a rapid prototyping environment to explore and validate ideas of a Vehicle App. digital.auto interacts with different vehicle sensors and actuators via standardized APIs specified by the COVESA Vehicle Signal Specification (VSS) without custom setup requirements. Within the platform you can:\nbrowse, navigate and enhance vehicle signals (sensors, actuators and branches) in the Vehicle API Catalogue mapped to a 3D model of the vehicle. build Vehicle App prototypes in the browser using Python and the Vehicle API Catalogue. test the Vehicle App prototype in a dashboard with 3D animation for API calls. create new plugins, which usually represent UX widgets or remote server communication to enhance the vehicle mockup experience in the playground. collect and evaluate user feedback to prioritize your development portfolio. Start the journey of a Vehicle App As first step open digital.auto , select Get Started in the prototyping section of the landing page and use the Vehicle Model of your choice.\nYou now have the possibility to browse existing vehicle signals for the selected vehicle model which you can use for prototyping your Vehicle App by clicking on Vehicle APIs.\nAdd additional Vehicle APIs If the ideation of your Vehicle App prototype comes with any new Vehicle API which is not part of the standard VSS you also have the option to include it into your pre-selected model by clicking the + New Wishlist API button. After filling out all required fields, simply click the create button - this will commit the new API to the existing model.\nNote For this feature, a digital.auto account is required. Get in touch with us or the digital.auto team in case you want to explore this feature. Prototype an idea of a Vehicle App The next step would be to prototype your idea. To do so:\nClick on Prototype Library of your selected model. Create a new prototype, by clicking on New Prototype and filling out the information or select one from the list. Click on the Open button. Go to the Code section and start your prototype right away. Test the prototype of a Vehicle App Testing of your prototype starts in the Run section. You will find a dashboard consisting all vehicle and application components similar to mockups. The control center on the right side has an integrated terminal showing all of your prototyped outputs as well as a list of all called VSS API’s. The Run button executes all your prototype code from top to bottom. The Debug button allows you to step through your prototype line by line.\nTo get started quickly, the digital.auto team has added a number of widgets to simulate related elements of the vehicle – like doors, seats, light, etc. – and made them available in the playground.\nFeel free to add your own Plugins with widgets for additional car features (maybe an antenna waving a warm “welcome”…?).\nTransfer your prototype into a Velocitas Vehicle App In the previous steps you started with envisioning and prototyping your Vehicle App idea and tested it against mocked vehicle components in digital.auto. The Velocitas team provides a project generator to transfer the prototype from digital.auto into your own development environment where you are able to test it with real Vehicle Services . The generator creates a Vehicle App GitHub repository using your prototype code based on our vehicle-app-python-template . In the ‘Code’ section of your prototype in digital.auto you have the button ‘Create Eclipse Velocitas Project’.\nAfter pressing the button you will be forwarded to GitHub . Login with your GitHub Account and authorize velocitas-project-generator to create the repository for you. You will be redirected to digital.auto and asked for a repository name (equals to the name of the Vehicle App). By clicking on “Create repository”:\nthe project generator takes over your prototype code. the code is adapted to the structure in the vehicle-app-python-template . a new private repository under your specified GitHub User will be created. A successful generation of the repository is followed by a pop-up dialogue with the URL of your repository.\nAmong other things the newly created repository will contain:\nFiles Description /app/src/main.py Main class of the Vehicle App, containing your modified prototype code /app/AppManifest.json Settings file defining required services /app/requirements.txt Requirements file defining all Python dependencies /.devcontainer/ Required scripts and settings to setup the devcontainer in Microsoft Visual Studio Code /.github/workflows/ All required CI/CD pipelines to build, test and deploy the Vehicle App as container image to the GitHub container registry /gen/vehicle_model/ The generated model classes. If your prototype includes any exceptional API you added beforehand our automated vehicle model lifecycle takes care of handling the custom VSS vspec file coming from digital.auto and generates a vehicle_model when starting the devContainer Your prototype Vehicle App transferred into a GitHub repository is now ready to be extended. Clone your newly created repository and open the Vehicle App in Microsoft Visual Studio Code and start to extend it.\nYou can proceed with the following topics:\nStarting development environment Vehicle App Development ","categories":"","description":"Learn how to start a _Vehicle App_ prototype with the playground of digital.auto and integrate it into Velocitas.\n","excerpt":"Learn how to start a _Vehicle App_ prototype with the playground of …","ref":"/velocitas-docs/docs/tutorials/prototyping/digital_auto/","tags":"","title":"digital.auto"},{"body":"Using tasks in Visual Studio Code Overview: If you are developing in Visual Studio Code, the runtime components (like KUKSA Databroker or Vehicle Services) are available for local execution coming from our devenv-runtimes package and are accessible as Tasks, a feature of the Visual Studio Code. Additional information on tasks can be found here .\nStart local runtime: To start local runtime, a task called Local Runtime - Up is available. This task runs the runtime services in the correct order. You can run this task by clicking F1 and choose Tasks: Run task, then select Local Runtime - Up.\nStop local runtime: To stop local runtime, a task called Local Runtime - Down is available. This task stops running runtime services gracefully. You can run this task by clicking F1 and choose Tasks: Run task, then select Local Runtime - Down.\nTasks Management: Visual Studio Code offers various other commands concerning tasks like Start/Terminate/Restart/… You can access them by pressing F1 and typing task. A list with available task commands will appear.\nLogging: Running tasks appear in the Terminals View of Visual Studio Code. From there, you can see the logs of each running task. More detailed logs can be found inside your workspace’s logs directory ./logs/*\nAdd/Change runtime service configuration The configuration for services of our provided local runtime are defined in the runtime.json at the root of the repository devenv-runtimes . For a more detailed view on how to change or add runtime service configuration, please visit: Lifecycle Management Package Development Using KUKSA Databroker CLI A CLI tool is provided for interacting with a running instance of the KUKSA Databroker. It can be started by running the task Local Runtime - VehicleDataBroker CLI(by pressing F1, type Run Task followed by Local Runtime - VehicleDataBroker CLI). The Runtime Local needs to be running for you to be able to use the tool.\nIntegrating a new runtime service into Visual Studio Code Task Integration of a new runtime service can be done by duplicating one of the existing tasks.\nCreate a new service in either a new created Package or branch/fork of devenv-runtimes as already explained above In .vscode/tasks.json, duplicate section from task e.g. Local Runtime - Up, Local Runtime - Run VehicleApp or Local Runtime - VehicleDataBroker CLI Correct names in a new code block Disclaimer: Problem Matcher defined in tasks.json is a feature of the Visual Studio Code Task, to ensure that the process runs in background Run task using [F1 -\u003e Tasks: Run Task -\u003e \u003cYour new task label\u003e] Task should be visible in Terminal section of Visual Studio Code Task CodeBlock helper { \"label\": \"\u003ctask_name\u003e\", \"detail\": \"\u003ctask_description\u003e\", \"type\": \"shell\", \"command\": [ \"velocitas exec runtime-local \u003cservice_id\u003e \u003cargs\u003e\" ], \"presentation\": { \"close\": true, \"reveal\": \"never\" }, \"problemMatcher\": [] } Troubleshooting Problem description: When integrating new services into an existing dev environment, it is highly recommended to use the Visual Studio Code Task Feature. A new service can be easily started by calling it from bash script, however restarting the same service might lead to port conflicts (GRPC Port or APP port). That can be easily avoided by using the Visual Studio Code Task Feature.\nCodespaces If you are using Codespaces, remember that you are working on a remote agent. That’s why it could happen that the tasks are already running in the background. If that’s the case a new start of the tasks will fail, since the ports are already in use. Another possibility to check if the processes are already running, is to check which ports are already open. Check the Ports-tab to view all open ports (if not already open, hit F1 and enter View: Toggle Ports).\nNext steps Tutorial: Quickstart Concept: Deployment Model Concept: Build and release process ","categories":"","description":"Learn how to run the _Vehicle App_ Runtime Services locally.\n","excerpt":"Learn how to run the _Vehicle App_ Runtime Services locally.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_app_runtime/local_runtime/","tags":"","title":"Local Runtime"},{"body":" We recommend that you make yourself familiar with the Vehicle App SDK first, before going through this tutorial.\nThe following information describes how to develop and test the sample Vehicle App that is included in the Python template repository . You will learn how to use the Vehicle App Python SDK and how to interact with the Vehicle Model.\nOnce you have completed all steps, you will have a solid understanding of the development workflow and you will be able to reuse the template repository for your own Vehicle App development project.\nDevelop your first Vehicle App This section describes how to develop your first Vehicle App. Before you start building a new Vehicle App, make sure you have already read this manual:\nQuickstart Once you have established your development environment, you will be able to start developing your first Vehicle App.\nFor this tutorial, you will recreate the Vehicle App that is included with the SDK repository : The Vehicle App allows to change the position of the driver’s seat in the car and also provides its current positions to other applications. A detailed explanation of the use case and the example is available here .\nNote If you don’t like to do the following steps by yourself, you can use the Import example app from SDK task within VS Code to get a working copy of this example into your repository. For details about the import of an example from the SDK look here\nSetting up the basic skeleton of your app At first, you have to create the main Python script called main.py in /app/src. All the relevant code for your new Vehicle App goes there.\nIf you’ve created your app development repository from our Python template repository , the Velocitas CLI create command or via digital.auto prototyping a file with this name is already present and can be adjusted to your needs.\nSetting up the basic skeleton of an app consists of the following steps:\nManage your imports Enable logging Initialize your class Define the entry point of your app Manage your imports Before you start development in the main.py you just created, it will be necessary to include the imports required, which you will understand better later through the development:\nimport asyncio import json import logging import signal from velocitas_sdk.util.log import ( # type: ignore get_opentelemetry_log_factory, get_opentelemetry_log_format, ) from velocitas_sdk.vdb.reply import DataPointReply from velocitas_sdk.vehicle_app import VehicleApp, subscribe_topic from vehicle import Vehicle, vehicle # type: ignore Enable logging The following logging configuration applies the default log format provided by the SDK and sets the log level to INFO:\nlogging.setLogRecordFactory(get_opentelemetry_log_factory()) logging.basicConfig(format=get_opentelemetry_log_format()) logging.getLogger().setLevel(\"INFO\") logger = logging.getLogger(__name__) Initialize your class The main class of your new Vehicle App needs to inherit the VehicleApp provided by the Python SDK .\nclass MyVehicleApp(VehicleApp): In class initialization, you have to pass an instance of the Vehicle Model:\ndef __init__(self, vehicle_client: Vehicle): super().__init__() self.Vehicle = vehicle_client We save the vehicle object to use it in our app. Now, you have initialized the app and can continue developing relevant methods.\nEntry point of your app Here’s an example of an entry point to the MyVehicleApp that we just developed:\nasync def main(): \"\"\"Main function\"\"\" logger.info(\"Starting my VehicleApp...\") vehicle_app = MyVehicleApp(vehicle) await vehicle_app.run() LOOP = asyncio.get_event_loop() LOOP.add_signal_handler(signal.SIGTERM, LOOP.stop) LOOP.run_until_complete(main()) LOOP.close() With this your app can now be started. In order to provide some meaningful behaviour of the app, we will enhance it with more features in the next sections.\nVehicle Model Access In order to facilitate the implementation, the whole vehicle is abstracted into model classes. Please check tutorial about creating models for more details about this topic. In this section, the focus is on using the model.\nThe first thing you need to do is to get access to the Vehicle Model. If you derived your project repository from our template, we already provide a generated model installed as a Python package named vehicle. Hence, in most cases no additional setup is necessary. How to tailor the model to your needs or how you could get access to vehicle services is described in the tutorial linked above.\nIf you want to access a single DataPoint e.g. for the vehicle speed, this can be done via\nvehicle_speed = (await self.Vehicle.Speed.get()).value As the get() method of the DataPoint-class there is a coroutine you have to use the await keyword when using it and access its .value.\nIf you want to get deeper inside the vehicle, to access a single seat for example, you just have to go the model-chain down:\nself.DriverSeatPosition = await self.Vehicle.Cabin.Seat.Row1.DriverSide.Position.get() Subscription to Data Points If you want to get notified about changes of a specific DataPoint, you can subscribe to this event, e.g. as part of the on_start() method in your app.\nasync def on_start(self): \"\"\"Run when the vehicle app starts\"\"\" await self.Vehicle.Cabin.Seat.Row1.DriverSide.Position.subscribe( self.on_seat_position_changed ) Every DataPoint provides a .subscribe() method that allows for providing a callback function which will be invoked on every data point update. Subscribed data is available in the respective DataPointReply object and need to be accessed via the reference to the subscribed data point. The returned object is of type TypedDataPointResult which holds the value of the data point and the timestamp at which the value was captured by the Databroker. Therefore the on_seat_position_changed callback function needs to be implemented like this:\nasync def on_seat_position_changed(self, data: DataPointReply): # handle the event here response_topic = \"seatadjuster/currentPosition\" position = data.get(self.Vehicle.Cabin.Seat.Row1.DriverSide.Position).value # ... Subscription using Annotations The Python SDK also supports annotations for subscribing to data point changes with @subscribe_data_points defined by the whole path to the DataPoint of interest. This would replace the implementation of the Subscription to Data Points @subscribe_data_points(\"Vehicle.Cabin.Seat.Row1.DriverSide.Position\") async def on_seat_position_changed(self, data: DataPointReply): response_topic = \"seatadjuster/currentPosition\" response_data = {\"position\": data.get(self.Vehicle.Cabin.Seat.Row1.DriverSide.Position).value} await self.publish_event(response_topic, json.dumps(response_data)) Similarly, subscribed data is available in the respective DataPointReply object and needs to be accessed via the reference to the subscribed data point.\nServices Services are used to communicate with other parts of the vehicle via remote function calls (RPC). Please read the basics about them here .\nNote Services are not supported by our automated vehicle model lifecycle for the time being. If you need access to services please read\nhere how you can create a model and add services to it manually.\nYou can ignore the following step if you would like to reach the final implementation of the example . The following code snippet shows how to use the MoveComponent() method of the SeatService from the vehicle model:\nlocation = SeatLocation(row=1, index=1) await self.vehicle_client.Cabin.SeatService.MoveComponent( location, BASE, data[\"position\"] ) In order to define which seat you like to move, you have to pass a SeatLocation object as the first parameter. The second argument specifies the component of the seat to be moved. The possible components are defined in the proto files. The last parameter to be passed into the method is the desired position of the component.\nMake sure to use the await keyword when calling service methods, since these methods are asynchronously working coroutines.\nMQTT Interaction with other Vehicle Apps or with the cloud is enabled by using the Mosquitto MQTT Broker. The MQTT broker runs inside a docker container, which is started as part of one of our predefined runtimes .\nIn the quickstart section about the Vehicle App, you already tested sending MQTT messages to the app. In the previous sections, you generally saw how to use Vehicle Models, DataPoints and Services. In this section, you will learn how to combine them with MQTT.\nIn order to receive and process MQTT messages inside your app, simply use the @subscribe_topic annotations from the SDK for an additional method on_set_position_request_received() you have to implement:\n@subscribe_topic(\"seatadjuster/setPosition/request\") async def on_set_position_request_received(self, data_str: str) -\u003e None: logger.info(f\"Got message: {data_str!r}\") data = json.loads(data_str) response_topic = \"seatadjuster/setPosition/response\" response_data = {\"requestId\": data[\"requestId\"], \"result\": {}} # ... The on_set_position_request_received method will now be invoked every time a message is published to the subscribed topic \"seatadjuster/setPosition/response\". The message data (string) is provided as parameter. In the example above the data is parsed from json (data = json.loads(data_str)).\nIn order to publish data to topics, the SDK provides the appropriate convenience method: self.publish_event() which will be added to the on_seat_position_changed callback function from before.\nasync def on_seat_position_changed(self, data: DataPointReply): response_topic = \"seatadjuster/currentPosition\" position = data.get(self.Vehicle.Cabin.Seat.Row1.DriverSide.Position).value await self.publish_event( response_topic, json.dumps({\"position\": position}), ) The above example illustrates how one can easily publish messages. In this case, every time the seat position changes, the new position is published to seatadjuster/currentPosition\nYour main.py should now have a full implementation for class MyVehicleApp(VehicleApp): containing:\n__init__() on_start() on_seat_position_changed() on_set_position_request_received() and last but not least a main() method to run the app.\nCheck the seat-adjuster example to see a more detailed implementation including error handling.\nUnitTests Unit testing is an important part of the development, so let’s have a look at how to do that. You can find some example tests in /app/tests/unit. First, you have to import the relevant packages for unit testing and everything you need for your implementation:\nfrom unittest import mock import pytest from sdv.vehicle_app import VehicleApp from sdv_model.Cabin.SeatService import SeatService # type: ignore from sdv_model.proto.seats_pb2 import BASE, SeatLocation # type: ignore @pytest.mark.asyncio async def test_for_publish_to_topic(): # Disable no-value-for-parameter, seems to be false positive with mock lib with mock.patch.object( VehicleApp, \"publish_event\", new_callable=mock.AsyncMock, return_value=-1 ): response = await VehicleApp.publish_event( str(\"sampleTopic\"), get_sample_request_data() # type: ignore ) assert response == -1 def get_sample_request_data(): return {\"position\": 330, \"requestId\": 123} Looking at a test you notice the annotation @pytest.mark.asyncio. This is required if the test is defined as a coroutine. The next step is to create a mock from all the external dependencies. The method takes 4 arguments: first is the object to be mocked, second the method for which you want to modify the return value, third a callable and the last argument is the return value. After creating the mock, you can test the method and check the response. Use asserts to make your test fail if the response does not match. Check the seat-adjuster unit tests to see a more detailed implementation.\nSee the results Once the implementation is done, it is time to run and debug the app.\nRun your App In order to run the app:\nMake sure the devenv-runtimes \u0026 devenv-devcontainer-setup packages are part of your .velocitas.json (which should be the default). Have a correctly configured app/AppManifest.json . See more Trigger our automated vehicle model lifecycle . (e. g. velocitas init) A runtime needs to be up and running. Read more about it in the run runtime services section. Now chose one of the options to start the VehicleApp under development:\nPress F5 or:\nPress F1 Select command Tasks: Run Task Select Local Runtime - Run VehicleApp Debug your Vehicle App In the introduction about debugging , you saw how to start a debugging session. In this section, you will learn what is happening in the background.\nThe debug session launch settings are already prepared for the VehicleApp in /.vscode/launch.json.\n{ \"configurations\": [ { \"type\": \"python\", \"justMyCode\": false, \"request\": \"launch\", \"name\": \"VehicleApp\", \"program\": \"${workspaceFolder}/app/src/main.py\", \"console\": \"integratedTerminal\", \"env\": { \"SDV_MIDDLEWARE_TYPE\": \"native\", \"SDV_VEHICLEDATABROKER_ADDRESS\": \"grpc://127.0.0.1:55555\", \"SDV_MQTT_ADDRESS\": \"mqtt://127.0.0.1:1883\" } } ] } We specify which python-script to run using the program key.\nYou can adapt the configuration in /.vscode/launch.json and in /.vscode/tasks.json to your needs (e.g., change the ports, add new tasks) or even add a completely new configuration for another Vehicle App.\nOnce you are done, you have to switch to the debugging tab (sidebar on the left) and select your configuration using the dropdown on the top. You can now start the debug session by clicking the play button or F5. Debugging is now as simple as in every other IDE, just place your breakpoints and follow the flow of your Vehicle App.\nNext steps Concept: SDK Overview Tutorial: Deploy runtime services in Kanto Tutorial: Start runtime services locally Tutorial: Creating a Python Vehicle Model Tutorial: Develop and run integration tests for a Vehicle App Concept: Deployment Model ","categories":"","description":"Learn how to develop and test a _Vehicle App_ using Python.\n","excerpt":"Learn how to develop and test a _Vehicle App_ using Python.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_app_development/python_development/","tags":"","title":"Python Vehicle App Development"},{"body":"This page describes\nhow to create a GitHub repository for your Vehicle App development, how to set up and configure the DevContainer-based development environment , and how to build, customize and test the sample Vehicle App included in your freshly created Vehicle App repository. You will learn how to use the Vehicle App SDK, interact with the Vehicle API and work with CI/CD using the pre-configured GitHub Workflows that come with the template repository.\nOnce you have completed all steps, you will have a solid understanding of the development workflow, and you will be able to use one of our template repositories as a starting point for your own Vehicle App development project.\nNote Before you start, we recommend familiarizing yourself with our Basic Concept to understand all mentioned terms.\nPrerequisites Please make sure you did all the prerequisite steps to create comprehensive development environment for your Vehicle App:\nInstall VS Code Install a working container runtime Add the Remote-Containers extension to VS Code via the marketplace or using the command line:\ncode --install-extension ms-vscode-remote.remote-containers How to create your Vehicle App repository? For your (GitHub) organization and Vehicle App repository the name MyOrg/MyFirstVehicleApp is used as a place holder during the rest of the document.\nYou can create your own repository using one of our provided templates or start prototyping via digital.auto.\nUsing Template Velocitas CLI create digital.auto Create your own repository copy from the template repository of your choice:\nPython C++ by clicking the green button Use this template. You don’t have to include all branches. For more information on Template Repositories take a look at this GitHub Tutorial .\nCreate your Vehicle App project via our Velocitas CLI create command from within vehicle-app-template’s devcontainer:\nvelocitas create interactive mode. velocitas create -n MyApp -l python for a skeleton vehicle application. velocitas create -n MyApp -l python -e seat-adjuster for a vehicle application based on the seat adjuster example . To learn how to start prototyping with the playground of digital.auto and integrate it into Velocitas please take a look here .\nHow to start developing? In this section you will learn different possibilities to start developing based on your repository. Basically you can work on your own machine using VS Code’s DevContainer or you can set up the environment on a remote agent, using GitHub Codespaces .\nVS Code GitHub Codespaces The VS Code DevContainer makes it possible to package a complete Vehicle App development environment, including VS Code extensions, Vehicle App SDK , Vehicle App Runtimes and all other development and testing tools into a container which is started directly in VS Code.\nProxy Configuration\nA non proxy configuration is used by default. If you are working behind a corporate proxy you will need to specify proxy settings: Working behind a proxy\nWith following steps you will clone and set up your development environment on your own machine using VS Code.\nClone created MyOrg/MyFirstVehicleApp repository locally using your favorite Git tool Switch the directory to the cloned repository folder, e.g. $ cd MyFirstVehicleApp Open the repository in VS Code via $ code . or via VS Code user interface . A popup appears in the lower right corner with the button Reopen in Container. Click on Reopen in Container. If the popup does not appear, you can also hit F1 and perform the command Dev-Containers: Reopen in Container Wait for the container to be set up The first initializing of the container will take some minutes to build the image and provision all the integrated tools.\nIf the DevContainer build process fails, press F1 and run the command Dev-Containers: Rebuild Container Without Cache. The DevContainer is using the docker-in-docker feature to run docker containers within the container.\nOne of the possibilities to use your newly created repository is to use it inside a GitHub Codespace . You can either try it out directly in the browser or also use it inside VS Code. The main thing to remember is that everything is executed on a remote agent and the browser or VS Code just acts as a “thin-client”.\nTo get started with GitHub Codespaces, you just have to follow a few steps:\nOpen your repository on GitHub (e.g. https://github.com/MyOrg/MyFirstVehicleApp ) Click on the green Code button and select Codespaces on the top Configure your Codespace if needed (defaults to the main branch and a standard agent) Click on create A new window will open where you can see logs for setting up the container. On this window you could now also choose to work with VS Code. The environment remains on a remote agent and VS Code establishes a connection to this machine.\nOnce everything is set up in the Codespace, you can work with it in the same way as with the normal DevContainer inside VS Code.\nBe careful with using GitHub Codespaces in a browser and VS Code locally at the same time: Tasks that are started using a browser session will not show in VS Code environment and vice versa. This might lead to problems.\nYou can find more information about the Vehicle App development in the respective pages .\nHow to start the runtime services? The runtime services (like KUKSA Databroker or Vehicle Services) are required to develop Vehicle Apps and run integration tests.\nCurrently, the supported options to run these services is either locally or via the Kanto runtime .\nLocal Runtime Kanto Runtime A VS Code task called Local Runtime - Up is available to start all necessary services in the correct order.\nPress F1 Select command Tasks: Run Task Select Local Runtime - Up You should see the task Local Runtime - Up being executed on a separate VS Code terminal with the following content:\n$ velocitas exec runtime-local up Hint: Log files can be found in your workspace's logs directory \u003e mqtt-broker running \u003e vehicledatabroker running \u003e seatservice running \u003e feedercan running ✅ Runtime is ready to use! To stop the runtime simply press Ctrl + C.\nA VS Code task called Kanto Runtime - Up is available to start all necessary services in the correct order.\nPress F1 Select command Tasks: Run Task Select Kanto Runtime - Up You should see the task Kanto Runtime - Up being executed on a separate VS Code terminal with the following content:\n$ velocitas exec runtime-kanto up Hint: Log files can be found in your workspace's logs directory \u003e Checking Kanto registry... registry already exists. \u003e Checking Kanto registry... starting registry. \u003e Checking Kanto registry... started. ✅ Configuring controlplane for Kanto... ⠇ Starting Kanto...waiting ✅ Kanto is ready to use! To stop the runtime simply press Ctrl + C or execute the task Kanto Runtime - Down.\nMore information about the runtimes are available here .\nHow to debug your Vehicle App? Warning Debugging functionality is only available when using the Local Runtime . Both given examples are available as part of template.\nNow that the runtime services are all up and running, let’s start a debug session for the Vehicle App.\nPython C++ Open the main source file /app/src/main.py and set a breakpoint in the given method on_get_speed_request_received Press F5 to start a debug session of the Vehicle App and see the log output on the DEBUG CONSOLE To trigger this breakpoint, let’s send a message to the Vehicle App using the mqtt broker that is running in the background.\nOpen VSMqtt extension in VS Code and connect to mosquitto (local) Set Subscribe Topic = sampleapp/getSpeed/response and click subscribe Set Publish Topic = sampleapp/getSpeed Press publish with an empty payload field. Open the main source file /app/src/VehicleApp.cpp and set a breakpoint in the given method onSetPositionRequestReceived Press F5 to start a debug session of the Vehicle App and see the log output on the DEBUG CONSOLE To trigger this breakpoint, let’s send a message to the Vehicle App using the mqtt broker that is running in the background.\nOpen VSMqtt extension in VS Code and connect to mosquitto (local) Set Subscribe Topic = seatadjuster/setPosition/response and click subscribe Set Subscribe Topic = seatadjuster/currentPosition and click subscribe Set Publish Topic = seatadjuster/setPosition/request Set and publish a dummy payload: { \"position\": 300, \"requestId\": 123 } Now your breakpoint in the Vehicle App gets hit and you can inspect everything in your debug session. After resuming execution (F5), a response from your Vehicle App is published to the response topic. You can see the response in the MQTT window.\nHow to trigger the CI Workflow? The provided GitHub workflows are used to build the container image for the Vehicle App, run unit and integration tests and collect the test results.\nThe CI Workflow will be triggered by pushing a change to the main branch of your repository:\nMake modification in any of your files\nNavigate in your terminal to your repository\nCommit and push your change\ngit add . git commit -m \"\u003cexplain your changes\u003e\" git push origin To see the results open the Actions page of your repository on GitHub, go to CI Workflow and check the workflow output.\nHow to release your Vehicle App? Now that the CI Workflow was successful, you are ready to build your first release. The goal is to build a ready-to-deploy container image that is published in the GitHub container registry.\nOpen the Code page of your repository on GitHub Click on Create a new release in the Releases section on the right side Enter a version (e.g. v1.0.0) and click on Publish release GitHub will automatically create a tag using the version number The provided release workflow will be triggered by the release. It creates a release documentation and publishes the container image of the Vehicle App to the GitHub container registry. A detailed description of the workflow can be found here .\nHow to deploy your Vehicle App? After releasing the Vehicle App to the GitHub container registry you might ask how to bring the Vehicle App and the required runtime stack on a device. Here, Eclipse Leda comes into the game.\nPlease read the documentation of Eclipse Leda to get more information.\nNext steps Tutorial: Creating a Vehicle Model Tutorial: Create a Vehicle App Tutorial: Develop and run integration tests for a Vehicle App ","categories":"","description":"Learn how to setup and explore the provided development environment.\n","excerpt":"Learn how to setup and explore the provided development environment.\n","ref":"/velocitas-docs/docs/tutorials/quickstart/quickstart/","tags":"","title":"Quickstart"},{"body":"In the scenario of a car sharing company, the goal is to provide the functionality of automatically adjusting the driver’s seat position based on their preferred settings stored in their profile. When the driver unlocks the car, a request is sent to the vehicle to retrieve the preferred seat position. This is where your implementation begins.\nThe Seat Adjuster Vehicle App receives a MQTT message containing the seat position, which then triggers a seat adjustment command through the Seat Service to change the seat position. Additionally, to ensure convenience for future trips, the car sharing company saves the driver’s preferred seat position and utilizes it accordingly. The Seat Adjuster Vehicle App subscribes to the seat position, receiving updates from the Databroker, which streams data from the Seat Service.\nRequesting new seat position The Customer requests the change of the seat position as MQTT message on the topic seatadjuster/setPosition/request with the payload:\n{\"requestId\": 42, \"position\": 300} The Seat Adjuster Vehicle App that has subscribed to this topic, receives the request to change the seat position as a MQTT message.\nThe Seat Adjuster Vehicle App gets the current vehicle speed from the Databroker, which is fed by the CAN Provider (KUKSA CAN Provider).\nWith the support of the Vehicle App SDK, the Seat Adjuster Vehicle App triggers a seat adjustment command of the Seat Service via gRPC in the event that the speed is equal to zero. Hint: This is a helpful convenience check but not a safety check.\nThe Seat Service moves the seat to the new position via CAN messages.\nThe Seat Service returns OK or an error code as gRPC status to the Seat Adjuster Vehicle App.\nIf everything went well, the Seat Adjuster Vehicle App returns a success message for the topic seatadjuster/setPosition/response with the payload:\n{\"requestId\": 42, \"status\": 0 } Otherwise, an error message will be returned:\n{\"requestId\": 42, \"status\": 1, \"message\": \"\u003cerror message\u003e\" } This success or error message will be returned to the Customer.\nPublishing current seat position If the seat position will be changed by the driver, the new seat position will be sent to the Seat Service via CAN.\nThe Seat Service streams the seat position via gRPC to the KUKSA Databroker since it was registered beforehand.\nThe Seat Adjuster Vehicle App that subscribed to the seat position receives the new seat position from the KUKSA Databroker as a result.\nThe Seat Adjuster Vehicle App publishes this on topic seatadjuster/currentPosition with the payload:\n{\"position\": 350} The Customer who has subscribed to this topic retrieves the new seat position and can store this position to use it for the next trip.\nExample Code You can find an example implementation of a Seat Adjuster Vehicle App here: Seat Adjuster ","categories":"","description":"Provides option to request a new seat position and to publish the current seat position\n","excerpt":"Provides option to request a new seat position and to publish the …","ref":"/velocitas-docs/docs/about/use_cases/seat_adjuster/","tags":"","title":"Seat Adjuster"},{"body":"Overview After you have set up the .velocitas.json for your project configuration , using packages is pretty straight forward.\nCurrently, the packages provided by the Velocitas team are the following: name description devenv-runtimes Containing scripts and configuration for Local and Kanto Runtime Services devenv-devcontainer-setup Basic configuration for the devcontainer, like proxy configuration, post create scripts, entry points for the lifecycle management. devenv-github-workflows Containing github workflow files used by velocitas repositories devenv-github-templates Containing github templates used by velocitas repositories devenv-runtime-local Central configuration for local runtime execution (deprecated) devenv-runtime-k3d Central configuration for k3d runtime execution (deprecated) To see how these provided packages are used inside a .velocitas.json you can use the Python template repository as a reference.\nInstallation The Velocitas CLI - acting as a package manager for Vehicle App repositories - is installed inside our devcontainer-base-images . After creation of a devcontainer a postCreateCommand is configured to be executed which runs:\nvelocitas init which will initialize all packages referenced in your .velocitas.json. That means, it will download them and run their respective onPostInit programs, if any. (e.g, automated model generation ) velocitas sync to sync files provided by some packages. Check the section about our Velocitas CLI to learn more about the background and usage of it.\nVelocitas Home Directory The packages will be downloaded by the Velocitas CLI to ~/.velocitas/packages/\u003cpackage_name\u003e. More Information: VELOCITAS_HOME .\nNext steps Lifecycle Management: Development of Packages Lifecycle Management: Velocitas CLI ","categories":"","description":"Learn how to use velocitas packages.\n","excerpt":"Learn how to use velocitas packages.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/packages/usage/","tags":"","title":"Usage"},{"body":"Velocitas offers a scalable and modular development toolchain for creating containerized Vehicle Apps that offers an easy to use, fast and efficient development experience to increase the velocity of your development team.\nVehicle Apps are implemented on top of a Vehicle Model (which is generated from the underlying semantic models like VSS for a concrete programming language) and its underlying language-specific SDK to provide headless comfort functions or connected application functions like Seat Adjuster, Dog Mode, Trunk Delivery or Data Logging \u0026 triggering.\nExamples ","categories":"","description":"Is Velocitas for me? How does Velocitas help?\n","excerpt":"Is Velocitas for me? How does Velocitas help?\n","ref":"/velocitas-docs/docs/about/use_cases/","tags":"","title":"Use Cases"},{"body":"This guide will help you to import examples provided by the SDK package into your template repository.\nA Visual Studio Code task called Import example app from SDK is available in the /.vscode/tasks.json which can replace your /app directory in your template repository with some example Vehicle Apps from the SDK package.\nTo avoid overwriting existing changes in your /app directory, commit or stash changes before importing the example app. Press F1 Select command Tasks: Run Task Select Import example app from SDK Choose Continue without scanning the output Select seat-adjuster Run the Vehicle App from SDK example The launch settings are already prepared for the VehicleApp in the template repository /.vscode/launch.json. The configuration is meant to be as generic as possible to make it possible to run all provided example apps.\nEvery example app comes with its own /app/AppManifest.json to see which Vehicle Services are configured and needed as a dependency.\nTo start the app: Just press F5 to start a debug session of the example Vehicle App.\nTo debug example, please check How to debug Vehicle App? ","categories":"","description":"Learn how to import examples provided by the _Vehicle App_ SDK.\n","excerpt":"Learn how to import examples provided by the _Vehicle App_ SDK.\n","ref":"/velocitas-docs/docs/tutorials/quickstart/import_examples/","tags":"","title":"Import examples"},{"body":"The Dog Mode Vehicle App consists of the following key features:\nRequest the vehicle’s Heating, Ventilation, and Air Conditioning (HVAC) service to turn the Air Conditioning (AC) ON/OFF The driver can adjust the temperature for a specific degree The Vehicle App observe the current temperature and the battery’s state of charge and react accordingly The driver/owner will be notified whenever the state of the charge drops below a certain value Example Code You can find an example implementation of a dog mode Vehicle App here: Dog Mode ","categories":"","description":"Climate control app that allows drivers to leave their vehicles while keeping the air conditioning system of the vehicle active for their pets.\n","excerpt":"Climate control app that allows drivers to leave their vehicles while …","ref":"/velocitas-docs/docs/about/use_cases/dog_mode/","tags":"","title":"Dog Mode"},{"body":"In the past the recommended runtime would for sure be Docker Desktop . But since Docker Inc. changed their license model it is fair enough for an open source project to look for free alternatives.\nLinux The obvious (and our recommended) “alternative” to Docker Desktop on Linux is to just use the Docker Engine (without Docker Desktop), a pure CLI-based solution available for most popular Linux distributions licensed under the Apache License, version 2.0. Installation instructions can be found here .\nMacOS Since the Docker Engine is not working out of the box on MacOS, a virtualizations tool which helps emulating linux is needed. Fortunately there are several solutions on the market. Good results could be achieved using Colima .\nSetup Colima Please uninstall or at least quit Docker Desktop if you already used it, before starting the setup.\nFor Colima to work properly you need Colima itself and a container client e.g. the Docker client, which is still free to use:\nbrew install colima brew install docker After the installation you need to start the runtime:\ncolima start --cpu x --memory y For M1 Macs it might be necessary to add --arch aarch64\nDocker Desktop uses 5 cores and 12 GB of RAM by default on an M1 MacBook Pro. The equivalent in Colima can be achieved with\ncolima start --cpu 5 --memory 12 That’s all you have to do. After these few steps you can go on with the devcontainer setup.\nMicrosoft Windows There is currently no recommended alternative for Windows except using GitHub codespaces, a cloud-based development environment.\nAn option would be to setup a VM (e.g. with VirtualBox or VMWare) running a Linux system with Docker Engine (see above).\nOther alternatives Besides our recommendations above, there are further alternatives, which are not yet evaluated by this project or have some other drawbacks, blocking a recommendation.\nFor example, you could try Podman / Buildah , which can replace docker run and docker build, respectively. Podman is available for MacOS, Windows, and several Linux distributions. Buildah seems just being available for several Linux distributions.\n","categories":"","description":"Overview about the setup of tested container runtimes\n","excerpt":"Overview about the setup of tested container runtimes\n","ref":"/velocitas-docs/docs/tutorials/quickstart/container_runtime/","tags":"","title":"Install a working container runtime"},{"body":"We know what a pain and how time consuming it can be to setup your environment behind a cooperate proxy. This guide will help you to set it up correctly.\nBe aware that correct proxy configuration depends on the setup of your organization and of course of your personal development environment (hardware, OS, virtualization setup, …). So, we most probably do not cover all issues out there in the developers world. So, we encourage you to share hints and improvements with us.\nHTTP(s) proxy server Install and configure the proxy server as recommended or required by your company. For example you could use PX , which is a HTTP(s) proxy server that allows applications to authenticate through an NTLM or Kerberos proxy server, typically used in corporate deployments, without having to deal with the actual handshake. Px leverages Windows SSPI or single sign-on and automatically authenticates using the currently logged in Windows user account. It is also possible to run Px on Windows, Linux and MacOS without single sign-on by configuring the domain, username and password to authenticate with. (Source: PX )\nInstall your HTTP(s) proxy server Start your HTTP(s) proxy server Docker Desktop You need to install Docker Desktop using the right version. As we recognized a proxy issue in Docker Desktop #12672 we strongly recommend to use a Docker Desktop version \u003e= 4.8.2. In case you have an older version on your machine please update to the current version.\nIn the next step you need to enter your proxy settings:\nOpen Docker Desktop and go to the Settings From Resources, select Proxies Enable Manual proxy configuration Enter your proxy settings, this depends on the configuration you did while setting up your proxy tool e.g.: Web Server (HTTP): http://localhost:3128 Secure Web Server (HTTPS): http://localhost:3128 Bypass: localhost,127.0.0.1 Apply \u0026 Restart. Docker daemon You also have to configure the Docker daemon, which is running the containers basically, to forward the proxy settings. For this you have to add the proxy configuration to the ~/.docker/config.json. Here is an example of a proper config (Port and noProxy settings might differ for your setup):\nWindows MacOS Linux { \"proxies\":{ \"default\":{ \"httpProxy\":\"http://host.docker.internal:3128\", \"httpsProxy\":\"http://host.docker.internal:3128\", \"noProxy\":\"host.docker.internal,localhost,127.0.0.1\" } } } { \"proxies\":{ \"default\":{ \"httpProxy\":\"http://host.docker.internal:3128\", \"httpsProxy\":\"http://host.docker.internal:3128\", \"noProxy\":\"host.docker.internal,localhost,127.0.0.1\" } } } { \"proxies\":{ \"default\":{ \"httpProxy\":\"http://172.17.0.1:3128\", \"httpsProxy\":\"http://172.17.0.1:3128\", \"noProxy\":\"host.docker.internal,localhost,127.0.0.1\" } } } For more details see: Docker Documentation Environment Variables It is required to set the following environment variables:\nHTTP_PROXY - proxy server, e.g. http://localhost:3128 HTTPS_PROXY - secure proxy server, e.g. http://localhost:3128 Windows MacOS Linux set setx HTTP_PROXY \"http://localhost:3128\" setx HTTPS_PROXY \"http://localhost:3128\" echo \"export HTTP_PROXY=http://localhost:3128\" \u003e\u003e ~/.bash_profile echo \"export HTTPS_PROXY=http://localhost:3128\" \u003e\u003e ~/.bash_profile source ~/.bash_profile echo \"export HTTP_PROXY=http://localhost:3128\" \u003e\u003e ~/.bash_profile echo \"export HTTPS_PROXY=http://localhost:3128\" \u003e\u003e ~/.bash_profile source ~/.bash_profile Troubleshooting Solving issues with TLS (SSL) certificate validation using https connections from containers If you are behind a so-called intercept proxy (which you most probably are), you can run into certificate issues: Your corporate proxy works as a “man-in-the-middle” to be able to check the transferred data for malicious content. Means, there is a protected connection between the application in your local runtime environment and the proxy and another from the proxy to the external server your application wants to interact with.\nFor the authentication corporate proxies often use self-signed certificates (certificates which are not signed by a (well-known official) certificate authority. Those kind of certificates need to be added to the database of trusted certificates of your local runtime environment. This task is typically handled by the IT department of your corporation (if the OS and software installed on it is managed by them) and you will not run into problems, normally.\nIf it comes to executing containers, those are typically not managed by your IT department and the proxy certificate(s) is/are missing. So, you need to find a way to install those into the (dev) container you want to execute.\nSee (one of) those articles to get how to achieve that:\nOvercoming Proxy Issues with Docker Containers Docker behind SSL intercepting proxy Initial DevContainer build issue If you experience issues during initial DevContainer build, clean all images and volumes otherwise cache might be used:\nOpen Docker Desktop From Troubleshooting choose Clean / Purge data GitHub rate limit exceeded How to fix can be found at Lifecycle Management Troubleshooting .\n","categories":"","description":"Learn how to setup your docker desktop and Visual Studio Code behind a corporate proxy.\n","excerpt":"Learn how to setup your docker desktop and Visual Studio Code behind a …","ref":"/velocitas-docs/docs/tutorials/quickstart/behind_proxy/","tags":"","title":"Working behind proxy"},{"body":" We recommend that you make yourself familiar with the Vehicle App SDK first, before going through this tutorial.\nThe following information describes how to develop and test the sample Vehicle App that is included in the C++ template repository . You will learn how to use the Vehicle App C++ SDK and how to interact with the Vehicle Model.\nOnce you have completed all steps, you will have a solid understanding of the development workflow and you will be able to reuse the template repository for your own Vehicle App development project.\nDevelop your first Vehicle App This section describes how to develop your first Vehicle App. Before you start building a new Vehicle App, make sure you have already read this manual:\nQuickstart For this tutorial, you will recreate the Vehicle App that is included in the template repository : The Vehicle App allows you to change the position of the driver’s seat in the car and also provides its current positions to other applications. A detailed explanation of the use case and the example is available here .\nSetting up the basic skeleton of your app At first, you have to create the main C++ file which we will call App.cpp in /app/src. All the relevant code for your new Vehicle App goes there. Afterwards, there are several steps you need to consider when developing the app:\nManage your includes Initialize your class Define the entry point of your app Manage your includes Before you start development in the App.cpp you just created, it will be necessary to include all required header files, which you will understand better later through the development:\n#include \"sdk/VehicleApp.h\" #include \"sdk/IPubSubClient.h\" #include \"sdk/IVehicleDataBrokerClient.h\" #include \"sdk/Logger.h\" #include \"vehicle/Vehicle.hpp\" #include \u003cmemory\u003e using namespace velocitas; Initialize your class The main class of your new Vehicle App needs to inherit the VehicleApp provided by the C++ SDK .\nclass MyVehicleApp : public VehicleApp { public: // \u003cremaining code in this tutorial goes here\u003e private: vehicle::Vehicle Vehicle; // this member exists to provide simple access to the vehicle model } In your constructor, you have to choose which implementations to use for the VehicleDataBrokerClient and the PubSubClient. By default we suggest you use the factory methods to generate the default implementations: IVehicleDataBrokerClient::createInstance and IPubSubClient::createInstance. These will create a VehicleDataBrokerClient which connects to the VAL via gRPC and an MQTT-based pub-sub client.\nMyVehicleApp() : VehicleApp(IVehicleDataBrokerClient::createInstance(\"vehicledatabroker\"), // this is the app-id of the KUKSA Databroker in the VAL. IPubSubClient::createInstance(\"MyVehicleApp\")) // the clientId identifies the client at the pub/sub broker {} {} Note The URI of the MQTT broker is by default localhost:1883 and can be set to another address via the environment variable SDV_MQTT_ADDRESS (beginning with C++ SDK v0.3.3) or MQTT_BROKER_URI (SDKs before v0.3.3). Now, you have initialized the app and can continue developing relevant methods.\nEntry point of your app Here’s an example of an entry point to the MyVehicleApp that we just developed:\nint main(int argc, char** argv) { MyVehicleApp app; app.run(); return 0; } With this your app can now be started. In order to provide some meaningful behaviour of the app, we will enhance it with more features in the next sections.\nVehicle Model Access In order to facilitate the implementation, the whole set of vehicle signals is abstracted into model classes. Please check the tutorial about creating models for more details. In this section, the focus is on using the model.\nThe first thing you need to do is to get access to the Vehicle Model. If you derived your project repository from our template, we already provide a generated model as a Conan source package. The library is already referenced as “include folder” in the CMake files. Hence, in most cases no additional setup is necessary. How to tailor the model to your needs or how you could get access to vehicle services is described in the tutorial linked above. In your source code the model is included via #include \"vehicle/Vehicle.hpp\" (as shown above).\nIf you want to read a single signal/data point e.g. for the vehicle speed, the simplest way is to do it via a blocking call and directly accessing the value of the speed:\nauto vehicleSpeed = Vehicle.Speed.get()-\u003eawait().value(); Lets have a look, what this line contains:\nThe term Vehicle.Speed addresses the signal we like to query, i.e. the current speed of the vehicle. The term .get() tells that we want to get/read the current state of that signal from the Data Broker. Behind the scenes this triggers a request-response flow via IPC with the Data Broker. The term -\u003eawait() blocks the execution until the response was received. Finally, the term .value() tries to access the returned speed value. The get() returns a shared_ptr to an AsyncResult which, as the name implies, is the result of an asynchronous operation. We have two options to access the value of the asynchronous result. First we can use await() and block the calling thread until a result is available or use onResult(...) which allows us to inject a function pointer or a lambda which is called once the result is available:\nVehicle.Speed.get() -\u003eonResult([](auto vehicleSpeed){ logger().info(\"Got speed!\"); }) -\u003eonError(auto status){ logger().info(\"Something went wrong communicating to the data broker!\"); }); If you want to get deeper inside to the vehicle, to access a single seat for example, you just have to go the model-chain down:\nauto driverSeatPosition = Vehicle.Cabin.Seat.Row1.Pos1.Position.get()-\u003eawait(); Class TypedDataPointValue If you have a detailed look at the AsyncResult class, you will observe that the object returned by the await() or passed to the onResult callback is not directly the current value of the signal, but instead an object of type TypedDataPointValue. This object does not only contain the current value of the signal but also some additional metadata accessible via these functions:\ngetPath() provides the signal name, i.e. the complete path, getType() provides the data type of the signal, getTimeStamp() provides the timestamp when the current state was received by the data broker, isValid() returns true if the current state represents a valid value of the signal or false otherwise, getFailure() returns the reason, why the current state does not represent a valid value (it returns NONE if the value is valid), getValue() returns the a valid current value. It will throw an InvalidValueException if the current value is invalid for whatever reason. The latter three points lead us to the next chapter.\nFailure Handling As indicated above, there might be reasons/situations why the get operation is not able to deliver a valid value for the requested signal. Those shall be handled properly by any application (that wants “to be more” than a prototype).\nThere are two ways to handle the failure situations:\nEither you can catch the exception thrown by the .value() function: try { auto vehicleSpeed = Vehicle.Speed.get()-\u003eawait().value(); // use the speed value } catch (AsyncException\u0026 e) { // thrown by the await(): Something went wrong on communication level with the data broker } catch (InvalidValueException\u0026 e) { // thrown by .value(): The vehicle speed signal does not contain a valid value, currently } Throwing the InvalidValueException can be avoided if you first check that .isValid() returns true before calling .value(): auto vehicleSpeed = Vehicle.Speed.get()-\u003eawait(); if (vehicleSpeed.isValid()) // Accessing .value() now wont throw an exception auto speed = vehicleSpeed.value() ... } else { // Do your failure handling here switch (vehicleSpeed.getFailure()) { case Failure::INVALID_VALUE: ... break; case ... default: ... } } (isValid() is a convenience function for checking .getFailure() == Failure::NONE.)\nNote If you use the asynchroneous variant, the callback passed to onError is just called to report errors on communication level with the data broker. The validity of the returned signal’s/data point’s value needs to be checked separatly (e.g. via ‘isValid()’)! Failure Reasons There are two levels where errors accessing signal/data points might occure.\nCommunication with the Data Broker (IPC Level) The data broker might be (temporarly) unavailable because\nit’s not yet started up, temporary “stopped” due to a crash or a “live update”, some temporary network issues (if running on a different hardware node), … Errors on the IPC level between the application and the data broker will be reported either via\nan AsyncException thrown by the await() function of the AsyncResult class or calling the function passed to the onError function of the AsyncResult/AsyncSubscription class. Errors on this level always make the overall call fail: If getting/setting multiple data points in a single call, the overall operation will fail. In case of setting multiple signals/data points, this means that none of the signals/data points are set. In case of an error on a subscription, this means that the overall subscription could not be established or is terminated now.\nSignal / Data Point Level Failures on signal/data point level are always reported individually per signal/data point. If accessing multiple signals/data points in a single call, getting or setting some certain signal might be successfully done but another one will report an error or failure.\nThe reasons why a valid value of signal/data point can be missing are explained here: Reported failure Reason Explanation Failure::UNKNOWN_DATAPOINT The addressed signal/data point is “unknown” on the system. This can be a hint for a misconfiguration of the overall system, because no provider is installed in that system which will provide this signal. It can be acceptable, if an application does just “optionally” require access to that signal and would work properly without it being present. Failure::ACCESS_DENIED The application does not have the necessary access rights to the addressed signal/data point. This can be a hint for a misconfiguration of the overall system, but could be also a “normal” situation if the user of the vehicle blocks access to certain signals for that application. Failure::NOT_AVAILABLE The addressed signal/data point is temporary not available. This is a normal situation which will arise, while the provider of that signal is - not yet started up or has not yet passed a value to the data broker, - temporary “stopped” due to a crash or a “live update”, - some temporary network issues (e.g. if the provider is running on a different hardware node), - … Failure::INVALID_VALUE The addressed signal/data point might currently not represent a valid value. This situation means, that the signal is currently provided but just the value itself is not representable, e.g. because the hardware sensor delivers implausible values. Failure::INTERNAL_ERROR The value is missing because of some internal issue in the data broker. This typically points out some misbehaviour within the broker’s implementation - call it “bug”. Failure::NONE No failure state - a valid value is provided. This “failure” reason is used to represent a signal state where a valid value is provided. It is the application developer’s decision if it makes sense to distinguish between the different failure reasons or if some or all of them can be handled as “just one”.\nSubscription to DataPoints If you want to get notified about changes of a specific DataPoint, you can subscribe to this event, e.g. as part of the onStart() method in your app:\nvoid onStart() override { subscribeDataPoints(QueryBuilder::select(Vehicle.Cabin.Seat.Row1.Pos1.Position).build()) -\u003eonItem([this](auto\u0026\u0026 item) { onSeatPositionChanged(std::forward\u003cdecltype(item)\u003e(item)); }) -\u003eonError([this](auto\u0026\u0026 status) { onError(std::forward\u003cdecltype(status)\u003e(status)); }); } void onSeatPositionChanged(const DataPointsResult\u0026 result) { const auto dataPoint = result.get(Vehicle.Cabin.Seat.Row1.Pos1.Position); logger().info(dataPoint-\u003evalue()); // do something with the data point value } The VehicleApp class provides the subscribeDataPoints() method which allows to listen for changes on one or multiple data points. Once a change in any of the data points is registered, the callback registered via AsyncSubscription::onItem() is called. Conversely, the callback registered via AsyncSubscription::onError() is called once there is an error during communication with the KUKSA Databroker.\nThe result passed to the callback registered via onItem() is an object of type DataPointsResult which holds the current state of all data points that were part of the respective subscription. The state of individual data points can be accessed by their reference: result.get(Vehicle.Cabin.Seat.Row1.Pos1.Position))\nNote If you select multiple signals/data points in a single subscription be aware that:\nThe update notification will not only contain those data points whose states were updated, but the state of all data points selected in the belonging subscription. If you don’t want this behaviour, you must subscribe to change notifications for each signal/data point separately. A possible failure state will be reported individually per signal/data point. The reason is, that each signal/data point might come from a different provider, has individual access rights and individual reasons to become invalid. This is also true, if requesting multiple signal/data point states via a single get call. Services Services are used to communicate with other parts of the vehicle via remote procedure calls (RPC). Please read the basics about them here .\nNote This description is outdated!\nServices were not supported by our automated vehicle model lifecycle for some time and could be made available via the\ndescription how you can create a model and add services to it manually.\nIn-between we provide a way to refer gRPC based services by referencing the required proto files from the AppManifest and auto-generated the language-specific stubs. The necessary steps need being described here.\nThe following code snippet shows how to use the moveComponent() method of the SeatService from the vehicle model:\nvehicle::cabin::SeatService::SeatLocation location{1, 1}; Vehicle.Cabin.SeatService.moveComponent( location, vehicle::cabin::SeatService::Component::Base, 300 )-\u003eawait(); In order to define which seat you like to move, you have to pass a SeatLocation object as the first parameter. The second argument specifies the component of the seat to be moved. The possible components are defined in the proto-files. The last parameter to be passed into the method is the final position of the component.\nMake sure to call the await() method when calling service methods or register a callback via onResult() otherwise you don’t know when your asynchronous call will finish.\nMQTT Interaction with other Vehicle Apps or with the cloud is enabled by using the Mosquitto MQTT Broker. When using the provided template repository you can start a MQTT Broker as part the local runtime. More information can be found here .\nIn the quickstart section about the Vehicle App, you already tested sending MQTT messages to the app. In the previous sections, you generally saw how to use Vehicle Models, DataPoints and GRPC Services. In this section, you will learn how to combine them with MQTT.\nIn order to receive and process MQTT messages inside your app, simply use the VehicleApp::subscribeTopic(\u003ctopic\u003e) method provided by the SDK:\nvoid onStart() override { subscribeTopic(\"seatadjuster/setPosition/request\") -\u003eonItem([this](auto\u0026\u0026 item){ onSetPositionRequestReceived(std::forward\u003cdecltype(item)\u003e(item);)}); } void onSetPositionRequestReceived(const std::string\u0026 data) { const auto jsonData = nlohmann::json::parse(data); const auto responseTopic = \"seatadjuster/setPosition/response\"; nlohmann::json respData({{\"requestId\", jsonData[\"requestId\"]}, {\"result\", {}}}); } The onSetPositionRequestReceived method will now be invoked every time a message is created on the subscribed topic seatadjuster/setPosition/response. The message data is provided as a string parameter. In the example above the data is parsed to json (data = json.loads(data_str)).\nIn order to publish data to other subscribers, the SDK provides the appropriate convenience method: VehicleApp::publishToTopic(...)\nvoid MyVehicleApp::onSeatPositionChanged(const DataPointsResult\u0026 result): const auto responseTopic = \"seatadjuster/currentPosition\"; nlohmann::json respData({\"position\": result.get(Vehicle.Cabin.Seat.Row1.Pos1.Position)-\u003evalue()}); publishToTopic( responseTopic, respData.dump(), ); The above example illustrates how one can easily publish messages. In this case, every time the seat position changes, the new position is published to seatadjuster/currentPosition\nSee the results Once the implementation is done, it is time to run and debug the app.\nBuild your App Before you can run the Vehicle App you need to build it first. To do so, simply run the provided build.sh script found in the root of the SDK. It does accept some arguments, but that is out of scope for this tutorial.\nWarning If this is your first time building, you might have to run install_dependencies.sh first. Run your App In order to run the app make sure the devenv-runtimes package is part of your .velocitas.json (which should be the default) and the runtime is up and running. Read more about it in the run runtime services section.\nNow chose one of the options to start the VehicleApp under development:\nPress F5 or:\nPress F1 Select command Tasks: Run Task Select Local Runtime - Run VehicleApp Debug your Vehicle App In the introduction about debugging , you saw how to start a debugging session. In this section, you will learn what is happening in the background.\nThe debug session launch settings are already prepared for the VehicleApp.\n{ \"configurations\": [ { \"name\": \"VehicleApp - Debug (Native)\", \"type\": \"cppdbg\", \"request\": \"launch\", \"program\": \"${workspaceFolder}/build/bin/app\", \"args\": [ ], \"stopAtEntry\": false, \"cwd\": \"${workspaceFolder}\", \"environment\": [ { \"name\": \"SDV_MIDDLEWARE_TYPE\", \"value\": \"native\" }, { \"name\": \"SDV_VEHICLEDATABROKER_ADDRESS\", \"value\": \"127.0.0.1:55555\" }, { \"name\": \"SDV_MQTT_ADDRESS\", \"value\": \"127.0.0.1:1883\" } ], \"externalConsole\": false, \"MIMode\": \"gdb\", \"setupCommands\": [ ], } ] } We specify which binary to run using the program key. In the environment you can specify all needed environment variables. You can adapt the JSON to your needs (e.g., change the ports, add new tasks) or even add a completely new configuration for another Vehicle App.\nOnce you are done, you have to switch to the debugging tab (sidebar on the left) and select your configuration using the dropdown on the top. You can now start the debug session by clicking the play button or F5. Debugging is now as simple as in every other IDE, just place your breakpoints and follow the flow of your Vehicle App.\nNext steps Concept: SDK Overview Concept: Deployment Model Tutorial: Deploy runtime services in Kanto Tutorial: Start runtime services locally Tutorial: Creating a Vehicle Model Tutorial: Develop and run integration tests for a Vehicle App ","categories":"","description":"Learn how to develop and test a _Vehicle App_ using C++.\n","excerpt":"Learn how to develop and test a _Vehicle App_ using C++.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_app_development/cpp_development/","tags":"","title":"C++ Vehicle App Development"},{"body":"Getting started First thing you need to do is to create a repository at e.g., https://github.com/my-organisation/my-velocitas-package. The URL needs to be referenced in the .velocitas.json of your Vehicle App repository.\nGeneral configuration of Packages Every Package repository needs a manifest.json at their root. The manifest.json is the package configuration and holds package relevant information and its behaviour.\nHere are examples of this configuration:\ndevenv-runtimes manifest devenv-devcontainer-setup manifest The manifest of a package describes a list of components. They are a collection of programs or files that serve a similar purpose or are inheritly connected. I.e. they provide a single runtime, a deployment for a runtime or add configuration required for Github Workflows or the devcontainer. More detailed information and explanation about configuration fields of the manifest.json and package development can be found here .\nConfiguration of Runtime Packages If you want to add a new service, adapt runtime.json and manifest.json . In order to use a newly created or updated service, new changes on devenv-runtimes need to be tagged and referenced inside .velocitas.json of the respective package version via a tag or branch name of the repository. When a version is changed in your .velocitas.json you have to initialize it through velocitas init from the terminal so the new package version will be installed. A new service can be started by using velocitas cli command velocitas exec runtime-local \u003cservice_id\u003e \u003cargs\u003e which can be also configured inside your ./.vscode/tasks.json.\nIf you plan to develop a Package with the purpose of managing the runtime used together with your Vehicle App the package needs a runtime.json at their root. The runtime.json is the runtime configuration containing all information for the relevant service dependencies with the following three required attributes:\nProperty Description id unique service id interfaces used for dependency resolution between Vehicle App and runtime config configurations in form of Key/Value pair with specific pre–defined keys and corresponding values Supported config keys of a service Key Value Description image URI of a container image port port number port-forward port mapping for forwarding env environment variable used by the service: \u003cenv_key\u003e=\u003cenv_value\u003e mount path for mounting files: \u003csource_path\u003e:\u003ctarget_path\u003e arg argument for starting the service start-pattern optional start pattern for identifying if the service starts correctly Runtime configuration helper { \"id\": \"\u003cservice_id\u003e\", \"interfaces\": [ \"\u003cinterface\u003e\" ], \"config\": [ { \"key\": \"image\", \"value\": \"\u003cimage\u003e:\u003ctag\u003e\" }, { \"key\": \"port\", \"value\": \"\u003cport_number\u003e\" }, { \"key\": \"port-forward\", \"value\": \"\u003csource_port\u003e:\u003ctarget_port\u003e\" }, { \"key\": \"env\", \"value\": \"\u003cenv_key\u003e=\u003cenv_value\u003e\" }, { \"key\": \"mount\", \"value\": \"\u003csource_path\u003e:\u003ctarget_path\u003e\" }, { \"key\": \"arg\", \"value\": \"\u003carg\u003e\" }, { \"key\": \"start-pattern\", \"value\": \".*Listening on \\\\d+\\\\.\\\\d+\\\\.\\\\d+\\\\.\\\\d+:\\\\d+\" } ] } In order to use a newly created or updated service, changes on the respective Package need to be tagged and referenced inside the .velocitas.json of your Vehicle App repository via a tag or branch name of the repository. More info about installation: Usage .\nNote A new service can be started manually and/or configured inside your ./.vscode/tasks.json with: velocitas exec runtime-\u003cruntime\u003e \u003cservice_id\u003e \u003cargs\u003e Next steps Lifecycle Management: Velocitas CLI ","categories":"","description":"Learn how to develop an own package.\n","excerpt":"Learn how to develop an own package.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/packages/development/","tags":"","title":"Development"},{"body":"Services can make sure, that when you write a VSS data point, something is actually happening. Eclipse Velocitas has an example seat or hvac service. If your Vehicle App makes use of e.g. Vehicle.Cabin.Seat.Row1.Pos1.Position or other seat/hvac specific data points you are in for some real action. To learn more, visit Vehicle Services .\nOur maintained devenv-runtimes package ( Velocitas Lifecycle Management ) comes with the support of adding further Vehicle Services to the runtime.json of a package. More information here .\nModify existing services For more advanced usage you can also try to modify existing services. Check out the seat service for example, modify it and integrate it into your Vehicle App repository.\nCreate your own services If you want to create your own service the KUKSA.VAL Services repository contains examples illustrating how such kind of vehicle services can be built. You need to write an application that talks to KUKSA.VAL listening to changes of a target value of some VSS data point and then do whatever you want. You can achieve this by using the KUKSA.VAL gRPC API with any programming language of your choice (learn more about gRPC ).\nMock Provider and Mock Provider Integration The Vehicle Mock Provider is a dummy service allowing to control all specified actuator- and sensor-signals via a configuration file. These configuration files are expressed in a Python-based domain-specific language (DSL). The default behavior is predefined in mock.py The Mock Provider is already integrated in all our Vehicle Runtimes . To be able to configure it, you need to add a custom mock.py in the root of your Vehicle App Project. The Mock Provider Container will pick it up automatically.\n","categories":"","description":"Learn how to integrate a _Vehicle Service_ that executes the request of your _Vehicle App_ on vehicle side\n","excerpt":"Learn how to integrate a _Vehicle Service_ that executes the request …","ref":"/velocitas-docs/docs/tutorials/prototyping/service_integration/","tags":"","title":"Service Integration"},{"body":"The Velocitas development model is centered around what are known as Vehicle Apps . Automation allows engineers to make high-impact changes frequently and deploy Vehicle Apps through cloud backends as over-the-air updates. The Vehicle App development model is about speed and agility paired with state-of-the-art software quality.\nDevelopment Architecture Velocitas provides a flexible development architecture for Vehicle Apps . The following diagram shows the major components of the Velocitas stack.\nVehicle Apps The Vehicle Applications (Vehicle Apps) contain the business logic that needs to be executed on a vehicle. A Vehicle App is implemented on top of a Vehicle Model and its underlying language-specific SDK . Many concepts of cloud-native and twelve-factor applications apply to Vehicle Apps as well and are summarized in the next chapter.\nVehicle Models A Vehicle Model makes it possible to easily get vehicle data from the Databroker and to execute remote procedure calls over gRPC against Vehicle Services and other Vehicle Apps . It is generated from the underlying semantic models for a concrete programming language as a graph-based, strongly-typed, intellisense-enabled library. The elements of the vehicle models are defined by the SDKs .\nSDKs Our SDKs, available for different programming languages, are the foundation for the vehicle abstraction provided by the vehicle model Furthermore, they offer abstraction from the underlying middleware and communication protocols, besides providing the base classes and utilities for the Vehicle Apps. SDKs are available for Python and C++, currently. Further SDKs for Rust and C are planned.\nVehicle Services Vehicle Services provide service interfaces to control actuators or to trigger (complex) actions. E.g. they communicate with the vehicle internal networks like CAN or Ethernet, which are connected to actuators, electronic control units (ECUs) and other vehicle computers (VCs). They may provide a simulation mode to run without a network interface. Vehicle services may feed data to the Databroker and may expose gRPC endpoints, which can be invoked by Vehicle Apps over a Vehicle Model .\nKUKSA Databroker Vehicle data is stored in the KUKSA Databroker conforming to an underlying Semantic Model like VSS . Vehicle Apps can either pull this data or subscribe for updates. In addition, it supports rule-based access to reduce the number of updates sent to the Vehicle App.\nSemantic models The Vehicle Signal Specification ( VSS ) provides a domain taxonomy for vehicle signals and defines the vehicle data semantically, which is exchanged between Vehicle Apps and the Databroker.\nThe Vehicle Service Catalog ( VSC ) extends VSS with functional remote procedure call definitions and semantically defines the gRPC interfaces of Vehicle Services and Vehicle Apps.\nAs an alternative to VSS and VSC, vehicle data and services can be defined semantically in a general IoT modelling language like Digital Twin Definition Language ( DTDL ) or BAMM Aspect Meta Model BAMM as well.\nThe Velocitas SDK is using VSS as the semantic model for the Vehicle Model.\nCommunication Protocols Asynchronous communication between Vehicle Apps and other vehicle components, as well as cloud connectivity, is facilitated through MQTT messaging. Direct, synchronous communication between Vehicle Apps , Vehicle Services and the Databroker is based on the gRPC protocol.\nMiddleware Abstraction Velocitas basically provides middleware abstraction interfaces for service discovery, pubsub messaging, and other cross-cutting functionalites. At the moment, Velocitas just offers a (what we call) “native middleware” implementation, which does not provide (gRPC) service discovery. Instead, addresses and port number of services need to be provided via environment variables to an app; e.g. SDV_VEHICLEDATABROKER_ADDRESS=grpc://localhost:55555. The support of Dapr as middleware has recently been removed.\nVehicle Edge Operating System Vehicle Apps are expected to run on a Linux -based operating system. An OCI-compliant container runtime is required to host the Vehicle App containers. For publish/subscribe messaging a MQTT broker must be available (e.g., Eclipse Mosquitto ).\nVehicle App Characteristics The following aspects are important characteristics for Vehicle Apps :\nCode base: Every Vehicle App is stored in its own repository. Tracked by version control, it can be deployed to multiple environments.\nPolyglot: Vehicle Apps can be written in any programming language. System-level programming languages like Rust and C/C++ are particularly relevant for limited hardware resources found in vehicles, but higher-level languages like Python and JavaScript are also considered for special use cases.\nOCI-compliant containers: Vehicle Apps are deployed as OCI-compliant containers. The size of these containers should be minimal to fit on constrained devices.\nIsolation: Each Vehicle App should execute in its own process and should be self-contained with its interfaces and functionality exposed on its own port.\nConfigurations: Configuration information is separated from the code base of the Vehicle App, so that the same deployment can propagate across environments with their respective configuration applied.\nDisposability: Favor fast startup and support graceful shutdowns to leave the system in a correct state.\nObservability: Vehicle Apps provide traces, metrics and logs of every part of the application using Open Telemetry.\nOver-the-air update capability: Vehicle Apps can be deployed via cloud backends like Pantaris and updated in vehicles frequently over the air through NextGen OTA updates .\nDevelopment Process The starting point for developing Vehicle Apps is a Semantic Model of the vehicle data and vehicle services. Based on the Semantic Model, language-specific Vehicle Models are generated. Vehicle Models are then distributed as packages to the respective package manager of the chosen programming language (e.g. pip, cargo, npm, …).\nAfter a Vehicle Model is available for the chosen programming language, the Vehicle App can be developed using the generated Vehicle Model and its SDK.\nFurther information ","categories":"","description":"Learn more about provided development model for _Vehicle Apps_.\n","excerpt":"Learn more about provided development model for _Vehicle Apps_.\n","ref":"/velocitas-docs/docs/concepts/development_model/","tags":"","title":"Development Model"},{"body":"The Velocitas project provides a two-stage process for development, continuous integration, and release of a new version of a Vehicle App.\nStage 1 - Build \u0026 Test On every new push to the main branch or every update to a pull request, a GitHub workflow is automatically executed to build your application as a container (optionally for different platforms), runs automated tests and code quality checks, and stores all results as GitHub artifacts for future reference with a default retention period of 90 days .\nThe workflow provides a quick feedback during development and improves efficient collaboration.\nStage 2 - Release Once the application is ready to be released in a new version, a dedicated release workflow is automatically executed as soon as you create a new release via GitHub.\nThe release workflow bundles all relevant images and artifacts into one tagged set of files and pushes it to the GitHub Container Registry. In addition, all the information needed for quality assurance and documentation are published as release artifacts on GitHub. The image pushed to the GitHub Container Registry can afterwards be deployed on your target system using the Over-The-Air (OTA) update system of your choice.\nThe drawing below illustrates the different workflows, actions and artifacts that are automatically created for you. All workflows are intended as a sensible baseline and can be extended and adapted to the needs of your own project.\nCI Workflow ( ci.yml ) The Continuous Integration (CI) workflow is triggered on every commit to the main branch or when creating/updating a pull request and contains a set of actions to achieve the following objectives:\nBuilding a container for the Vehicle App - actions create a containerized version of the Vehicle App. Scanning for vulnerabilities - actions scan your code and container for vulnerabilities and in case of findings the workflow will be marked as “failed”. Running integration tests - actions provision a runtime instance and deploy all required services as containers together with your containerized application to allow for automatically executing integration test cases. In case the test cases fail, the workflow will be marked as “failed”. Running unit tests \u0026 code coverage - actions run unit tests and calculate code coverage for your application, in case of errors or unsatisfactory code coverage, the workflow will be marked as “failed”. Storing scan \u0026 test results as GitHub action artifacts - actions store results from the previously mentioned actions for further reference or download as Github Action Artifacts. Check out the example GitHub workflows in our template repository for Python Build multi-arch image Workflow ( build-multiarch-image.yml ) The Build multi-arch image workflow is triggered on every commit to the main branch and contains a set of actions to achieve the following objectives:\nBuilding a multi-arch container for the app - actions create a containerized version of the Vehicle App for multiple architectures (currently AMD64 and ARM64). Scanning for vulnerabilities - actions scan your code and container for vulnerabilities and in case of findings the workflow will be marked as “failed”. Storing container images to GitHub action artifacts - at the end of the workflow, the container image created is stored in a Github Action Artifacts so that it can be referenced by the Release Workflow later. Release Workflow ( release.yml ) The Release workflow is triggered as soon as the main branch is ready for release and the Vehicle App developer creates a new GitHub release. This can be done manually through the GitHub UI.\nOn creating a new release with a specific new version, GitHub creates a tag and automatically runs the Release workflow defined in .github/workflows/release.yml, given that CI workflow has run successfully for the current commit on the main branch.\nThe set of actions included in the Release workflow cover the objective:\nGenerating and publishing QA information - actions load the QA information from GitHub artifacts stored for the same commit reference and verify it. Additionally, release documentation is generated and added to the GitHub release. If there is no information available for the current commit, the release workflow will fail. Publish as GitHub pages - all information from the release together with the project documentation is built as a static page using hugo. The result is pushed to a separate branch and can be published as a GitHub page in your repository. Pull \u0026 label container image - actions pull the Vehicle App container image based on the current commit hash from the GitHub artifacts and label it with the specified tag version. If the image cannot be found, the workflow will fail. Push container image to ghcr.io - finally the labeled container image is pushed to the GitHub container registry and can be used as a deployment source. GitHub Actions artifacts GitHub Actions artifacts are used for storing data, which is generated by the CI workflow and referenced by the Release workflow. This saves time during workflow runs because we don’t have to create artifacts multiple times.\nGitHub Actions artifacts always have a retention period, which is 90 days by default. This may be configured differently in the specific GitHub organization. After this period, the QA info gets purged automatically. In this case, a re-run of the CI workflow would be required to regenerate all QA info needed for creating a release.\nContainer Registry The GitHub container registry is used for storing container images pushed by the Release workflow. These images can easily be used for a deployment and don’t have a retention period. Since the registry does not have an automatic cleanup, it keeps container images as long as they are not deleted. It is recommended that you automate the removal of older images to limit storage size and costs.\nVersioning Vehicle App image versions are set to the Git tag name during release. Though any versioning scheme can be adopted, the usage of semantic versions is recommended.\nIf the tag name contains a semantic version, the leading v will be trimmed. Example: A tag name of v1.0.0 will lead to version 1.0.0 of the Vehicle App container.\nMaintaining multiple versions If there is a need to maintain multiple versions of a Vehicle App, e.g., to hotfix the production version while working on a new version at the same time or to support multiple versions in production, create and use release branches.\nThe release process would be the same as described in the overview, except that a release branch (e.g., release/v1.0) is created before the release step and the GitHub release is based on the release branch rather than the main branch. For hotfixes, release branches may be created retroactively from the release tag, if needed.\nFurther information Tutorial: How to write integration tests ","categories":"","description":"Learn more about the provided continuous integration, and release process of a _Vehicle App_.\n","excerpt":"Learn more about the provided continuous integration, and release …","ref":"/velocitas-docs/docs/concepts/deployment_model/vehicle_app_releases/","tags":"","title":"Build and Release Process"},{"body":"The Velocitas project uses a common deployment model. It uses OCI-compliant containers to increase the flexibility for the support of different programming languages and runtimes, which accelerates innovation and development. OCI-compliant containers also allow for a standardized yet flexible deployment process, which increases the ease of operation. Using OCI-compliant is portable to different architectures as long as there is support for OCI-compliant containers on the desired platform (e.g., like a container runtime for arm32, arm64 or amd64).\nGuiding principles The deployment model is guided by the following principles\nApplications are provided as OCI-compliant container images. The container runtime offers a control plane and API to manage the container lifecycle. The template projects provided come with a pre-configured developer toolchain that accelerates the development process. The developer toolchain ensures an easy creation through a high-degree of automation of all required artifacts needed to follow the Velocitas principles.\nTesting your container during development The Velocitas project provides for developers a repository template and devcontainer that contains everything to build a containerized version of your app locally and test it. Check out our tutorial e.g., for the Python template to learn more.\nAutomated container image builds Velocitas uses GitHub workflows to automate the creation of your containerized application. A workflow is started with every increment of your application code that you push to your GitHub repository. The workflow creates a containerized version of your application and stores this container image in a registry. Further actions are carried out using this container (e.g., integration tests).\nThe workflows are set up to support multi-platform container creation and generate container images for amd64 and arm64 out of the box. This provides a great starting point for developers and lets you add additional support for further platforms easily.\nFurther information ","categories":"","description":"Learn more about our deployment model and guiding principles.\n","excerpt":"Learn more about our deployment model and guiding principles.\n","ref":"/velocitas-docs/docs/concepts/deployment_model/","tags":"","title":"Deployment Model"},{"body":"\nRepository Description vehicle-app-python-template GitHub Template repository contains an exemplary Vehicle App that uses an exemplary SDK to provide access to vehicle data points and methods. The sample SDK extends the sdv-vehicle-app-python-sdk. In addition the template repository contains the development environment for Visual Studio Code for a Vehicle App as well as the CI/CD workflows that can be used as blueprint for your own Vehicle App written in Python. vehicle-app-python-sdk Provides basic functionality to write a SDK to allow access to vehicle data points and method. This includes publishing \u0026 subscribe messaging, VehicleApp API, vehicle data model ontology and function-based query \u0026 rule support. vehicle-model-python Basic vehicle model for Python is generated from VSS with addition of some specialized vehicle services. vehicle-app-cpp-template GitHub Template repository contains an exemplary Vehicle App that uses an exemplary SDK to provide access to vehicle data points and methods. The sample SDK extends the sdv-vehicle-app-cpp-sdk. In addition the template repository contains the development environment for Visual Studio Code for a Vehicle App as well as the CI/CD workflows that can be used as blueprint for your own Vehicle App written in C++. vehicle-app-cpp-sdk Provides basic functionality to write a SDK to allow access to vehicle data points and method. This includes publishing \u0026 subscribe messaging, VehicleApp API, vehicle data model ontology and function-based query \u0026 rule support. vehicle-model-cpp Basic vehicle model for C++ is generated from VSS with addition of some specialized vehicle services. kuksa-databroker Is a part of the Vehicle Abstraction Layer (VAL) of the Eclipse KUKSA project and provides the KUKSA Databroker. The KUKSA Databroker offers data points available in the vehicle to the Vehicle Apps semantically aligned to a data model like the Vehicle Signal Specification (VSS) . kuksa-can-provider The KUKSA CAN Provider is a generic data feeder that reads data from the vehicle’s CAN bus defined by a DBC file, maps them to a set of data points (e.g. according to the VSS) and feeds it into the Databroker. kuksa.val.services Provides exemplary vehicle services and respective implementations that illustrates how to interact with in-vehicle components and services via an unified access that is semantically described e.g. in the Vehicle Service Catalog (VSC) . release-documentation-action GitHub Action to generate a release documentation from the CI workflow output by rendering it to markdown files so that this can be easily published with GitHub Pages. license-check GitHub Action to collect the licenses of the used components and can be configured to fail with an error message on invalid licenses. vehicle-model-generator Provides basic functionality to create a vehicle model from the given vspec specification for the target programming cli The CLI implements Velocitas lifecyle management concept of the development environment of a Vehicle App. It allows us to take care of the development environment while you focus on the business logic of your Vehicle App. devcontainer-base-images Central configuration to create base docker images for specific languages to be used in devcontainer Package Repositories Repository Description devenv-runtimes Central configuration for maintained runtime services devenv-devcontainer-setup Central configuration for setting up devcontainer environment devenv-github-workflows Central configuration for syncing github workflows devenv-github-templates Central configuration for syncing github templates devenv-runtime-local Central configuration for local runtime execution (deprecated) devenv-runtime-k3d Central configuration for k3d runtime execution (deprecated) ","categories":"","description":"The repositories of the Eclipse _Velocitas_ and their relations between each other\n","excerpt":"The repositories of the Eclipse _Velocitas_ and their relations …","ref":"/velocitas-docs/docs/about/repository-overview/","tags":"","title":"Repository Overview"},{"body":" Providing CLI package Interface type-key devenv-devcontainer-setup vehicle-signal-interface The Vehicle Signal Interface formerly known as Vehicle Model interface type creates an interface to a signal interface described by the VSS spec. This interface will generate a source code package equivalent to the contents of your VSS JSON automatically upon devContainer creation.\nIf a Vehicle App requires a vehicle-signal-interface, it will act as a consumer of datapoints already available in the system. If, on the other hand, a Vehicle App provides a vehicle-signal-interface, it will act as a provider (formerly feeder in KUKSA terms) of the declared datapoints.\nFurthermore, in the source code generated by this functional interface, a connection to KUKSA Databroker will be established via the configured Velocitas middleware. It uses the broker.proto if provided by the KUKSA Databroker to connect via gRPC. A seperate declaration of a grpc-interface for the databroker is NOT required.\nMore information: Vehicle Model Creation Configuration structure Attribute Type Example value Description src string \"https://github.com/COVESA/vehicle_signal_specification/releases/download/v3.0/vss_rel_3.0.json\" URI of the used COVESA Vehicle Signal Specification JSON export. URI may point to a local file or to a file provided by a server. datapoints object Object containing both required and provided datapoints. datapoints.required array Array of required datapoints. datapoints.required.[].path string Vehicle.Speed Path of the VSS datapoint. datapoints.required.[].optional boolean? true, false Is the datapoint optional, i.e. can the Vehicle App work without the datapoint being present in the system. Defaults to false. datapoints.required.[].access string read, write What kind of access to the datapoint is needed by the application. datapoints.provided array Array of provided datapoints. datapoints.provided.[].path string Vehicle.Cabin.Seat.Row1.Pos1.Position Path of the VSS datapoint. Example { \"type\": \"vehicle-signal-interface\", \"config\": { \"src\": \"https://github.com/COVESA/vehicle_signal_specification/releases/download/v3.0/vss_rel_3.0.json\", \"datapoints\": { \"required\": [ { \"path\": \"Vehicle.Speed\", \"access\": \"read\" }, { \"path\": \"Vehicle.Body.Horn.IsActive\", \"optional\": true, \"access\": \"write\" } ], \"provided\": [ { \"path\": \"Vehicle.Cabin.Seat.Row1.Pos1.Position\" } ] } } } ","categories":"","description":"The functional interface for providing vehicle signal access via VSS specification.\n","excerpt":"The functional interface for providing vehicle signal access via VSS …","ref":"/velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/interfaces/vehicle_signal_interface/","tags":"","title":"Vehicle Signal Interface"},{"body":"","categories":"","description":"Learn more about logical interfaces.\n","excerpt":"Learn more about logical interfaces.\n","ref":"/velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/interfaces/","tags":"","title":"Interfaces"},{"body":" Info This article describes our new model lifecycle approach released on Friday, 2023-03-03. With that, the model is now automatically generated with the instantiation of the devContainer. It is generated from the vehicle model source file referenced in the AppManifest.\nFor the time being, the integration of services is not supported by the new approach.\nThe previous approach, using pre-generated model repositories, is now deprecated. But it is still available and described here .\nThis tutorial will show you how:\nthe vehicle API used as the source to generate the model is referenced in the app manifest, the automatic generation of the model works, you can trigger manual recreation of the model (after adding extensions to the API required by your project) How to Reference a Model Specification The model specification defines the vehicle API to be used by your project. It is referenced in the AppManifest.json via a URI or local file path like this:\nURI reference Local file reference \"vehicleModel\": { \"src\": \"\u003chttps://github.com/COVESA/vehicle_signal_specification/releases/download/v3.0/vss_rel_3.0.json\u003e\" } \"vehicleModel\": { \"src\": \"./my_model/my_model.json\" } Info The reference must point to a JSON file containing the model specification as VSS vspec. References to a VSS .vspec file hierarchy are not supported as of now. Model Creation The generation of the model is taking place:\nthrough a onPostInit hook when velocitas init is called: either triggered manually or automatically during the instantiation of the devContainer through our Velocitas Lifecycle Management , or when you trigger the VS Code task (Re-)generate vehicle model explicitly. The model generation is a three step process:\nThe model generator is installed as a Python package (if not already present) The referenced model specification is downloaded (if no local reference) The model code is generated and installed. The model is generated using our Velocitas vehicle-model-generator . The used version and also the repository of the generator can be altered via the variables section of the project configuration in the .velocitas.json. The default values for those are defined in the manifest.json of the devContainer setup package . Also, the target folder for the generated model source code is specified here:\n{ \"variables\": { \"modelGeneratorGitRepo\": \"https://github.com/eclipse-velocitas/vehicle-model-generator.git\", \"modelGeneratorGitRef\": \"v0.3.0\", \"generatedModelPath\": \"./gen/vehicle_model\" } } In Python template based projects the generated model is finally installed in the site-packages folder, while in C++ projects it is made available as a CMake include folder.\nFurther information Concept: SDK Overview Tutorial: Quickstart Tutorial: Create a Vehicle App ","categories":"","description":"Learn how to refer a model source and how the automated model lifecycle is working.\n","excerpt":"Learn how to refer a model source and how the automated model …","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/automated_model_lifecycle/","tags":"","title":"Automated Vehicle Model Lifecycle"},{"body":"Every Vehicle App repo comes with a .velocitas.json which is the project configuration of your app. It holds references to the packages and their respective versions as well as components you are using in your project.\nHere is an example of this configuration:\n{ \"packages\": { \"devenv-runtimes\": \"v3.1.0\", \"devenv-devcontainer-setup\": \"v2.1.0\" }, \"components\": [ \"runtime-local\", \"devcontainer-setup\", \"vehicle-signal-interface\", \"sdk-installer\", \"grpc-interface-support\" ], \"variables\": { \"language\": \"python\", \"repoType\": \"app\", \"appManifestPath\": \"app/AppManifest.json\", \"githubRepoId\": \"eclipse-velocitas/vehicle-app-python-template\", \"generatedModelPath\": \"./gen/vehicle_model\" }, \"cliVersion\": \"v0.9.0\" } More detailed information and explanation about the project configuration and fields of the .velocitas.json can be found here .\nNext steps Lifecycle Management: Usage of Packages Lifecycle Management: Development of Packages ","categories":"","description":"Learn everything about Velocitas project configuration.\n","excerpt":"Learn everything about Velocitas project configuration.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/project_configuration/","tags":"","title":"Project Configuration"},{"body":"Problem Currently, the development of in-vehicle applications (Vehicle Apps) can be excessively complex and challenging:\nMany time-consuming steps involved from setting up the development environment to the deployment of a Vehicle App.\nUnderstanding the vehicle’s E/E architecture details and specific API requires expert knowledge.\nPorting a Vehicle App to another vehicle platform is complex.\nSpecific processes, methods, and tools within each company creates challenges for effective collaboration.\nSolution The solution would be a development toolchain for creating vehicle-independent applications with:\nUsage of standardized vehicle APIs.\nEnabling portability through containerized Vehicle Apps with no dependencies to E/E architecture.\nPre-configured project setup​.\nSpeeding up the development by reducing complexity focus on differentiating business logic to innovate quickly.\nProduct Eclipse Velocitas™ is an open source project providing an end-to-end, scalable and modular development tool chain to create containerized Vehicle Apps, offering a comfortable, fast and efficient development experience to increase the speed of a development team (velocity).\nFeatures Project lifecycle management to update Vehicle App repositories via CLI. Vehicle abstraction support helps to focus on business logic by using a generated vehicle model on code level with type safety and auto-completion. The vehicle model is generated from a standardized API that hides the details of vehicle-specific signals and E/E architecture, allowing Vehicle Apps to be portable across different electronics and software architectures. Microsoft Visual Studio Code integration with DevContainer helps to install everything required to start the local development immediately, while tasks and launch configurations help to launch runtime services, other apps, and tests. Vehicle App skeleton and examples helps to understand easily how to write a Vehicle App using the KUKSA.VAL runtime services. Ready-to-use CI/CD workflows that build (for multi architectures), test, document and deploy a containerized Vehicle App with no dependencies to E/E architecture help saving setup time. Language Support Feature Python C++ Project lifecycle management + + Vehicle abstraction support + + Visual Studio Code integration + + Vehicle App skeleton and examples + + CI/CD workflows + + Unit test support + + Integration test support + digital.auto integration + Concepts ","categories":"","description":"Explore the goal, benefits and basic concepts of Eclipse _Velocitas™_\n","excerpt":"Explore the goal, benefits and basic concepts of Eclipse _Velocitas™_\n","ref":"/velocitas-docs/docs/about/","tags":"","title":"About Velocitas"},{"body":"Not yet done for C++\n","categories":"","description":"Learn how to create a Vehicle Model manually for C++\n","excerpt":"Learn how to create a Vehicle Model manually for C++\n","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_cpp/","tags":"","title":"C++ Manual Vehicle Model Creation"},{"body":"","categories":"","description":"Learn how to setup and explore the provided development environment.\n","excerpt":"Learn how to setup and explore the provided development environment.\n","ref":"/velocitas-docs/docs/tutorials/quickstart/","tags":"","title":"Getting Started"},{"body":"Introduction The Vehicle App SDK consists of the following building blocks:\nVehicle Model Ontology : The SDK provides a set of model base classes for the creation of vehicle models.\nMiddleware integration : Vehicle Models can contain gRPC stubs to communicate with Vehicle Services. gRPC communication is integrated natively.\nFluent query \u0026 rule construction : Based on a concrete Vehicle Model, the SDK is able to generate queries and rules against the KUKSA Databroker to access the real values of the data points that are defined in the vehicle model.\nPublish \u0026 subscribe messaging : The SDK supports publishing messages to a MQTT broker and subscribing to topics of a MQTT broker.\nVehicle App abstraction : Last but not least the SDK provides a VehicleApp base class, which every Vehicle App derives from.\nAn overview of the Vehicle App SDK and its dependencies is depicted in the following diagram:\nVehicle Model Ontology The Vehicle Model is a tree-based model where every branch in the tree, including the root, is derived from the Model base class provided by the SDK.\nThe Vehicle Model Ontology consists of the following classes:\nModel A model contains services, data points and other models. It corresponds to branch entries in VSS, interfaces in DTDL or namespaces in VSC.\nModelCollection Info The ModelCollection is deprecated since SDK v0.4.0. The generated vehicle model must reflect the actual representation of the data points. Please use the Model base class instead. Specifications like VSS support a concept that is called Instances . It makes it possible to describe repeating definitions. In DTDL, such kind of structures may be modeled with Relationships . In the SDK, these structures are mapped with the ModelCollection class. A ModelCollection is a collection of models, which make it possible to reference an individual model either by a NamedRange (e.g., Row [1-3]), a Dictionary (e.g., “Left”, “Right”) or a combination of both.\nService Direct asynchronous communication between Vehicle Apps and Vehicle Services is facilitated via the gRPC protocol.\nThe SDK has its own Service base class, which provides a convenience API layer to access the exposed methods of exactly one gRPC endpoint of a Vehicle Service or another Vehicle App. Please see the Middleware Integration section for more details.\nDataPoint DataPoint is the base class for all data points. It corresponds to sensors/actuators/attributes in VSS or telemetry/properties in DTDL.\nData points are the signals that are typically emitted by Vehicle Services or Data Providers.\nThe representation of a data point is a path starting with the root model, e.g.:\nVehicle.Speed Vehicle.FuelLevel Vehicle.Cabin.Seat.Row1.Pos1.Position Data points are defined as attributes of the model classes. The attribute name is the name of the data point without its path.\nTyped DataPoint classes Every primitive datatype has a corresponding typed data point class, which is derived from DataPoint (e.g., DataPointInt32, DataPointFloat, DataPointBool, DataPointString, etc.).\nExample An example of a Vehicle Model created with the described ontology is shown below:\nPython C++ ## import ontology classes from sdv import ( DataPointDouble, Model, Service, DataPointInt32, DataPointBool, DataPointArray, DataPointString, ) class Seat(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Position = DataPointBool(\"Position\", self) self.IsOccupied = DataPointBool(\"IsOccupied\", self) self.IsBelted = DataPointBool(\"IsBelted\", self) self.Height = DataPointInt32(\"Height\", self) self.Recline = DataPointInt32(\"Recline\", self) class Cabin(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.DriverPosition = DataPointInt32(\"DriverPosition\", self) self.Seat = SeatCollection(\"Seat\", self) class SeatCollection(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Row1 = self.RowType(\"Row1\", self) self.Row2 = self.RowType(\"Row2\", self) def Row(self, index: int): if index \u003c 1 or index \u003e 2: raise IndexError(f\"Index {index} is out of range\") _options = { 1 : self.Row1, 2 : self.Row2, } return _options.get(index) class RowType(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Pos1 = Seat(\"Pos1\", self) self.Pos2 = Seat(\"Pos2\", self) self.Pos3 = Seat(\"Pos3\", self) def Pos(self, index: int): if index \u003c 1 or index \u003e 3: raise IndexError(f\"Index {index} is out of range\") _options = { 1 : self.Pos1, 2 : self.Pos2, 3 : self.Pos3, } return _options.get(index) class VehicleIdentification(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.VIN = DataPointString(\"VIN\", self) self.Model = DataPointString(\"Model\", self) class CurrentLocation(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Latitude = DataPointDouble(\"Latitude\", self) self.Longitude = DataPointDouble(\"Longitude\", self) self.Timestamp = DataPointString(\"Timestamp\", self) self.Altitude = DataPointDouble(\"Altitude\", self) class Vehicle(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Speed = DataPointFloat(\"Speed\", self) self.CurrentLocation = CurrentLocation(\"CurrentLocation\", self) self.Cabin = Cabin(\"Cabin\", self) vehicle = Vehicle(\"Vehicle\") #include \"sdk/DataPoint.h\" #include \"sdk/Model.h\" using namespace velocitas; class Seat : public Model { public: Seat(std::string name, Model* parent) : Model(name, parent) {} DataPointBoolean Position{\"Position\", this}; DataPointBoolean IsOccupied{\"IsOccupied\", this}; DataPointBoolean IsBelted{\"IsBelted\", this}; DataPointInt32 Height{\"Height\", this}; DataPointInt32 Recline{\"Recline\", this}; }; class CurrentLocation : public Model { public: CurrentLocation(Model* parent) : Model(\"CurrentLocation\", parent) {} DataPointDouble Latitude{\"Latitude\", this}; DataPointDouble Longitude{\"Longitude\", this}; DataPointString Timestamp{\"Timestamp\", this}; DataPointDouble Altitude{\"Altitude\", this}; }; class Cabin : public Model { public: class SeatCollection : public Model { public: class RowType : public Model { public: using Model::Model; Seat Pos1{\"Pos1\", this}; Seat Pos2{\"Pos2\", this}; }; SeatCollection(Model* parent) : Model(\"Seat\", parent) {} RowType Row1{\"Row1\", this}; RowType Row2{\"Row2\", this}; }; Cabin(Model* parent) : Model(\"Cabin\", parent) {} DataPointInt32 DriverPosition{\"DriverPosition\", this}; SeatCollection Seat{this}; }; class Vehicle : public Model { public: Vehicle() : Model(\"Vehicle\") {} DataPointFloat Speed{\"Speed\", this}; ::CurrentLocation CurrentLocation{this}; ::Cabin Cabin{this}; }; Middleware integration gRPC Services Vehicle Services are expected to expose their public endpoints over the gRPC protocol. The related protobuf definitions are used to generate method stubs for the Vehicle Model to make it possible to call the methods of the Vehicle Services.\nModel integration Info Please be aware that the integration of Vehicle Services into the overall model is not supported by automated model lifecycle , currently.\nBased on the .proto files of the Vehicle Services, the protocol buffer compiler generates descriptors for all rpcs, messages, fields etc. for the target language. The gRPC stubs are wrapped by a convenience layer class derived from Service that contains all the methods of the underlying protocol buffer specification.\nInfo The convenience layer of C++ is a bit more extensive than in Python. The complexity of gRPC’s async API is hidden behind individual AsyncGrpcFacade implementations which need to be implemented manually. Have a look at the SeatService of the SeatAdjusterApp example and its SeatServiceAsyncGrpcFacade. Python C++ class SeatService(Service): def __init__(self): super().__init__() self._stub = SeatsStub(self.channel) async def Move(self, seat: Seat): response = await self._stub.Move( MoveRequest(seat=seat), metadata=self.metadata ) return response class SeatService : public Service { public: // nested classes/structs omitted SeatService(Model* parent) : Service(\"SeatService\", parent) , m_asyncGrpcFacade(grpc::CreateChannel(\"localhost:50051\", grpc::InsecureChannelCredentials())) { } AsyncResultPtr_t\u003cVoidResult\u003e move(Seat seat) { auto asyncResult = std::make_shared\u003cAsyncResult\u003cVoidResult\u003e\u003e(); m_asyncGrpcFacade-\u003eMove( toGrpcSeat(seat), [asyncResult](const auto\u0026 reply){ asyncResult-\u003einsertResult(VoidResult{})}), [asyncResult](const auto\u0026 status){ asyncResult-\u003einsertError(toInternalStatus(status))}; return asyncResult; } private: std::shared_ptr\u003cSeatServiceAsyncGrpcFacade\u003e m_asyncGrpcFacade; }; Fluent query \u0026 rule construction A set of query methods like get(), where(), join() etc. are provided through the Model and DataPoint base classes. These functions make it possible to construct SQL-like queries and subscriptions in a fluent language, which are then transmitted through the gRPC interface to the KUKSA Databroker.\nQuery examples The following examples show you how to query data points.\nGet single data point Python C++ driver_pos: int = vehicle.Cabin.DriverPosition.get() # Call to broker # GetDataPoint(rule=\"SELECT Vehicle.Cabin.DriverPosition\") auto driverPos = getDataPoints({Vehicle.Cabin.DriverPosition})-\u003eawait(); // Call to broker: // GetDataPoint(rule=\"SELECT Vehicle.Cabin.DriverPosition\") Get data points from multiple branches Python C++ vehicle_data = vehicle.CurrentLocation.Latitude.join( vehicle.CurrentLocation.Longitude).get() print(f' Latitude: {vehicle_data.CurrentLocation.Latitude} Longitude: {vehicle_data.CurrentLocation.Longitude} ') # Call to broker # GetDataPoint(rule=\"SELECT Vehicle.CurrentLocation.Latitude, CurrentLocation.Longitude\") auto datapoints = getDataPoints({Vehicle.CurrentLocation.Latitude, Vehicle.CurrentLocation.Longitude})-\u003eawait(); // Call to broker: // GetDataPoint(rule=\"SELECT Vehicle.CurrentLocation.Latitude, CurrentLocation.Longitude\") Subscription examples Subscribe and Unsubscribe to a single data point Python C++ self.rule = ( await self.vehicle.Cabin.Seat.Row(2).Pos(1).Position .subscribe(self.on_seat_position_change) ) def on_seat_position_change(self, data: DataPointReply): position = data.get(self.vehicle.Cabin.Seat.Row2.Pos1.Position).value print(f'Seat position changed to {position}') # Call to broker # Subscribe(rule=\"SELECT Vehicle.Cabin.Seat.Row2.Pos1.Position\") # If needed, the subscription can be stopped like this await self.rule.subscription.unsubscribe() auto subscription = subscribeDataPoints( velocitas::QueryBuilder::select(Vehicle.Cabin.Seat.Row(2).Pos(1).Position).build()) -\u003eonItem( [this](auto\u0026\u0026 item) { onSeatPositionChanged(std::forward\u003cdecltype(item)\u003e(item)); }); // If needed, the subscription can be stopped like this: subscription-\u003ecancel(); void onSeatPositionChanged(const DataPointMap_t datapoints) { logger().info(\"SeatPosition has changed to: \"+ datapoints.at(Vehicle.Cabin.Seat.Row(2).Pos(1).Position)-\u003easFloat().get()); } Subscribe to a single data point with a filter Python C++ Vehicle.Cabin.Seat.Row(2).Pos(1).Position.where( \"Cabin.Seat.Row2.Pos1.Position \u003e 50\") .subscribe(on_seat_position_change) def on_seat_position_change(data: DataPointReply): position = data.get(Vehicle.Cabin.Seat.Row2.Pos1.Position).value print(f'Seat position changed to {position}') # Call to broker # Subscribe(rule=\"SELECT Vehicle.Cabin.Seat.Row2.Pos1.Position WHERE Vehicle.Cabin.Seat.Row2.Pos1.Position \u003e 50\") auto query = QueryBuilder::select(Vehicle.Cabin.Seat.Row(2).Pos(1).Position) .where(vehicle.Cabin.Seat.Row(2).Pos(1).Position) .gt(50) .build(); subscribeDataPoints(query)-\u003eonItem([this](auto\u0026\u0026 item){onSeatPositionChanged(std::forward\u003cdecltype(item)\u003e(item));})); void onSeatPositionChanged(const DataPointMap_t datapoints) { logger().info(\"SeatPosition has changed to: \"+ datapoints.at(Vehicle.Cabin.Seat.Row(2).Pos(1).Position)-\u003easFloat().get()); } // Call to broker: // Subscribe(rule=\"SELECT Vehicle.Cabin.Seat.Row2.Pos1.Position WHERE Vehicle.Cabin.Seat.Row2.Pos1.Position \u003e 50\") Publish \u0026 subscribe messaging The SDK supports publishing messages to a MQTT broker and subscribing to topics of a MQTT broker. Using the Velocitas SDK, the low-level MQTT communication is abstracted away from the Vehicle App developer. Especially the physical address and port of the MQTT broker is no longer configured in the Vehicle App itself, but rather is set as an environment variable, which is outside of the Vehicle App.\nPublish MQTT Messages MQTT messages can be published easily with the publish_event() method, inherited from VehicleApp base class:\nPython C++ await self.publish_event( \"seatadjuster/currentPosition\", json.dumps(req_data)) publishToTopic(\"seatadjuster/currentPosition\", \"{ \\\"position\\\": 40 }\"); Subscribe to MQTT Topics In Python subscriptions to MQTT topics can be easily established with the subscribe_topic() annotation. The annotation needs to be applied to a method of the VehicleApp base class. In C++ the subscribeToTopic() method has to be called. Callbacks for onItem and onError can be set. The following examples provide some more details.\nPython C++ @subscribe_topic(\"seatadjuster/setPosition/request\") async def on_set_position_request_received(self, data: str) -\u003e None: data = json.loads(data) logger.info(\"Set Position Request received: data=%s\", data) #include \u003cfmt/core.h\u003e #include \u003cnlohmann/json.hpp\u003e subscribeToTopic(\"seatadjuster/setPosition/request\")-\u003eonItem([this](auto\u0026\u0026 item){ const auto jsonData = nlohmann::json::parse(item); logger().info(fmt::format(\"Set Position Request received: data={}\", jsonData)); }); Vehicle App abstraction Vehicle Apps are inherited from the VehicleApp base class. This enables the Vehicle App to use the Publish \u0026 Subscribe messaging and to connect to the KUKSA Databroker.\nThe Vehicle Model instance is passed to the constructor of the VehicleApp class and should be stored in a member variable (e.g. self.vehicle for Python, std::shared_ptr\u003cVehicle\u003e m_vehicle; for C++), to be used by all methods within the application.\nFinally, the run() method of the VehicleApp class is called to start the Vehicle App and register all MQTT topic and Databroker subscriptions.\nImplementation detail In Python, the subscriptions are based on asyncio, which makes it necessary to call the run() method with an active asyncio event_loop. A typical skeleton of a Vehicle App looks like this:\nPython C++ class SeatAdjusterApp(VehicleApp): def __init__(self, vehicle: Vehicle): super().__init__() self.vehicle = vehicle async def main(): # Main function logger.info(\"Starting seat adjuster app...\") seat_adjuster_app = SeatAdjusterApp(vehicle) await seat_adjuster_app.run() LOOP = asyncio.get_event_loop() LOOP.add_signal_handler(signal.SIGTERM, LOOP.stop) LOOP.run_until_complete(main()) LOOP.close() #include \"sdk/VehicleApp.h\" #include \"vehicle/Vehicle.hpp\" using namespace velocitas; class SeatAdjusterApp : public VehicleApp { public: SeatAdjusterApp() : VehicleApp(IVehicleDataBrokerClient::createInstance(\"vehicledatabroker\")), IPubSubClient::createInstance(\"localhost:1883\", \"SeatAdjusterApp\")) {} private: ::Vehicle Vehicle; }; int main(int argc, char** argv) { SeatAdjusterApp app; app.run(); return 0; } Further information Tutorial: Quickstart Tutorial: Vehicle Model Creation Tutorial: Vehicle App Development Tutorial: Develop and run integration tests for a Vehicle App ","categories":"","description":"Learn more about the provided _Vehicle App_ SDK.\n","excerpt":"Learn more about the provided _Vehicle App_ SDK.\n","ref":"/velocitas-docs/docs/concepts/development_model/vehicle_app_sdk/","tags":"","title":"Vehicle App SDK"},{"body":" Providing CLI package Interface type-key devenv-devcontainer-setup grpc-interface Description This interface type introduces a dependency to a gRPC service. It is used to generate either client stubs (in case your application requires the interface) or server stubs (in case your application provides the interface). The result of the generation is a language specific and package manager specific source code package, integrated with the Velocitas SDK core.\nIf a Vehicle App requires a grpc-interface - a client stub embedded into the Velocitas framework will be generated and added as a build-time dependency of your application. It enables you to access your service from your Vehicle App without any additional effort.\nIf a Vehicle App provides a grpc-interface - a server stub embedded into the Velocitas framework will be generated and added as a build-time dependency of your application. It enables you to quickly add the business logic of your application.\nConfiguration structure Attribute Type Example value Description src string \"https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto\" URI of the used protobuf specification of the service. URI may point to a local file or to a file provided by a server. It is generally recommended that a stable proto file is used. I.e. one that is already released under a proper tag rather than an in-development proto file. required.methods array Array of service’s methods that are accessed by the application. In addition to access control the methods attribute may be used to determine backward or forward compatibility i.e. if semantics of a service’s interface did not change but methods were added or removed in a future version. required.methods.[].name string \"Move\", \"MoveComponent\" Name of the method that the application would like to access provided object {} Reserved object indicating that the interface is provided. Might be filled with further configuration values. Example { \"type\": \"grpc-interface\", \"config\": { \"src\": \"https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto\", \"required\": { \"methods\": [ \"Move\", \"MoveComponent\" ] } } } ","categories":"","description":"The functional interface for supporting remote procedure calls via gRPC.\n","excerpt":"The functional interface for supporting remote procedure calls via …","ref":"/velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/interfaces/grpc_interface/","tags":"","title":"gRPC Service Interface"},{"body":" Providing CLI package Interface type-key devenv-runtimes pubsub Description This interface type introduces a dependency to a publish and subscribe middleware. While this may change in the future due to new middlewares being adopted, at the moment this will always indicate a dependency to MQTT.\nIf a Vehicle App requires pubsub - this will influence the generated deployment specs to include a publish and subscribe broker (i.e. an MQTT broker).\nIf a Vehicle App provides pubsub - this will influence the generated deployment specs to include a publish and subscribe broker (i.e. an MQTT broker).\nConfiguration structure Attribute Type Example value Description reads array[string] [ \"sampleapp/getSpeed\" ] Array of topics which are read by the application. writes array[string] [ \"sampleapp/currentSpeed\", \"sampleapp/getSpeed/response\" ] Array of topics which are written by the application. Example { \"type\": \"pubsub\", \"config\": { \"reads\": [ \"sampleapp/getSpeed\" ], \"writes\": [ \"sampleapp/currentSpeed\", \"sampleapp/getSpeed/response\" ] } } ","categories":"","description":"The functional interface for supporting communication via publish and subscribe.\n","excerpt":"The functional interface for supporting communication via publish and …","ref":"/velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/interfaces/pubsub/","tags":"","title":"Publish Subscribe"},{"body":"To be filled.\nTemplate based creation flow Bootstrapping creation flow Resulting Velocitas CLI and Velocitas Package changes velocitas create command shall be introduced\nit will guide through the project creation process, allowing the developer to add APIs and services at creation time which will reference the correct Velocitas CLI packages (either provided by Velocitas or by a 3rd party). in addition to an interactive mode where create is invoked without arguments, there shall be a CLI mode where all of the arguments shall be passable as arguments Packages need to be available in a central registry (i.e. a new git repository) otherwise step 3 (depicted below) is not possible.\nPackages need to expose which dependency types they are providing in their manifest. For each dependency type a human readable name for the type shall be exposed.\nInteraction mockup \u003e velocitas create ... Creating a new Velocitas project! \u003e What is the name of your project? MyApp \u003e 1. Which programming language would you like to use for your project? [ ] Python [x] C++ \u003e 2. Which integrations would you like to use? (multiple selections possible) [x] Github [x] Gitlab [ ] Gitee \u003e 3. Which API dependencies does your project have? [x] gRPC service [ ] uProtocol service [x] Vehicle Service Catalogue \u003e 4. Add an API dependency (y/n)? y \u003e 5. What type of dependency? [x] gRPC-IF [ ] VSC-IF \u003e 6. URI of the .proto file? https://some-url/if.proto \u003e 7. Add an(other) API dependency (y/n)? n ... Project created! Arguments mockup:\n$ velocitas create \\ --name MyApp \\ --lang cpp \\ --package grpc-service-support \\ --package vsc-support \\ --require grpc-interface:https://some-url/if.proto \u003e Project created! ","categories":"","description":"To be filled\n","excerpt":"To be filled\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/phases/create/","tags":"","title":"Create"},{"body":"","categories":"","description":"Overview of Velocitas Concepts.\n","excerpt":"Overview of Velocitas Concepts.\n","ref":"/velocitas-docs/docs/concepts/","tags":"","title":"Concepts"},{"body":"Introduction Once a repository has been created from one of our Vehicle App templates, basically the only way to receive updates into your derived repository is to manually pull changes, which would be quite tedious and error prone. This is where our Lifecycle Management comes to the rescue!\nAll of our main components of the development environment, like\ntools runtimes devcontainer configuration and setup build systems CI workflows are (or will be) provided as versioned packages which can be updated individually, if required.\nThe driver for this is our Velocitas CLI which is our package manager for Vehicle App repositories.\nOverview Here we can see how the MyVehicleApp repository references package repositories by Velocitas, customer specific packages and some packages from a totally different development platform (Gitee).\nIf you want to learn more about how to reference and use packages check the sections for project configuration and packages .\nLifecycle Management flow ","categories":"","description":"Learn more about our lifecycle management.\n","excerpt":"Learn more about our lifecycle management.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/","tags":"","title":"Lifecycle Management"},{"body":"Background Our Velocitas CLI is introduced to support the process of the lifecycle of a Vehicle App as a project manager.\nCommands You can find all information about available commands here .\nCLI Flow examples velocitas create Create a new Velocitas Vehicle App project. Note velocitas create needs to be executed inside our generic vehicle-app-template (inside the devcontainer) where a so called\npackage-index.json is located for now, which is a central place of defining our extension and core packages with their respective exposed interfaces.\nvscode ➜ /workspaces/vehicle-app-template (main) $ velocitas create Interactive project creation started \u003e What is the name of your project? MyApp \u003e Which programming language would you like to use for your project? (Use arrow keys) ❯ python cpp \u003e Would you like to use a provided example? No \u003e Which functional interfaces does your application have? (Press \u003cspace\u003e to select, \u003ca\u003e to toggle all, \u003ci\u003e to invert selection, and \u003center\u003e to proceed) ❯◉ Vehicle Signal Interface based on VSS and KUKSA Databroker ◯ gRPC service contract based on a proto interface description ... Config 'src' for interface 'vehicle-signal-interface': URI or path to VSS json (Leave empty for default: v3.0) ... velocitas init Download packages configured in your .velocitas.json to VELOCITAS_HOME vscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas init Initializing Velocitas packages ... ... Downloading package: 'devenv-runtimes:v1.0.1' ... Downloading package: 'devenv-github-workflows:v2.0.4' ... Downloading package: 'devenv-github-templates:v1.0.1' ... Downloading package: 'devenv-devcontainer-setup:v1.1.7' Running post init hook for model-generator Running 'install-deps' ... Single Package Init Single packages can also easily be initialized or re-initialized using the package parameter -p / --package and the specifier parameter -s / --specifier. The specifier parameter can be either a git tag or a git hash. If the specifier parameter is omitted either the version defined in .velocitas.json resp. the latest version of the specified package will be used automatically. After initialisation the package and it’s resolved version will be written to .velocitas.json. If the package already exists in .velocitas.json, however the versions differ it will be automatically updated to the specified version. If no components from the specified package are added to .velocitas.json all components from this package are automatically written to it.\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas init -p devenv-runtimes -s v3.0.0 Initializing Velocitas packages ... ... Package 'devenv-runtimes:v3.0.0' added to .velocitas.json ... Downloading package: 'devenv-runtimes:v3.0.0' ... \u003e Running post init hook for ... ... velocitas sync If any package provides files they will be synchronized into your repository. Note This will overwrite any changes you have made to the files manually! Affected files are prefixed with an auto generated notice: vscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas sync Syncing Velocitas components! ... syncing 'devenv-github-workflows' ... syncing 'devenv-github-templates' ... syncing 'devenv-devcontainer-setup' velocitas upgrade Updates Velocitas components.\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas upgrade --dry-run [--ignore-bounds] Checking .velocitas.json for updates! ... devenv-devcontainer-setup:vx.x.x → up to date! ... devenv-runtimes:vx.x.x → vx.x.x ... devenv-github-templates:vx.x.x → up to date! ... devenv-github-workflows:vx.x.x → up to date! velocitas package Prints information about packages.\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas package devenv-devcontainer-setup devenv-devcontainer-setup version: v1.1.7 components: - id: devcontainer-setup type: setup variables: language type: string description: The programming language of the project. Either 'python' or 'cpp' required: true repoType type: string description: The type of the repository: 'app' or 'sdk' required: true appManifestPath type: string description: Path of the AppManifest file, relative to the .velocitas.json required: true vscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas package devenv-devcontainer-setup -p /home/vscode/.velocitas/packages/devenv-devcontainer-setup/v1.1.7 velocitas exec Executes a script contained in one of your installed components.\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas exec runtime-local run-vehicledatabroker ####################################################### ### Running Databroker ### ####################################################### ... More detailed usage can be found at the Velocitas CLI README .\nAdditional Information Cache Usage The Velocitas CLI supports caching data for a Vehicle App project. The cache data makes it easy for any script/program of a component to read from or write to. More detailed information about the Project Cache can be found here .\nBuilt-In Variables The Velocitas CLI also creates default environment variables which are available to every script/program.\nvariable description VELOCITAS_WORKSPACE_DIR Current working directory of the Vehicle App VELOCITAS_CACHE_DIR Vehicle App project specific cache directory. e.g, ~/.velocitas/cache/\u003cgeneratedMd5Hash\u003e VELOCITAS_CACHE_DATA JSON string of ~/.velocitas/cache/\u003cgeneratedMd5Hash\u003e/cache.json VELOCITAS_APP_MANIFEST JSON string of the Vehicle App AppManifest More detailed information about Built-In Variables can be found here .\nNext steps Lifecycle Management: Troubleshooting ","categories":"","description":"Learn everything about the Velocitas CLI.\n","excerpt":"Learn everything about the Velocitas CLI.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/velocitas_cli/","tags":"","title":"Velocitas CLI"},{"body":"","categories":"","description":"Learn how to start your _Vehicle App_ development with a prototype created in the playground of digital.auto and how to set up and customize _Vehicle Services_/_Data Providers_.\n","excerpt":"Learn how to start your _Vehicle App_ development with a prototype …","ref":"/velocitas-docs/docs/tutorials/prototyping/","tags":"","title":"Prototyping"},{"body":"Introduction The Vehicle Abstraction Layer (VAL) enables access to the systems and functions of a vehicle via a unified - or even better - a standardized Vehicle API abstracting from the details of the end-to-end architecture of the vehicle. The unified API enables Vehicle Apps to run on different vehicle architectures of a single OEM. Vehicle Apps can be even implemented OEM-agnostic, if using an API based on a standard like the COVESA Vehicle Signal Specification (VSS) . The Vehicle API eliminates the need to know the source, destination, and format of signals for the vehicle system.\nThe Eclipse Velocitas project is using the VAL of the Eclipse KUKSA project , also called KUKSA.VAL. KUKSA.VAL does not provide a concrete VAL. That’s up to you as an OEM (vehicle manufacturer) or as a supplier. But KUKSA.VAL provides the components and tools that helps you to implement a VAL for your chosen end-to-end architecture. Also, it can support you to simulate the vehicle hardware during the development phase of an Vehicle App or Service.\nKUKSA.VAL provides you with ready-to-use generic components for the signal-based access to the vehicle, like the KUKSA Databroker and the generic Data Providers (aka Data Feeders). It also provides you reference implementations of certain Vehicle Services, like the Seat Service and the HVAC Service.\nArchitecture The image below shows the main components of the VAL and its relation to the Velocitas Development Model .\nKUKSA Databroker The KUKSA Databroker is a gRPC service acting as a broker of vehicle data / signals also called data points in the following. It provides central access to vehicle data points arranged in a - preferably standardized - vehicle data model like the COVESA VSS or others. But this is not a must, it is also possible to use your own (proprietary) vehicle model or to extend the COVESA VSS with your specific extensions via VSS overlays .\nData points represent certain states of a vehicle, like the current vehicle speed or the currently applied gear. Data points can represent sensor values like the vehicle speed or engine temperature, actuators like the wiper mode, and immutable attributes of the vehicle like the needed fuel type(s) of the vehicle, engine displacement, maximum power, etc.\nData points factually belonging together are typically arranged in branches and sub-branches of a tree structure (like this example on the COVESA VSS site).\nThe KUKSA Databroker is implemented in Rust, can run in a container and provides services to get data points, update data points and for subscribing to automatic notifications on data point changes. Filter- and rule-based subscriptions of data points can be used to reduce the number of updates sent to the subscriber.\nData Providers / Data Feeders Conceptually, a data provider is the responsible to take care for a certain set of data points: It provides updates of sensor data from the vehicle to the Databroker and forwards updates of actuator values to the vehicle. The set of data points a data provider maintains may depend on the network interface (e.g. CAN bus) via that those data is accessible or it can depend on a certain use case the provider is responsible for (like seat control).\nEclipse KUKSA provides several generic Data Providers for different datasources. As of today, Eclipse Velocitas only utilizes the generic CAN Provider (KUKSA CAN Provider) implemented in Python, which reads data from a CAN bus based on mappings specified in e.g. a CAN network description (dbc) file. The feeder uses a mapping file and data point metadata to convert the source data to data points and injects them into the Databroker using its Collector gRPC interface. The feeder automatically reconnects to the Databroker in the event that the connection is lost.\nVehicle Services A vehicle service offers a Vehicle App to interact with the vehicle systems on a RPC-like basis. It can provide service interfaces to control actuators or to trigger (complex) actions, or provide interfaces to get data. It communicates with the Hardware Abstraction to execute the underlying services, but may also interact with the Databroker.\nThe KUKSA.VAL Services repository contains examples illustrating how such kind of vehicle services can be built.\nHardware Abstraction Data feeders rely on hardware abstraction. Hardware abstraction is project/platform specific. The reference implementation relies on SocketCAN and vxcan, see KUKSA CAN Provider . The hardware abstraction may offer replaying (e.g., CAN) data from a file (can dump file) when the respective data source (e.g., CAN) is not available.\nOverview of the VAL architecture Information Flow The VAL offers an information flow between vehicle networks and vehicle services. The data that can flow is ultimately limited to the data available through the Hardware Abstraction, which is platform/project-specific. The KUKSA Databroker offers read/subscribe access to data points based on a gRPC service. The data points which are actually available are defined by the set of feeders providing the data into the broker. Services (like the seat service ) define which CAN signals they listen to and which CAN signals they send themselves, see documentation . Service implementations may also interact as feeders with the Databroker.\nData flow when a Vehicle App uses the KUKSA Databroker Architectural representation of the KUKSA Databroker data flow Data flow when a Vehicle App uses a Vehicle Service Architectural representation of the vehicle service data flow Source Code Source code and build instructions are available in the respective KUKSA repositories:\nKUKSA Databroker KUKSA CAN Provider KUKSA example providers Guidelines Guidelines for best practices on how to specify a gRPC-based service interface and on how to implement a vehicle service can be found in the kuksa.val.services repository . ","categories":"","description":"Learn about the main concepts and components of the vehicle abstraction and how it relates to the [Eclipse KUKSA project](https://github.com/eclipse-kuksa).\n","excerpt":"Learn about the main concepts and components of the vehicle …","ref":"/velocitas-docs/docs/concepts/development_model/val/","tags":"","title":"Vehicle Abstraction Layer (VAL)"},{"body":"Now that you have created your own Vehicle Model, we can distribute it to make use of it in Vehicle Apps.\nCopying the folder to your Vehicle App repo The easiest way to get started quickly is to copy the created model, presumably stored in vehicle_model into your Vehicle App repository to use it. To do so, simply copy and paste the directory into the \u003csdk_root\u003e/app directory and replace the existing model.\nUsing a git submodule A similar approach to the one above but a bit more difficult to set up is to create a git repository for the created model. The advantage of this approach is that you can share the same model between multiple Vehicle Apps without any manual effort.\nCreate a new git repository on i.e. Github Clone it locally, add the created vehicle_model folder to the git repository Commit everything and push the branch In your Vehicle App repo, add a new git submodule via\ngit submodule add \u003ccheckout URL of your new repo\u003e app/vehicle_model git submodule init Now you are ready to develop new Vehicle Apps with your custom Vehicle Model!\n","categories":"","description":"Learn how to distribute a Vehicle Model written in C++.\n","excerpt":"Learn how to distribute a Vehicle Model written in C++.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_cpp/","tags":"","title":"C++ Vehicle Model Distribution"},{"body":" Info With the release of our new model lifecycle approach on Friday, 2023-03-03, the model is now automatically generated with the instantiation of the devContainer from a model source referenced in the app manifest.\nThe approach described here, using pre-generated model repositories, is deprecated as of now. But it is still available and must be used if you need access to vehicle services. Please be aware, that you would either have to use template versions before the above mentioned release, or you need to adapt the newer versions of the template using the old approach.\nThis tutorial will show you how to:\nCreate a Vehicle Model Add a Vehicle Service to the Vehicle Model Distribute your Python Vehicle Model Note A Vehicle Model should be defined in its own package. This makes it possible to distribute the Vehicle Model later as a standalone package and to use it in different Vehicle App projects.\nThe creation of a new vehicle model is only required if the vehicle signals (like sensors and actuators) defined in the current version of the COVESA Vehicle Signal Specification (VSS) is not sufficient for the definition of your vehicle API. Otherwise you could use the default vehicle model we already generated for you, see\nPython Vehicle Model and\nC++ Vehicle Model .\nCreate a Vehicle Model from VSS specification A Vehicle Model can be generated from a COVESA Vehicle Signal Specification (VSS). VSS introduces a domain taxonomy for vehicle signals, in the sense of classical attributes, sensors and actuators with the raw data communicated over vehicle buses and data. The Velocitas vehicle-model-generator creates a Vehicle Model from the given specification and generates a package for use in Vehicle App projects.\nFollow the steps to generate a Vehicle Model.\nClone the vehicle-model-generator repository in a container volume.\nIn this container volume, clone the vehicle-signal-specification repository and if required checkout a particular branch:\ngit clone https://github.com/COVESA/vehicle_signal_specification cd vehicle_signal_specification git checkout \u003cbranch-name\u003e In case the VSS vspec doesn’t contain the required signals, you can create a vspec using the VSS Rule Set .\nExecute the command\npython3 gen_vehicle_model.py -I ./vehicle_signal_specification/spec ./vehicle_signal_specification/spec/VehicleSignalSpecification.vspec -l \u003clang\u003e -T sdv_model -N sdv_model or if you want to generate it from a .json file\npython3 gen_vehicle_model.py \u003cpath_to_your_json_file\u003e -l \u003clang\u003e -T sdv_model Depending on the value of lang, which can assume the values python and cpp, this creates a sdv_model directory in the root of repository along with all generated source files for the given programming language.\nHere is an overview of what is generated for every available value of lang:\nlang output python Python sources and a setup.py ready to be used as Python package cpp C++ sources, headers and a CMakeLists.txt ready to be used as a CMake project To have a custom model name, refer to README of vehicle-model-generator repository.\nFor Python: Change the version of package in setup.py manually (defaults to 0.1.0).\nNow the newly generated sdv_model can be used for distribution. (See Distributing your Vehicle Model )\nCreate a Vehicle Model Manually Alternative to the generation from a VSS specification you could create the Vehicle Model manually. The following sections describing the required steps.\nPython Distributing your Vehicle Model Once you have created your Vehicle Model either manually or via the Vehicle Model Generator, you need to distribute your model to use it in an application. Follow the links below for language specific tutorials on how to distribute your freshly created Vehicle Model.\nPython C++ Further information Concept: SDK Overview Tutorial: Quickstart Tutorial: Create a Vehicle App ","categories":"","description":"Learn how to manually create a vehicle model to access vehicle data or execute remote procedure calls.\n","excerpt":"Learn how to manually create a vehicle model to access vehicle data or …","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/","tags":"","title":"Manual Vehicle Model Creation"},{"body":"","categories":"","description":"Learn about the different phases within the lifecycle of your project.\n","excerpt":"Learn about the different phases within the lifecycle of your project. …","ref":"/velocitas-docs/docs/concepts/lifecycle_management/phases/","tags":"","title":"Phases"},{"body":"Versions v1 v2 v3 (current) Introduction The AppManifest defines the properties of your Vehicle App and its functional interfaces (FIs).\nFIs may be:\nrequired service interfaces (e.g. a required gRPC service interface) the used vehicle model and accessed data points. an arbitrary abstract interface description used by 3rd parties In addition to required FIs, provided FIs can (and need) to be specified as well.\nThese defined interfaces are then used by the Velocitas toolchain to:\ngenerate service stubs for either a client implementation (required IF) or a server implementation (provided IF) (i.e. for gRPC) generate a source code equivalent of the defined vehicle model Overview The image below depicts the interaction between App Manifest and DevEnv Configuration at -development time- The responsibilities are clearly separated; the App Manifest describes the application and its interfaces whereas DevEnv Configuration (or .velocitas.json) defines the configuration of the development environment and all the packages used by the Velocitas toolchain.\nContext To fully understand the AppManifest, let’s have a look at who interacts with it:\nPurpose Define the requirements of a Vehicle App in an abstract way to avoid dependencies on concrete Runtime and Middleware configurations. Description of your applications functional interfaces(VehicleModel, services, APIs, …) Enable loose coupling of functional interface descriptions and the Velocitas toolchain. Some parts of the toolchain are responsible for reading the file and acting upon it, depending on the type of functional interface Providing an extendable syntax to enable custom functional interface types which may not provided by the Velocitas toolchain itself, but by a third party Providing a single source of truth for generation of deployment specifications (i.e. Kanto spec, etc…) Example // AppManifest.json { \"manifestVersion\": \"v3\", \"name\": \"SampleApp\", \"interfaces\": [ { \"type\": \"vehicle-signal-interface\", \"config\": { \"src\": \"https://github.com/COVESA/vehicle_signal_specification/releases/download/v3.0/vss_rel_3.0.json\", \"datapoints\": { \"required\": [ { \"path\": \"Vehicle.Speed\", \"optional\": \"true\", \"access\": \"read\", } ], \"provided\": [ { \"path\": \"Vehicle.Cabin.Seat.Row1.Pos1.Position\", } ] } } }, { \"type\": \"grpc-interface\", \"config\": { \"src\": \"https://raw.githubusercontent.com/eclipse-kuksa/kuksa-incubation/0.4.0/seat_service/proto/sdv/edge/comfort/seats/v1/seats.proto\", \"required\": { \"methods\": [ \"Move\", \"MoveComponent\" ] }, } }, { \"type\": \"pubsub\", \"config\": { \"reads\": [ \"sampleapp/getSpeed\" ], \"writes\": [ \"sampleapp/currentSpeed\", \"sampleapp/getSpeed/response\" ] } } ] } The VehicleApp above has an:\ninterface towards our generated Vehicle Signal Interface based on the COVESA Vehicle Signal Specification . In particular, it requires read access to the vehicle signal Vehicle.Speed since the signal is marked as optional the application will work, even if the signal is not present in the system. Additionally, the application acts as a provider for the signal Vehicle.Cabin.Seat.Row1.Pos1.Position meaning that it will take responsibility of reading/writing data directly to vehicle networks for the respective signal.\ninterface towards gRPC based on the seats.proto file. Since the direction is required a service client for the seats service will be generated who interacts with the Velocitas middleware.\ninterface towards the pubsub middleware and is reading to the topic sampleapp/getSpeed and writing the topics sampleapp/currentSpeed, sampleapp/getSpeed/response.\nThe example has no provided interfaces.\nStructure Describes all external properties and interfaces of a Vehicle Application.\nProperties Property Type Required Description manifestVersion string Yes The version of the App Manifest. name string Yes The name of the Vehicle Application. interfaces object [] No Array of all provided or required functional interfaces. Interfaces Properties Property Type Required Description type string Yes The type of the functional interface. config object No The configuration of the functional interface type. Content may vary between all types. Config The configuration of the functional interface type. Content may vary between all types.\nRefer to the JSON Schema of the current AppManifest here .\nVisualization graph TD manifest(AppManifest.json) manifest --\u003e manifestVersion[manifestVersion] manifest --\u003e name[name] manifest -.-\u003e interfaces[interfaces] interfaces -- \"0..n\" --\u003e interfaces.item(object) interfaces.item --\u003e interfaces.item.type[type] interfaces.item -.-\u003e interfaces.item.config[config] Functional interface types supported by Velocitas Here is a list of functional interface types directly supported by the Velocitas toolchain and which Velocitas CLI packages are exposing the support:\nVehicle Signal Interface gRPC interface Publish and subscribe Support for additional interface types may be added by providing a 3rd party CLI package .\nPlanned, but not yet available features Some FIs are dependent on used classes, methods or literals in your Vehicle App’s source code. For example the vehicle-model FI requires you to list required or provided datapoints. At the moment, these attributes need to be filled manually. There are ideas to auto-generate these attributes by analyzing the source code, but nothing is planned for that, yet.\nFurther information Tutorial: Quickstart Tutorial: Vehicle Model Creation Tutorial: Vehicle App Development Concept: Lifecycle Management ","categories":"","description":"Learn more about the _Vehicle App_ Manifest.\n","excerpt":"Learn more about the _Vehicle App_ Manifest.\n","ref":"/velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/","tags":"","title":"Vehicle App Manifest"},{"body":"Now you a have a Python package containing your first Python Vehicle Model and it is time to distribute it. There is nothing special about the distribution of this package, since it is just an ordinary Python package. Check out the Python Packaging User Guide to learn more about packaging and package distribution in Python.\nDistribute to single Vehicle App If you want to distribute your Python Vehicle Model to a single Vehicle App, you can do so by copying the entire folder my_vehicle_model under the /app/src folder of your Vehicle App repository and treat it as a sub-package of the Vehicle App.\nCreate a new folder my_vehicle_model under /app/src in your Vehicle App repository. Copy the my_vehicle_model folder to the /app/src folder of your Vehicle App repository. Import the package my_vehicle_model in your Vehicle App: from \u003cmy_app\u003e.my_vehicle_model import vehicle ... my_app = MyVehicleApp(vehicle) Distribute inside an organization If you want to distribute your Python Vehicle Model inside an organization and use it to develop multiple Vehicle Apps, you can do so by creating a dedicated Git repository and copying the files there.\nCreate new Git repository called my_vehicle_model\nCopy the content under my_vehicle_model to the repository.\nRelease the Vehicle Model by creating a version tag (e.g., v1.0.0).\nInstall the Vehicle Model package to your Vehicle App:\npip3 install git+https://github.com/\u003cyourorg\u003e/my_vehicle_model.git@v1.0.0 Import the package my_vehicle_model in your Vehicle App and use it as shown in the previous section.\nDistribute publicly as open source If you want to distribute your Python Vehicle Model publicly, you can do so by creating a Python package and distributing it on the Python Package Index (PyPI) . PyPi is a repository of software for the Python programming language and helps you find and install software developed and shared by the Python community. If you use the pip command, you are already using PyPI.\nDetailed instructions on how to make a Python package available on PyPI can be found here .\n","categories":"","description":"Learn how to distribute a Vehicle Model written in Python.\n","excerpt":"Learn how to distribute a Vehicle Model written in Python.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_python/","tags":"","title":"Python Vehicle Model Distribution"},{"body":"\n","categories":"","description":"Learn how to get started with Eclipse Velocitas™, including setting up the development environment, creating a Vehicle Model as well as developing, testing and deploying a _Vehicle App_.\n","excerpt":"Learn how to get started with Eclipse Velocitas™, including setting up …","ref":"/velocitas-docs/docs/tutorials/","tags":"","title":"Tutorials"},{"body":"Please visit first Getting Started page if you don’t know where to start.\n","categories":"","description":"Learn how to develop a new _Vehicle App_.\n","excerpt":"Learn how to develop a new _Vehicle App_.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_app_development/","tags":"","title":"Vehicle App Development"},{"body":" Info On Friday, 2023-03-03 we released our new model lifecycle approach . With the update of the documentation the previous content of this page can be found in the section\nManual Vehicle Model Creation now.\nA Vehicle Model makes it possible to easily get vehicle data from the KUKSA Databroker and to execute remote procedure calls over gRPC against Vehicle Services and other Vehicle Apps. It is generated from the underlying semantic models based e.g. on the COVESA Vehicle Signal Specification (VSS) . The model is generated for a concrete programming language as a graph-based, strongly-typed, intellisense-enabled library providing vehicle abstraction “on code level”.\nBy default our app templates now generate the vehicle model during the devContainer initialization - managed by the Velocitas life cycle management. The respective VSS-based model source is referenced in the app manifest allowing to freely choose the model being used in your project. You will find more details about this in section Automated Model Lifecycle .\nThe previous approach, using pre-generated model repositories, is deprecated as of now. But is still available and is described in section Manual Vehicle Model Creation . Please be aware, that you would either have to use template versions before the above mentioned release, or you need to adapt the newer versions of the template using the old approach.\n","categories":"","description":"Learn how creation of vehicle models work and how to adapt it to your needs.\n","excerpt":"Learn how creation of vehicle models work and how to adapt it to your …","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/","tags":"","title":"Vehicle Model Creation"},{"body":"","categories":"","description":"Learn everything about Velocitas packages.\n","excerpt":"Learn everything about Velocitas packages.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/packages/","tags":"","title":"Packages"},{"body":"Thanks for thinking about contributing to Eclipse Velocitas. We really appreciate the time and effort you want to spend helping to improve Eclipse Velocitas.\nHowever, in order to get you started as fast as possible, we need to go through some organizational issues first.\nEclipse Contributor Agreement Before your contribution can be accepted by the project team, contributors must electronically sign the Eclipse Contributor Agreement (ECA).\nhttp://www.eclipse.org/legal/ECA.php Commits that are provided by non-committers must have a Signed-off-by field in the footer indicating that the author is aware of the terms by which the contribution has been provided to the project. The non-committer must additionally have an Eclipse Foundation account and must have a signed Eclipse Contributor Agreement (ECA) on file.\nFor more information, please see the Eclipse Committer Handbook: https://www.eclipse.org/projects/handbook/#resources-commit Making Your Changes Fork the repository on GitHub. Create a new branch for your changes. Make your changes following the code style guide (see Code Style Guide section above). When you create new files, make sure you include a proper license header at the top of the file (see License Header section below). Make sure you include test cases for non-trivial features. Make sure test cases provide sufficient code coverage (see GitHub actions for minimal accepted coverage). Make sure the test suite passes after your changes. Commit your changes into that branch. Use descriptive and meaningful commit messages. Start the first line of the commit message with the issue number and title e.g., [#9865] Add token-based authentication. Squash multiple commits that are related to each other semantically into a single one. Make sure you use the -s flag when committing as explained above. Push your changes to your branch in your forked repository. Adding Documentation to Hugo Add the markdown document to the appropriate folder in the path velocitas-docs/hugo/hugo/content. Add the front-matter --- title: \"title of the file\" date: 2022-05-09T13:43:25+05:30 --- Additional front matter that can be added – url : \"specifying a definite url to the file\" weight : 10 (used for ordering your content in lists. Lower weight gets higher precedence.) The images need to be put in path velocitas-docs/hugo/hugo/static/assets. The image reference should be /assets/image.jpg in the markdown file. (Note: Do not use relative paths or url) In case you are creating a new folder, create _index.md file with the front matter only. Running Locally Install hugo version 0.98.0 extended Release v0.98.0 · gohugoio/hugo (github.com) Install docsy theme in the path velocitas-docs/hugo/hugo/theme – #Run this command from the root directory of velocitas-docs git clone https://github.com/google/docsy.git hugo/hugo/themes/docsy Install pre-requisites cd themes/docsy/userguide/ npm install npm install --save-dev postcss Run the command hugo server visit localhost:1313 from the velocitas-docs/hugo/hugo directory to see the rendered static site. Submitting the Changes Submit a pull request via the normal GitHub UI.\nAfter Submitting Do not use your branch for any other development, otherwise further changes that you make will be visible in the PR. License Header Please make sure any file you newly create contains a proper license header like this:\n# Copyright (c) \u003cyear\u003e 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 You should, of course, adapt this header to use the specific mechanism for comments pertaining to the type of file you create.\nImportant\nPlease do not forget to add your name/organization to the /legal/legal/NOTICE.md file’s Copyright Holders section. If this is not the first contribution you make, then simply update the time period contained in the copyright entry to use the year of your first contribution as the lower boundary and the current year as the upper boundary, e.g.,\nCopyright 2017, 2018 ACME Corporation\nBuild A pipeline run will be triggered on every PR merge. This run will trigger the hugo docs build Hugo v0.98.0 extended is set up for the runner docsy theme is setup for beautification of static site Then dependencies are installed for the theme Static site is generated and stored in a folder \"public\" The contents of public are committed to gh_pages branch which is exposed to host the GitHub pages ","categories":"","description":"Read how you can contribute to Eclipse Velocitas.\n","excerpt":"Read how you can contribute to Eclipse Velocitas.\n","ref":"/velocitas-docs/docs/contribution-guidelines/","tags":"","title":"Contribution Guidelines"},{"body":"","categories":"","description":"Learn how to run the _Vehicle App_ Runtime Services locally or in Kanto.\n","excerpt":"Learn how to run the _Vehicle App_ Runtime Services locally or in …","ref":"/velocitas-docs/docs/tutorials/vehicle_app_runtime/","tags":"","title":"Vehicle App Runtime"},{"body":"See the Kanto container configuration for details how to write Kanto deployment files.\n","categories":"","description":"Learn how to deploy the _Vehicle App_ to currently supported infrastructure targets.\n","excerpt":"Learn how to deploy the _Vehicle App_ to currently supported …","ref":"/velocitas-docs/docs/tutorials/vehicle_app_deployment/","tags":"","title":"Vehicle App Deployment"},{"body":"To be sure that a newly created Vehicle App will run together with the KUKSA Databroker and potentially other dependant Vehicle Services or Vehicle Apps, it’s essential to write integration tests along with developing the app.\nTo execute an integration test, the dependant components need to be running and be accessible from the test runner. This guide will describe how integration tests can be written and integrated in the CI pipeline so that they are executed automatically when building the application.\nNote This guide is currently only available for development of integration tests with Python. Writing Test Cases To write an integration test, you should check the sample that comes with the template ( /app/tests/integration/integration_test.py ). To support interacting with the MQTT broker and the KUKSA Databroker (to get and set values for data points), there are two classes present in Python SDK that will help:\nMqttClient: this class provides methods for interacting with the MQTT broker. Currently, the following methods are available:\npublish_and_wait_for_response: publishes the specified payload to the given request topic and waits (till timeout) for a message to the response topic. The payload of the first message that arrives in the response topic will be returned. If the timeout expires before, an empty string (\"\") is returned.\npublish_and_wait_for_property: publishes the specified payload to the given request topic and waits (till timeout) until the given property value is found in an incoming message to the response topic. The path describes the property location within the response message, the value the property value to look for.\nExample:\n{ \"status\": \"success\", \"result\": { \"responsecode\": 10 } } If the responsecode property should be checked for the value 10, the path would be [\"result\", \"responsecode\"], property value would be 10. When the requested value has been found in a response message, the payload of that message will be returned. If the timeout expires before receiving a matching message, an empty string (\"\") is returned.\nThis class can be initialized with a given port. If no port is specified, the environment variable MQTT_PORT will be checked. If this is not possible either, the default value of 1883 will be used. It’s recommended to specify no port when initializing that class as it will locally use the default port 1883 and in CI the port is set by the environment variable MQTT_PORT. This will prevent a check-in in the wrong port during local development.\nIntTestHelper: this class provides functionality to interact with the KUKSA Databroker.\nregister_datapoint: registers a new data point with given name and type ( here you can find more information about the available types) set_..._datapoint: set the given value for the data point with the given name (with given type). If the data point does not exist, it will be registered. This class can be initialized with a given port. If no port is specified, the environment variable VDB_PORT will be checked. If this is not possible either, the default value of 55555 will be used. It’s recommended to specify no port when initializing that class as it will locally use the default port 55555 and in CI the port is set by the environment variable VDB_PORT. This will prevent a check-in in the wrong port during local development.\nRuntime components To be able to test the Vehicle App in an integrated way, the following components should be running:\nMosquitto Databroker Vehicle Mock Provider We distinguish between two environments for executing the Vehicle App and the runtime components:\nLocal execution: components are running locally in the development environment Kanto execution: components (and application) are deployed and running in a Kanto control plane Local execution First, make sure that the runtime services are configured and running like described here .\nThe application itself can be executed by using a Visual Studio Launch Config (by pressing F5) or by executing the provided task Local Runtime - Run VehicleApp.\nWhen the runtime services and the application are running, integration tests can be executed locally via\npytest ./app/tests/integration or using the testing tab in the sidebar to the left.\nKanto runtime First, make sure that the runtime and the services are up and running, like described here .\nThe application itself can be deployed by executing the provided task Kanto Runtime - Deploy VehicleApp or Kanto Runtime - Deploy VehicleApp (without rebuild). Depending on whether your app is already available as a container or not.\nWhen the runtime services and the application are running, integration tests can be executed locally via\npytest ./app/tests/integration or using the testing tab in the sidebar to the left.\nIntegration Tests in CI pipeline The tests will be discovered and executed automatically in the provided CI pipeline . The job Run Integration Tests contains all steps to set up and execute all integration tests in the Kanto runtime. Basically it is doing the same steps as you saw above:\nstart the Kanto runtime deploy the Vehicle App container set the correct MQTT and Databroker ports execute the integration tests Finally the test results are collected and published as artifacts of the workflow.\nTroubleshooting Troubleshoot IntTestHelper Make sure that the KUKSA Databroker is up and running by checking the task log. Make sure that you are using the right ports. Make sure that you installed the correct version of the SDK (SDV-package). Troubleshoot Mosquitto (MQTT Broker) Make sure that Mosquitto is up and running by checking the task log. Make sure that you are using the right ports. Use VsMqtt extension to connect to MQTT broker locally (localhost:1883) to monitor topics in MQTT broker by subscribing to all topics using #. Next steps Concept: Deployment Model Concept: Build and release process ","categories":"","description":"Learn how to test that a _Vehicle App_ together with the KUKSA Databroker and potentially other dependant Vehicle Services or _Vehicle Apps_ runs as expected.\n","excerpt":"Learn how to test that a _Vehicle App_ together with the KUKSA …","ref":"/velocitas-docs/docs/tutorials/vehicle_app_development/integration_tests/","tags":"","title":"Vehicle App Integration Testing"},{"body":"Setup a Python Package manually A Vehicle Model should be defined in its own Python Package. This allows to distribute the Vehicle Model later as a standalone package and to use it in different Vehicle App projects.\nThe name of the Vehicle Model package will be my_vehicle_model for this walkthrough.\nStart Visual Studio Code\nSelect File \u003e Open Folder (File \u003e Open… on macOS) from the main menu.\nIn the Open Folder dialog, create a my_vehicle_model folder and select it. Then click Select Folder (Open on macOS).\nCreate a new file setup.py under my_vehicle_model:\nfrom setuptools import setup setup(name='my_vehicle_model', version='0.1', description='My Vehicle Model', packages=['my_vehicle_model'], zip_safe=False) This is the Python package distribution script.\nCreate an empty folder my_vehicle_model under my_vehicle_model.\nCreate a new file __init__.py under my_vehicle_model/my_vehicle_model.\nAt this point the source tree of the Python package should look like this:\nmy_vehicle_model ├── my_vehicle_model │ └── __init__.py └── setup.py To verify that the package is created correctly, install it locally:\npip3 install . The output of the above command should look like this:\nDefaulting to user installation because normal site-packages is not writeable Processing /home/user/projects/my-vehicle-model Preparing metadata (setup.py) ... done Building wheels for collected packages: my-vehicle-model Building wheel for my-vehicle-model (setup.py) ... done Created wheel for my-vehicle-model: filename=my_vehicle_model-0.1-py3-none-any.whl size=1238 sha256=a619bc9fbea21d587f9f0b1c1c1134ca07e1d9d1fdc1a451da93d918723ce2a2 Stored in directory: /home/user/.cache/pip/wheels/95/c8/a8/80545fb4ff73c974ac1716a7bff6f7f753f92022c41c2e376f Successfully built my-vehicle-model Installing collected packages: my-vehicle-model Successfully installed my-vehicle-model-0.1 Finally, uninstall the package again:\npip3 uninstall my_vehicle_model Add Vehicle Models manually Install the Python Vehicle App SDK:\npip3 install git+https://github.com/eclipse-velocitas/vehicle-app-python-sdk.git The output of the above command should end with:\nSuccessfully installed sdv-x.y.z Now it is time to add some Vehicle Models to the Python package. At the end of this section you will have a Vehicle Model, that contains a Cabin model, a Seatmodel and has the following tree structure:\nVehicle └── Cabin └── Seat (Row, Pos) Create a new file Seat.py under my_vehicle_model/my_vehicle_model:\nfrom sdv.model import Model class Seat(Model): def __init__(self, parent): super().__init__(parent) self.Position = DataPointFloat(\"Position\", self) This creates the Seat model with a single data point of type float named Position.\nCreate a new file Cabin.py under my_vehicle_model/my_vehicle_model:\nfrom sdv.model import Model class Cabin(Model): def __init__(self, parent): super().__init__(parent) self.Seat = SeatCollection(\"Seat\", self) class SeatCollection(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Row1 = self.RowType(\"Row1\", self) self.Row2 = self.RowType(\"Row2\", self) def Row(self, index: int): if index \u003c 1 or index \u003e 2: raise IndexError(f\"Index {index} is out of range\") _options = { 1 : self.Row1, 2 : self.Row2, } return _options.get(index) class RowType(Model): def __init__(self, name, parent): super().__init__(parent) self.name = name self.Pos1 = Seat(\"Pos1\", self) self.Pos2 = Seat(\"Pos2\", self) self.Pos3 = Seat(\"Pos3\", self) def Pos(self, index: int): if index \u003c 1 or index \u003e 3: raise IndexError(f\"Index {index} is out of range\") _options = { 1 : self.Pos1, 2 : self.Pos2, 3 : self.Pos3, } return _options.get(index) This creates the Cabin model, which contains a set of six Seat models, referenced by their names or by rows and positions:\nrow=1, pos=1 row=1, pos=2 row=1, pos=3 row=2, pos=1 row=2, pos=2 row=2, pos=3 Create a new file vehicle.py under my_vehicle_model/my_vehicle_model:\nfrom sdv.model import Model from my_vehicle_model.Cabin import Cabin class Vehicle(Model): \"\"\"Vehicle model\"\"\" def __init__(self, name): super().__init__() self.name = name self.Speed = DataPointFloat(\"Speed\", self) self.Cabin = Cabin(\"Cabin\", self) vehicle = Vehicle(\"Vehicle\") The root model of the Vehicle Model tree should be called Vehicle by convention and is specified, by setting parent to None. For all other models a parent model must be specified as the 2nd argument of the Model constructor, as can be seen by the Cabin and the Seat models above.\nA singleton instance of the Vehicle Model called vehicle is created at the end of the file. This instance is supposed to be used in the Vehicle Apps. Creating multiple instances of the Vehicle Model should be avoided for performance reasons.\nAdd a Vehicle Service Vehicle Services provide service interfaces to control actuators or to trigger (complex) actions. E.g. they communicate with the vehicle internal networks like CAN or Ethernet, which are connected to actuators, electronic control units (ECUs) and other vehicle computers (VCs). They may provide a simulation mode to run without a network interface. Vehicle Services may feed data to the Databroker and may expose gRPC endpoints, which can be invoked by Vehicle Apps over a Vehicle Model.\nIn this section, we add a Vehicle Service to the Vehicle Model.\nCreate a new folder proto under my_vehicle_model/my_vehicle_model.\nCopy your proto file under my_vehicle_model/my_vehicle_model/proto\nAs example you could use the protocol buffers message definition seats.proto provided by the KUKSA.VAL services which describes a seat control service .\nInstall the grpcio tools including mypy types to generate the Python classes out of the proto-file:\npip3 install grpcio-tools mypy_protobuf Generate Python classes from the SeatService message definition:\npython3 -m grpc_tools.protoc -I my_vehicle_model/proto --grpc_python_out=./my_vehicle_model/proto --python_out=./my_vehicle_model/proto --mypy_out=./my_vehicle_model/proto my_vehicle_model/proto/seats.proto This creates the following gRPC files under the proto folder:\nseats_pb2.py seats_pb2_grpc.py seats_pb2.pyi Create the SeatService class and wrap the gRPC service:\nfrom sdv.model import Service from my_vehicle_model.proto.seats_pb2 import ( CurrentPositionRequest, MoveComponentRequest, MoveRequest, Seat, SeatComponent, SeatLocation, ) from my_vehicle_model.proto.seats_pb2_grpc import SeatsStub class SeatService(Service): \"SeatService model\" def __init__(self): super().__init__() self._stub = SeatsStub(self.channel) async def Move(self, seat: Seat): response = await self._stub.Move(MoveRequest(seat=seat), metadata=self.metadata) return response async def MoveComponent( self, seatLocation: SeatLocation, component: SeatComponent, position: int, ): response = await self._stub.MoveComponent( MoveComponentRequest( seat=seatLocation, component=component, # type: ignore position=position, ), metadata=self.metadata, ) return response async def CurrentPosition(self, row: int, index: int): response = await self._stub.CurrentPosition( CurrentPositionRequest(row=row, index=index), metadata=self.metadata, ) return response Some important remarks about the wrapping SeatService class shown above:\nThe SeatService class must derive from the Service class provided by the Python SDK. The SeatService class must use the gRPC channel from the Service base class and provide it to the _stub in the __init__ method. This allows the SDK to manage the physical connection to the gRPC service and use service discovery of the middleware. Every method needs to pass the metadata from the Service base class to the gRPC call. This is done by passing the self.metadata argument to the metadata of the gRPC call. ","categories":"","description":"Learn how to create a Vehicle Model manually for Python\n","excerpt":"Learn how to create a Vehicle Model manually for Python\n","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_python/","tags":"","title":"Python Manual Vehicle Model Creation"},{"body":"GitHub rate limit exceeded To avoid exceeding GitHubs rate limit we suggest to generate a personal access token in your GitHub settings and set it as an environment variable:\nMac/Linux Windows export GITHUB_API_TOKEN=\u003cyour_api_token\u003e\nset GITHUB_API_TOKEN=\u003cyour_api_token\u003e or Set environment variable via system settings GITHUB_API_TOKEN=\u003cyour_api_token\u003e\nAfter you have set the ENV consider to restart VS Code.\nIt is important that VS Code has access to this ENV during the postCreateCommand inside the devcontainer. If you experienced this error and the devcontainer still has started correctly please run either:\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ ./.devcontainer/scripts/postCreateCommand.sh or\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas init vscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas sync Debugging inside installed packages Open up a seperate VScode window where you can debug installed toolchain packages.\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ code ~/.velocitas/packages Solution to (almost) all problems The following would clean up the VELOCITAS_HOME but afterwards a new project initialization is required.\nvscode ➜ /workspaces/vehicle-app-python-template (main) $ rm -rf ~/.velocitas vscode ➜ /workspaces/vehicle-app-python-template (main) $ velocitas init ","categories":"","description":"Known issues and fixes.\n","excerpt":"Known issues and fixes.\n","ref":"/velocitas-docs/docs/concepts/lifecycle_management/troubleshooting/","tags":"","title":"Troubleshooting"},{"body":"","categories":"","description":"Learn how to distribute a Vehicle Model.\n","excerpt":"Learn how to distribute a Vehicle Model.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/","tags":"","title":"Vehicle Model Distribution"},{"body":"Rationale: Logging application behavior is absolutely necessary for monitoring applications and also track down possible issues.\nLevels In Velocitas, we establish the following log levels, ordered from lowest to highest priority:\nLevel Purpose Examples Debug Display of information to aid debugging of live systems like resolved values, executed lines of code, taken branches etc… \"variable=5\", \"executing branch debug==false\" Info Display of regular, user friendly messages to indicate the current state of the application. \"Startup successful\", \"Application ready\" Warning Deviation from optimal program flow which is tolerable by the application, but not recommended. \"Memory usage exceeding upper bounds!\",\"Usage of deprecated API\" Error Display of a type of failure that is not expected and can lead to unexpected or degraded behavior which may lead to program termination. \"Memory allocation failed!\", \"Unable to persist data\" Critical Display of a failure which leads to system unavailablity due to a missing feature, i.e. a database connection. \"Database not available\",\"Unable to establish connection to server!\" Destination of log levels Historically On *nix systems the philosophy is for programs to be as silent as possible by default. stdout is reserved for regular program output. Logging is never regular program output, it is there for diagnostic reasons\nSee the ls program as an example:\nls integration logs requirements.txt Regular output is written to stdout and should not be poluted by logging because it is designed to be pipeable into other programs.\nWhat does this mean for Vehicle Apps/Services? An app or a service is a long running, self-contained application which is inheritly not designed to execute and terminate quickly such that its output may be piped into other programs. Therefore, stdout would be free to be used for log levels, since there is no “regular output”.\nHowever, due to the inherent nature of logs not being regular problem output and the issue of potentially re-ordering messages when they are directed to different files, in Velocitas we chose to output all logs to stderr:\nHere the overview in table form: Level Target file Debug stderr Info stderr Warning stderr Error stderr Critical stderr References https://julienharbulot.com/python-cli-streams.html https://sematext.com/blog/logging-levels/ https://softwareengineering.stackexchange.com/questions/439462/log-levels-and-stdout-vs-stderr ","categories":"","description":"How logging shall be handled by Vehicle Applications.\n","excerpt":"How logging shall be handled by Vehicle Applications.\n","ref":"/velocitas-docs/docs/concepts/logging/","tags":"","title":"Logging guidelines"},{"body":"Traditionally, the automotive industry was and still is centered around vehicle hardware and the corresponding hardware development and life-cycle management. Software, however, is gaining more and more importance in vehicle development and over the entire vehicle lifetime. Thus, the vehicle and its value to the customer is increasingly defined by software. This transition towards what are termed as software-defined vehicles changes the way in which we innovate, code, deliver and work together. It is a change across the whole mobility value chain and life-cycle: from development and production to delivery and operations of the vehicle.\n","categories":"","description":"","excerpt":"Traditionally, the automotive industry was and still is centered …","ref":"/velocitas-docs/docs/","tags":"","title":"Velocitas"},{"body":"Besides starting the vehicle runtime components locally , another way is to deploy them as containers using Kanto . To start the runtime, we provide VS Code Tasks, a feature of Visual Studio Code. Additional information on tasks can be found here .\nQuick Start: Each step has a task that is defined in /.vscode/tasks.json:\nCore tasks (dependent on each other in the given order):\nKanto - Runtime Up: Starts up the Kanto runtime and deploys the runtime components. Kanto - Build VehicleApp: Builds the VehicleApp. Kanto - Deploy VehicleApp: Deploys the VehicleApp as container in the Kanto runtime. Optional helper tasks:\nKanto - Deploy VehicleApp (without rebuild): Deploys the VehicleApp as container in the Kanto runtime but does not build it upfront. That requires, that the task Kanto - Build VehicleApp has been executed once before. Kanto - Runtime Down: Stops the Kanto runtime and all deployed containers. Run as Bundle: To orchestrate these tasks, you can use the task Kanto - Deploy VehicleApp. This task runs the other tasks in the correct order. You can run this task by clicking F1 and choose Tasks: Run task, then select Kanto - Deploy VehicleApp.\nTasks Management: Visual Studio Code offers various other commands concerning tasks like Start/Terminate/Restart/… You can access them by pressing F1 and typing task. A list with available task commands will appear.\nLogging: Running tasks appear in the Terminals View of Visual Studio Code. From there, you can see the logs of each running task. More detailed logs can be found inside your workspace’s logs directory ./logs/*\nKantUI The Leda team developed a tool to easily work with Kanto. It is similar to K9S for Kubernetes. You can find more details about KantUI in the documentation of Leda .\nIn the devcontainer KantUI is already installed and it can be started via:\nsudo kantui After starting the Kanto runtime with the mentioned tasks above, you will directly see all the running containers in KantUI. Now you could also take a look at the logs, delete or stop single containers. After you deployed your application to Kanto, this container will also show up and can be handled with KantUI.\nMounting folders for FeederCAN Some applications (e.g. FeederCAN) might make it necessary to load custom files from a mounted volume. All the files that are located in [./config/feedercan](https://github.com/eclipse-velocitas/devenv-runtimes/tree/main/config/feedercan) will be automatically mounted into the container. In order to mount files to the directory that is accessible by the application, please refer to the deployment configuration file: runtime-kanto/src/runtime/deployment/feedercan.json .\nUploading custom candump file to FeederCAN FeederCAN requires a candump file. A pre-defined candump file is already part of our delivery, however, if necessary, there is an option to upload a custom file by:\nCreating/updating candump file with the name candumpDefault.log in ./config/feedercan Restarting Kanto (execute the tasks Kanto - Runtime Down and Kanto - Runtime Up) More information about the CAN Provider can be found here Next steps Concept: Deployment Model Concept: Build and release process Tutorial: Start runtime services locally Tutorial: Quickstart ","categories":"","description":"Learn how to run the _Vehicle App_ Runtime Services in Kanto.\n","excerpt":"Learn how to run the _Vehicle App_ Runtime Services in Kanto.\n","ref":"/velocitas-docs/docs/tutorials/vehicle_app_runtime/kanto_runtime/","tags":"","title":"Kanto Runtime"},{"body":" Eclipse Velocitas™ Toolchain for creating containerized in-vehicle applications\nQuickstart Concepts Tutorials The Eclipse project Velocitas™ provides an end-to-end, scalable and modular development toolchain to create containerized in-vehicle applications (Vehicle Apps) that offers a comfortable, fast and efficient development experience to increase the velocity of a development team. Vehicle App Project Template Quick setup of a Vehicle App project with the help of GitHub templates for the supported programming languages including a sample Vehicle App and GitHub Actions workflow, and comfortable setup of the development environment e.g. in Microsoft Visual Studio Code.\nRead more …\nVehicle App Development Model Simplify coding and debugging of Vehicle Apps that access vehicle data points and call vehicle functions using the provided SDK for the different programming languages that delegates to the Vehicle Abstraction Layer.\nRead more …\nVehicle Abstraction Layer Abstracts vehicle make \u0026 model specific properties and capabilities to a common representation. This makes it possible for Vehicle Apps to be portable across different electric and electronic vehicle architectures e.g. the Vehicle Apps do not care whether the seat is controlled via CAN, LIN or some other physical interface.\nRead more …\nGitHub Actions Workflow Blueprint Providing ready-to-use GitHub workflows to check the Vehicle App, build images for multi architectures, scan it, execute integration tests and release the Vehicle App to allow the developer to focus on the development of the Vehicle App.\nRead more …\nAutomated Release Process Providing a release workflow to generate release artifacts and documentation out of the CI workflow results and push it to the GitHub container registry to be used by a deployment system.\nRead more …\nDeployment Model Running and deploying Vehicle App as OCI-compliant container to increase the flexibility to support different programming languages and runtimes to accelerate innovation and development.\nRead more …\n","categories":"","description":"","excerpt":" Eclipse Velocitas™ Toolchain for creating containerized in-vehicle …","ref":"/velocitas-docs/","tags":"","title":""},{"body":" --- title: Community menu: main: weight: 40 --- ","categories":"","description":"","excerpt":" --- title: Community menu: main: weight: 40 --- ","ref":"/velocitas-docs/community/","tags":"","title":""},{"body":"","categories":"","description":"","excerpt":"","ref":"/velocitas-docs/categories/","tags":"","title":"Categories"},{"body":"","categories":"","description":"","excerpt":"","ref":"/velocitas-docs/tags/","tags":"","title":"Tags"}] \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index ebd59e1d..6d7e3af3 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -3,169 +3,181 @@ xmlns:xhtml="http://www.w3.org/1999/xhtml"> /velocitas-docs/docs/tutorials/prototyping/digital_auto/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_app_runtime/local_runtime/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_app_development/python_development/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/quickstart/quickstart/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/about/use_cases/seat_adjuster/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/lifecycle_management/packages/usage/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/about/use_cases/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/quickstart/import_examples/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/about/use_cases/dog_mode/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/quickstart/container_runtime/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/quickstart/behind_proxy/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_app_development/cpp_development/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/lifecycle_management/packages/development/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/prototyping/service_integration/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/development_model/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/deployment_model/vehicle_app_releases/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/deployment_model/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/about/repository-overview/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/interfaces/vehicle_signal_interface/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/interfaces/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_model_creation/automated_model_lifecycle/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/lifecycle_management/project_configuration/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/about/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 + + /velocitas-docs/docs/concepts/development_model/val/grpc_style_guide/ + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_cpp/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/quickstart/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/development_model/vehicle_app_sdk/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/interfaces/grpc_interface/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/interfaces/pubsub/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/lifecycle_management/phases/create/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/lifecycle_management/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/lifecycle_management/velocitas_cli/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/prototyping/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/development_model/val/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_cpp/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/lifecycle_management/phases/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/development_model/vehicle_app_manifest/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/distribution_python/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_app_development/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_model_creation/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/lifecycle_management/packages/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/contribution-guidelines/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_app_runtime/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 + + /velocitas-docs/docs/tutorials/grpc_service_generation/create_client/ + 2024-09-12T08:10:31+02:00 + + /velocitas-docs/docs/tutorials/grpc_service_generation/create_server/ + 2024-09-12T08:10:31+02:00 + + /velocitas-docs/docs/tutorials/grpc_service_generation/ + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_app_deployment/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_app_development/integration_tests/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/manual_creation_python/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/lifecycle_management/troubleshooting/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_model_creation/manual_model_creation/vehicle_model_distribution/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/concepts/logging/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/docs/tutorials/vehicle_app_runtime/kanto_runtime/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/community/ - 2024-05-31T11:58:59+02:00 + 2024-09-12T08:10:31+02:00 /velocitas-docs/categories/ diff --git a/tags/index.html b/tags/index.html index 7b7c97eb..0e19ff31 100644 --- a/tags/index.html +++ b/tags/index.html @@ -85,7 +85,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/velocitas-docs/offline-search-index.b9de75ab8ed72d4d7a8d8ab3558d3364.json" + data-offline-search-index-json-src="/velocitas-docs/offline-search-index.898608b2e212281545d5ed2fdb781372.json" data-offline-search-base-href="/" data-offline-search-max-results="10" >