From 5b3fa86e609ab388f9d5fa918c8d2eaa918bd58d Mon Sep 17 00:00:00 2001 From: jorchiu <122116059+jorchiu@users.noreply.github.com> Date: Fri, 17 Nov 2023 11:10:04 -0800 Subject: [PATCH] Add opening tutorial and consumer tutorial. (#70) --- docs/tutorials/README.md | 55 +++++++ docs/tutorials/consumer/README.md | 129 +++++++++++++++++ docs/tutorials/in_vehicle_model/README.md | 8 +- docs/tutorials/provider/README.md | 137 +++++++----------- .../tutorial/provider/src/provider_impl.rs | 4 +- 5 files changed, 245 insertions(+), 88 deletions(-) create mode 100644 docs/tutorials/README.md create mode 100644 docs/tutorials/consumer/README.md diff --git a/docs/tutorials/README.md b/docs/tutorials/README.md new file mode 100644 index 00000000..c4a6669b --- /dev/null +++ b/docs/tutorials/README.md @@ -0,0 +1,55 @@ +# Ibeji Tutorials + +- [Introduction](#introduction) +- [Run the Tutorial Demo](#run-the-tutorial-demo) + +## Introduction + +It is recommend to follow this sequence for tutorial completion: + +1. [Tutorial: Create an In-Vehicle Digital Twin Model With DTDL](./in_vehicle_model/README.md) + +1. [Tutorial: Create a Digital Twin Provider](./provider/README.md) + +1. [Tutorial: Create a Digital Twin Conusmer](./consumer//README.md) + +## Run the Tutorial Demo + +1. The best way to run the demo is by using three windows: one running the In-Vehicle Digital Twin, one running the Digital Twin Provider and one running the Digital Twin Consumer. Orientate the three windows so that they are lined up in a column. The top window can be used for the In-Vehicle Digital Twin. The middle window can be used for the Digital Twin Provider. The bottom window can be used for the Digital Twin Consumer. +In each window, change the current directory to the directory containing the build artifacts. Make sure that you replace "{repo-root-dir}" with the repository root directory on the machine where you are running the demo. + +1. cd {repo-root-dir}/target/debug +Create the three config files with the following contents, if they are not already there: + +---- consumer_settings.yaml ---- + +```yaml +invehicle_digital_twin_uri: "http://0.0.0.0:5010" +``` + +---- invehicle_digital_twin_settings.yaml ---- + +```yaml +invehicle_digital_twin_authority: "0.0.0.0:5010" +``` + +---- provider_settings.yaml ---- + +```yaml +provider_authority: "0.0.0.0:4010" +invehicle_digital_twin_uri: "http://0.0.0.0:5010" +``` + +1. In the top window, run: + + `./invehicle-digital-twin` + +1. In the middle window, run: + + `./digital-twin-provider-tutorial` + +1. In the bottom window, run: + + `./digital-twin-consumer-tutorial` + +1. Use control-c in each of the windows when you wish to stop the demo. diff --git a/docs/tutorials/consumer/README.md b/docs/tutorials/consumer/README.md new file mode 100644 index 00000000..ccac3706 --- /dev/null +++ b/docs/tutorials/consumer/README.md @@ -0,0 +1,129 @@ +# Tutorial: Create a Digital Twin Consumer + +- [Introduction](#introduction) +- [Prerequisites](#prerequisites) +- [1. Create an Ibeji Digital Twin Consumer](#1-create-an-ibeji-digital-twin-consumer) + - [1.1 Define the Interaction with a Digital Twin Provider](#11-define-the-interaction-with-a-digital-twin-provider) + - [Rust Sample Implementation of the Interaction with a Digital Twin Provider](#rust-sample-implementation-of-the-interaction-with-a-digital-twin-provider) +- [2. Discover a Digital Twin Provider with the In-Vehicle Digital Twin Service](#2-discover-a-digital-twin-provider-with-the-in-vehicle-digital-twin-service) + - [2.1 Rust Sample Discovery of a Digital Twin Provider](#21-rust-sample-discovery-of-a-digital-twin-provider) +- [3. Add Managed Subscribe to Digital Twin Consumer](#3-add-managed-subscribe-to-digital-twin-consumer) + - [3.1 Rust Sample Implementation of a Managed Subscribe Digital Twin Consumer](#31-rust-sample-implementation-of-a-managed-subscribe-digital-twin-consumer) +- [Next Steps](#next-steps) + +## Introduction + +>[Digital Twin Consumer:](../../../docs/design/README.md#architecture) A Digital Twin Consumer is a software entity that utilizes Ibeji to interface with the digital representation of the In-Vehicle hardware components. In the [Tutorial: Create a Digital Twin Provider](../provider/README.md), you have learned that a `digital twin provider` exposes a subset of the in-vehicle's hardware capabilities. Each in-vehicle hardware capability includes metadata that allows digital twin consumers to comprehend the nature of the capability, how to work with it and how it can be remotely accessed. + +In this tutorial, you will leverage the code for the in-vehicle digital twin model that you have developed in the [Tutorial: Create an In-Vehicle Digital Twin Model with DTDL](../in_vehicle_model/README.md), and the digital twin provider that you have created in the [Tutorial: Create a Digital Twin Provider](../provider/README.md). You will learn how to create a digital twin consumer. Using Ibeji's [In-Vehicle Digital Twin Service](../../design/README.md#in-vehicle-digital-twin-service), you will learn how to find a digital twin provider that exposes the desired in-vehicle capabilities to your digital twin consumer. + +This tutorial references the code in the `{repo-root-dir}/samples/tutorial` directory. Relevant code snippets are explicitly highlighted and discussed to ensure a clear understanding of the concepts. + +## Prerequisites + +- Complete the [Tutorial: Create a Digital Twin Provider](../provider/README.md). +- Basic knowledge about [Protocol Buffers (protobufs) version 3.0](https://protobuf.dev/programming-guides/proto3/). +- Basic knowledge about the [gRPC protocol](https://grpc.io/docs/what-is-grpc/introduction/). + +## 1. Create an Ibeji Digital Twin Consumer + +In this section, you will learn how to develop a digital twin consumer that communicates with the [digital twin provider that you have created in the previous tutorial](../provider/README.md#rust-sample-implementation-of-the-sample-interface) via [gRPC](https://grpc.io/docs/what-is-grpc/introduction/). Remember digital twin providers are protocol-agnostic. This means they are not limited to gRPC, they can use other communication protocols. + +To interact with a digital twin provider, the digital twin consumer must use the same communication protocol and understand the interface contract. The programming language of the digital twin consumer and the digital twin provider does not need to match. + +The `{repo-root-dir}/samples/tutorial/consumer` directory contains the code for the sample digital twin consumer used in this tutorial. The `{repo-root-dir}/digital-twin-model/src` directory contains the Rust code for the in-vehicle digital twin model that you have constructed in [Tutorial: Create an In-Vehicle Digital Twin Model with DTDL](../in_vehicle_model/README.md) along with additional signals that are not needed for this tutorial. + +Throughout this tutorial, the sample contents in the `{repo-root-dir}/samples/tutorial` directory are referenced to guide you through the process of creating a digital twin consumer. + +### 1.1 Define the Interaction with a Digital Twin Provider + +You have defined a [digital twin provider's interface](../provider/README.md#11-define-digital-twin-provider-interface). A digital twin consumer needs to utilize that interface to communicate with your digital twin provider to access the in-vehicle capabilities that a digital twin provider makes available. + +The following discusses the steps that a digital twin consumer should take to interact with a digital twin provider using the programming language of your choice. + +1. Examine the digital twin provider's interface. Make sure that you understand its contract and the communication protocol that it uses. + +1. Choose a programming language that supports both gRPC and your digital twin provider's communication protocol. gRPC is required to communicate with the In-Vehicle Digital Twin Service. This will be described further in [2. Discover a Digital Twin Provider with the In-Vehicle Digital Twin Service](#2-discover-a-digital-twin-provider-with-the-in-vehicle-digital-twin-service). For instance, if your digital twin provider uses MQTT, then you should select a programming language that supports both MQTT and gRPC. This includes languages like Rust, Python, Java, C++ and Go. + +1. In the implementation of your digital twin consumer, import the code for your in-vehicle digital twin model that you have developed in the [Tutorial: Create an In-Vehicle Digital Twin Model with DTDL](../in_vehicle_model/README.md#3-translating-dtdl-to-code). + +1. In your digital twin consumer, call the desired operations of the digital twin provider to access the desired in-vehicle capabilities. You can reference an in-vehicle capability's model id using the [code for your in-vehicle digital twin model](../in_vehicle_model/README.md#3-translating-dtdl-to-code). + +#### Rust Sample Implementation of the Interaction with a Digital Twin Provider + +This section shows a sample digital twin consumer interacting with a digital twin provider in Rust. It uses the [sample digital twin provider interface](../provider/README.md#sample-digital-twin-provider-interface) that is defined in a protobuf file, and it covers calling the `Get` and `Invoke` operations that are defined in the [sample digital twin provider](../../../samples/tutorial/provider/src/provider_impl.rs). This is the same sample digital twin provider that is shown in the [Tutorial: Create a Digital Twin Provider](../provider/README.md#rust-sample-implementation-of-the-sample-interface). + +1. Refer to the [Rust code for the sample digital twin consumer](../../../samples/tutorial/consumer/src/main.rs). + +1. There is an import statement for the Rust in-vehicle digital twin model that is shown in the [Tutorial: Create an In-Vehicle Digital Model with DTDL](../in_vehicle_model/README.md#3-translating-dtdl-to-code): + + ```rust + use digital_twin_model::{sdv_v1 as sdv, ...}; + ``` + +1. This sample digital twin consumer aims to communicate with a digital twin provider through gRPC, so there is an imported gRPC client. + + ```rust + use samples_protobuf_data_access::tutorial_grpc::v1::digital_twin_provider_tutorial_client::DigitalTwinProviderTutorialClient; + ``` + +1. The [sample digital twin provider](../../../samples/tutorial/provider/src/provider_impl.rs) has a `Get` operation defined. This operation is called by the sample digital consumer in the `send_get_request` method. + +1. The [sample digital twin provider](../../../samples/tutorial/provider/src/provider_impl.rs) has an `Invoke` operation defined. This operation is called by the sample digital consumer in the `start_show_notification_repeater` method. + +### 2. Discover a Digital Twin Provider with the In-Vehicle Digital Twin Service + +You have defined a [digital twin provider's interface](../provider/README.md#11-define-digital-twin-provider-interface). You have defined the interactions that your digital twin consumer needs to communicate with the digital twin provider to access the in-vehicle capabilities that the digital twin provider makes available. + +A digital twin consumer needs to discover the digital twin provider using the [In-Vehicle Digital Twin Service](../../../README.md#high-level-design) before it can interact with the digital twin provider. + +The following discusses the steps that your digital twin consumer should take to discover a digital twin provider in the programming language of your choice: + +1. Refer to the interface of the [In-Vehicle Digital Twin Service](../../../interfaces/invehicle_digital_twin/v1/invehicle_digital_twin.proto) which is defined as a protobuf file. + +1. In the code for your digital twin consumer, you will need to import an `In-Vehicle Digital Twin Service` gRPC client. + +1. For each in-vehicle capability required by your digital twin consumer, the digital twin consumer should utilize an `In-Vehicle Digital Twin Service` gRPC client to discover the corresponding digital twin provider. This involves calling the `FindById` gRPC method with the gRPC client. Please see the sequence diagram for [Find By Id](../../design/README.md#find-by-id) for more details. + +1. When trying to discover a digital twin provider for an in-vehicle capability, your digital twin consumer can refer to the capability's model id by using the [code for your in-vehicle digital twin model](../in_vehicle_model/README.md#3-translating-dtdl-to-code). + +### 2.1 Rust Sample Discovery of a Digital Twin Provider + +This section uses the same *sample* Rust implementation of the digital twin consumer in the [Rust Sample Implementation of the Interaction with a Digital Twin Provider](#rust-sample-implementation-of-the-interaction-with-a-digital-twin-provider) section. This digital twin consumer uses an `In-Vehicle Digital Twin Service` gRPC client to discover the signals *ambient air temperature* and *is air conditioning active*, as well as the command *show notification*. + +1. Refer to the [code for the sample digital twin consumer](../../../samples/tutorial/consumer/src/main.rs). + +1. One function of interest in the [code for the sample digital twin consumer](../../../samples/tutorial/consumer/src/main.rs) is the `discover_digital_twin_provider_using_ibeji` helper function in the [sample commons utils](../../../samples/common/src/utils.rs). This is a helper function for discovering a digital twin provider through the In-Vehicle Digital Twin Service. + + ```rust + /// Use Ibeji to discover the endpoint for a digital twin provider that satifies the requirements. + /// + /// # Arguments + /// * `invehicle_digitial_twin_service_uri` - In-vehicle digital twin service URI. + /// * `entity_id` - The matching entity id. + /// * `protocol` - The required protocol. + /// * `operations` - The required operations. + pub async fn discover_digital_twin_provider_using_ibeji( + invehicle_digitial_twin_service_uri: &str, + entity_id: &str, + protocol: &str, + operations: &[String], + ) -> Result {..} + ``` + + The `discover_digital_twin_provider_using_ibeji` function is called in the main function to discover the provider's endpoints for the signals *ambient air temperature* and *is air conditioning active*, as well as the command *show notification*. This Rust sample digital twin consumer shows how to discover a digital twin provider that uses gRPC and supports the desired operations of the digital twin consumer. + +## 3. Add Managed Subscribe to Digital Twin Consumer + +In the previous [Tutorial: Create a Digital Twin Provider](../provider/README.md), the [Managed Subscribe module was introduced for digital twin providers](../provider/README.md#3-add-managed-subscribe-to-digital-twin-provider). + +Please consult the [Managed Subscribe interface](../../../interfaces/module/managed_subscribe/v1/managed_subscribe.proto), and the [documentation for the Managed Subscribe sample](../../../samples/managed_subscribe/README.md) for guidance on developing a digital twin consumer to communicate with a digital twin provider that supports the `Managed Subscribe` module. + +### 3.1 Rust Sample Implementation of a Managed Subscribe Digital Twin Consumer + +Please refer to the [sample Rust code for the Managed Subscribe Sample Consumer](../../../samples/managed_subscribe/consumer/src/) to see an example of how to integrate the Managed Subscribe module into a digital twin consumer. +This sample Rust code contains an *ambient air temperature* signal, and does not include the in-vehicle signal *is air conditioning active* and the command *show notification*. + +## Next Steps + +- Run the entire tutorial demo by following the steps in [Run the Tutorial](../README.md#run-the-tutorial) diff --git a/docs/tutorials/in_vehicle_model/README.md b/docs/tutorials/in_vehicle_model/README.md index 6f8972c5..0015c839 100644 --- a/docs/tutorials/in_vehicle_model/README.md +++ b/docs/tutorials/in_vehicle_model/README.md @@ -1,4 +1,4 @@ -# Tutorial: Create an In-vehicle Model With DTDL +# Tutorial: Create an In-Vehicle Digital Twin Model with DTDL - [Introduction](#introduction) - [1. Create an In-Vehicle Digital Twin Model with DTDL](#1-create-an-in-vehicle-digital-twin-model-with-dtdl) @@ -13,13 +13,13 @@ ## Introduction -In this tutorial, you will learn how to create an in-vehicle model using [Digital Twins Definition Language (DTDL) version 3.0](https://azure.github.io/opendigitaltwins-dtdl/DTDL/v3/DTDL.v3.html), and build a corresponding Rust in-vehicle model. The focus will be on translating DTDL to a programming language. While Rust is used here to be consistent with Ibeji's samples (which are in Rust), you can use any programming language. +In this tutorial, you will learn how to create an in-vehicle digital twin model using [Digital Twins Definition Language (DTDL) version 3.0](https://azure.github.io/opendigitaltwins-dtdl/DTDL/v3/DTDL.v3.html), and build a corresponding Rust in-vehicle digital twin model. The focus will be on translating DTDL to a programming language. While Rust is used here to be consistent with Ibeji's samples (which are in Rust), you can use any programming language. This tutorial provides a basic understanding of DTDL in the context of our Ibeji samples, but it is not a comprehensive guide to DTDL. Specifically, it covers [interfaces](https://azure.github.io/opendigitaltwins-dtdl/DTDL/v3/DTDL.v3.html#interface), [commands](https://azure.github.io/opendigitaltwins-dtdl/DTDL/v3/DTDL.v3.html#command), [properties](https://azure.github.io/opendigitaltwins-dtdl/DTDL/v3/DTDL.v3.html#property) Please refer to the [DTDL v3](https://azure.github.io/opendigitaltwins-dtdl/DTDL/v3/DTDL.v3.html) documentation for more information on DTDL. ->Note: DTDL is used to define a digital twin model of the in-vehicle's hardware. Currently in Ibeji, DTDL serves as a guide to manually construct the in-vehicle model in code. In the future, the in-vehicle model code should be generated from a DTDL file. +>Note: DTDL is used to define a digital twin model of the in-vehicle's hardware. Currently in Ibeji, DTDL serves as a guide to manually construct the in-vehicle digital twin model in code. In the future, the in-vehicle digital twin model code should be generated from a DTDL file. ## 1. Create an In-Vehicle Digital Twin Model with DTDL @@ -241,7 +241,7 @@ In the `hmi` module, there is a `show_notification` submodule that represents th Similarly, in the `hvac` module, there are two submodules: `ambient_air_temperature` and `is_air_conditioning_active`. These represent the `AmbientAirTemperature` and `IsAirConditioningActive` properties in the `hvac.json` DTDL. Each submodule has an `ID`, `NAME`, `DESCRIPTION` and `TYPE` constants, which correspond to the `@id`, `name`, `description`, and `schema` fields in DTDL. -This Rust code is a way to use a DTDL model in a Rust program, with each DTDL element represented as a Rust module, constant, or type. You can translate a DTDL model into other programming languages. Use the `@id` fields in your in-vehicle digital twin model as guidance to code your in-vehicle model. +This Rust code is a way to use a DTDL model in a Rust program, with each DTDL element represented as a Rust module, constant, or type. You can translate a DTDL model into other programming languages. Use the `@id` fields in your in-vehicle digital twin model as guidance to translate your in-vehicle digital model to code. Both Ibeji providers and Ibeji consumers can utilize this code. This code serves as a set of constants to standardize the values used in their communication with Ibeji, which ensures a consistent and reliable exchange of information. diff --git a/docs/tutorials/provider/README.md b/docs/tutorials/provider/README.md index 611ef79a..6c8190ee 100644 --- a/docs/tutorials/provider/README.md +++ b/docs/tutorials/provider/README.md @@ -9,29 +9,29 @@ - [Rust Sample Implementation of the Sample Interface](#rust-sample-implementation-of-the-sample-interface) - [2. Register a Digital Twin Provider with the In-Vehicle Digital Twin Service](#2-register-digital-twin-provider-with-the-in-vehicle-digital-twin-service) - [2.1 Rust Sample Registration of a Digital Twin Provider](#21-rust-sample-registration-of-a-digital-twin-provider) - - [Run the Sample Digital Twin Provider](#run-the-sample-digital-twin-provider) - [3. Add Managed Subscribe to Digital Twin Provider](#3-add-managed-subscribe-to-digital-twin-provider) + - [3.1 Rust Sample Implementation of a Managed Subscribe Digital Twin Provider](#31-rust-sample-implementation-of-a-managed-subscribe-digital-twin-provider) - [Next Steps](#next-steps) ## Introduction >[Digital Twin Provider:](../../../README.md#high-level-design) A provider exposes a subset of the vehicle's hardware capabilities by registering them with the In-Vehicle Digital Twin Service. Once registered with the In-Vehicle Digital Twin Service they can in turn be offered to Ibeji consumers. Each capability includes metadata that allows Ibeji consumers to comprehend the nature of the capability, how to work with it and how it can be remotely accessed. -In this tutorial, you will leverage your in-vehicle model in code that you have created in [Tutorial: Create an In-Vehicle Model with DTDL](../in_vehicle_model/README.md) to create a digital twin provider. Additionally, you will learn how to register your digital twin provider with the [In-Vehicle Digital Twin Service](../../design/README.md#in-vehicle-digital-twin-service). +In this tutorial, you will leverage the code for your in-vehicle digital twin model that you have developed in [Tutorial: Create an In-Vehicle Digital Twin Model with DTDL](../in_vehicle_model/README.md) to create a digital twin provider. Additionally, you will learn how to register your digital twin provider with the [In-Vehicle Digital Twin Service](../../design/README.md#in-vehicle-digital-twin-service). -This tutorial will reference the sample code provided in Ibeji to keep the tutorial concise. Relevant code snippets are explicitly highlighted and discussed to ensure a clear understanding of the concepts. +This tutorial references the code in the `{repo-root-dir}/samples/tutorial` directory. Relevant code snippets are explicitly highlighted and discussed to ensure a clear understanding of the concepts. ## Prerequisites -- Complete the tutorial in [Tutorial: Create an In-Vehicle Model with DTDL](../in_vehicle_model/README.md). +- Complete the [Tutorial: Create an In-Vehicle Digital Twin Model with DTDL](../in_vehicle_model/README.md). - Basic knowledge about [Protocol Buffers (protobufs) version 3.0](https://protobuf.dev/programming-guides/proto3/). - Basic knowledge about the [gRPC protocol](https://grpc.io/docs/what-is-grpc/introduction/). ## 1. Create an Ibeji Digital Twin Provider -In this section, you will learn how to develop a digital twin provider that communicates with its digital twin consumers via [gRPC](https://grpc.io/docs/what-is-grpc/introduction/). It is important to note that digital twin providers in Ibeji are protocol-agnostic. This means they are not restricted to using gRPC and can employ other communication protocols. +In this section, you will learn how to develop a digital twin provider that communicates with its digital twin consumers via [gRPC](https://grpc.io/docs/what-is-grpc/introduction/). It is important to note that digital twin providers in Ibeji are protocol-agnostic. This means they are not limited to gRPC, they can use other communication protocols. -The `{repo-root-dir}/samples/tutorial` directory contains code for the sample digital twin provider used in this tutorial. The `{repo-root-dir}/digital-twin-model/src` contains the in-vehicle model in Rust code that you have constructed in [Tutorial: Create an In-Vehicle Model with DTDL](../in_vehicle_model/README.md) along with additional signals not needed for this tutorial. +The `{repo-root-dir}/samples/tutorial` directory contains code for the sample digital twin provider used in this tutorial. The `{repo-root-dir}/digital-twin-model/src` directory contains the in-vehicle digital twin model in Rust code that you have constructed in [Tutorial: Create an In-Vehicle Digital Twin Model with DTDL](../in_vehicle_model/README.md) along with additional signals that are not needed for this tutorial. Throughout this tutorial, the sample contents in the `{repo-root-dir}/samples/tutorial` directory are referenced to guide you through the process of creating a digital twin provider. @@ -47,9 +47,9 @@ The [digital twin provider tutorial interface](../../../samples/interfaces/tutor This section provides an example of a digital twin provider interface. To reiterate, you are free to use this interface as a starting point or you may come up with your own convention. -1. Consider the in-vehicle signals *ambient air temperature* and *is air conditioning active*, as well as the command *show notification* that you defined in the [Tutorial: Create an In-Vehicle Model with DTDL](../in_vehicle_model/README.md). +1. Consider the in-vehicle signals *ambient air temperature* and *is air conditioning active*, as well as the command *show notification* that you defined in the [Tutorial: Create an In-Vehicle Digital Twin Model with DTDL](../in_vehicle_model/README.md). -1. Reference the [sample digital twin provider tutorial interface](../../../samples/interfaces/tutorial/digital_twin_provider.proto): +1. Refer to the [sample digital twin provider tutorial interface](../../../samples/interfaces/tutorial/digital_twin_provider.proto): In this digital twin provider sample interface, the conventions that this interface enforces are as follows: @@ -57,7 +57,7 @@ In this digital twin provider sample interface, the conventions that this interf - A digital twin consumer should utilize the `Invoke` operation to send a *show notification* command. -When introducing additional signals and commands, it is crucial to carefully select the operation(s) that best align with the behavior of each signal or command. This ensures a seamless integration and optimal performance of your system. +When introducing additional capabilities, it is crucial to carefully select the operation(s) that best align with the behavior of each capability. This ensures a seamless integration and optimal performance of your system. ### 1.2 Implement the Operations of a Digital Twin Provider Interface @@ -65,13 +65,14 @@ You have defined your digital twin provider interface. The following lists out the flow for implementing the operations of a digital twin interface in the programming language of your choice: -1. Choose Your Programming Language: Since operations can be defined in a protobuf file, you can select any programming language that supports protobufs. This includes languages like Rust, Python, Java, C++, Go, etc. However, operations do not need to be defined in a protobuf file to be programming language agnostic. For instance, if you have a subscribe operation you may want to use [MQTT](https://mqtt.org/) for publishing to digital twin consumers that have subscribed to your digital twin provider. Please see the [Managed Subscribe Sample](https://github.com/eclipse-ibeji/ibeji/tree/main/samples/managed_subscribe) and [Property Sample](../../../samples/property/provider/src/main.rs) for Rust examples of a digital twin provider using MQTT. +1. Choose a programming language that supports gRPC. gRPC is required to communicate with the In-Vehicle Digital Twin Service. This will be described further in [2. Register Digital Twin Provider with the In-Vehicle Digital Twin Service](#2-register-digital-twin-provider-with-the-in-vehicle-digital-twin-service). This includes languages like Rust, Python, Java, C++ and Go. + >Note: Operations can be performed by various protocols. Some protocols require that the operation's interface contract is specified. For example in gRPC, the operation must be specified in a protobuf file. Operations are programming language and protocol agnostic. If you have a subscribe operation, you may want to use [MQTT](https://mqtt.org/) for publishing to digital twin consumers that have subscribed to your digital twin provider. Please see the [Managed Subscribe Sample](../../../samples/managed_subscribe/README.md) and [Property Sample](../../../samples/property/provider/src/main.rs) for Rust examples of a digital twin provider using MQTT. -1. In your implementation, import the code of your in-vehicle digital twin model that you have created in the [Tutorial: Create an In-Vehicle Model with DTDL](../in_vehicle_model/README.md#3-translating-dtdl-to-code). +1. In your implementation, import the code for your in-vehicle digital twin model that you have developed in the [Tutorial: Create an In-Vehicle Digital Twin Model with DTDL](../in_vehicle_model/README.md#3-translating-dtdl-to-code). -1. Implement the operations you have defined in your interface. This involves writing the logic for what should happen to each in-vehicle signal or command when each operation is called. If you are using the [sample digital twin provider interface](#sample-digital-twin-provider-interface), you need to implement the functionality for the `Get` and `Invoke` operations. +1. Implement the operations that you have defined in your interface. This involves writing the logic for what should happen to each in-vehicle capability when each operation is called. If you are using the [sample digital twin provider interface](#sample-digital-twin-provider-interface), you need to implement the functionality for the `Get` and `Invoke` operations. -1. For each operation you implement, you can reference an in-vehicle signal or command using the code of your in-vehicle digital twin model. +1. For each operation you implement, you can refer to an in-vehicle capability using the [code for your in-vehicle digital twin model](../in_vehicle_model/README.md#3-translating-dtdl-to-code). In order to translate your operations into code, it is important to understand the requirements of each operation. @@ -79,36 +80,36 @@ In order to translate your operations into code, it is important to understand t This section uses the [sample digital twin provider interface](#sample-digital-twin-provider-interface) that is defined in a protobuf file, and covers a *sample* Rust implementation of the synchronous `Get` and `Invoke` operations. -1. Reference the [code for implementing the operations for the sample digital twin provider interface](../../../samples/tutorial/provider/src/provider_impl.rs). +1. Refer to the [code for implementing the operations for the sample digital twin provider interface](../../../samples/tutorial/provider/src/provider_impl.rs). -1. There is an import statement for the Rust in-vehicle digital twin model that you have previously constructed in the [Tutorial: Create an In-Vehicle Model with DTDL](../in_vehicle_model/README.md#3-translating-dtdl-to-code): +1. There is an import statement for the Rust in-vehicle digital twin model that you have previously constructed in the [Tutorial: Create an In-Vehicle Digital Twin Model with DTDL](../in_vehicle_model/README.md#3-translating-dtdl-to-code): -```rust -use digital_twin_model::sdv_v1 as sdv; -``` + ```rust + use digital_twin_model::sdv_v1 as sdv; + ``` 1. The implementation of the `Get` operation references the signals *is air conditioning active* and *ambient air temperature*: -```rust - /// Get implementation. - /// - /// # Arguments - /// * `request` - Get request. - async fn get(&self, request: Request) -> Result, Status> {..} -``` + ```rust + /// Get operation. + /// + /// # Arguments + /// * `request` - Get request. + async fn get(&self, request: Request) -> Result, Status> {..} + ``` 1. The implementation of the `Invoke` operation references the command *show notification*. -```rust -/// Invoke implementation. -/// -/// # Arguments -/// * `request` - Invoke request. -async fn invoke( - &self, - request: Request, -) -> Result, Status> {..} -``` + ```rust + /// Invoke operation. + /// + /// # Arguments + /// * `request` - Invoke request. + async fn invoke( + &self, + request: Request, + ) -> Result, Status> {..} + ``` ## 2. Register Digital Twin Provider with the In-Vehicle Digital Twin Service @@ -120,66 +121,36 @@ You will need to register your digital twin provider with the [In-Vehicle Digita The following lists out the flow for registering a digital twin provider in the programming language of your choice: -1. Reference the interface of the [In-Vehicle Digital Twin Service](../../../interfaces/invehicle_digital_twin/v1/invehicle_digital_twin.proto) which is defined as a protobuf file. +1. Refer to the interface of the [In-Vehicle Digital Twin Service](../../../interfaces/invehicle_digital_twin/v1/invehicle_digital_twin.proto) which is defined as a protobuf file. 1. In the code for your digital twin provider, you will need to import an `In-Vehicle Digital Twin Service` gRPC client. -1. Using the `In-Vehicle Digital Twin Service` gRPC client, you will need to define how to register your in-vehicle signals and commands with the In-Vehicle Digital Twin Service. This involves calling the `Register` gRPC method with the gRPC client. +1. Using the `In-Vehicle Digital Twin Service` gRPC client, you will need to define how to register your in-vehicle capabilities with the In-Vehicle Digital Twin Service. This involves calling the `Register` gRPC method with the gRPC client. Please see the sequence diagram for [Register](../../design/README.md#register) for more details. + +1. For each in-vehicle capability you register, you can refer to the in-vehicle capability with the [code for your in-vehicle digital twin model](../in_vehicle_model/README.md#3-translating-dtdl-to-code). ### 2.1 Rust Sample Registration of a Digital Twin Provider This section uses the [sample digital twin provider interface](#sample-digital-twin-provider-interface), and covers a *sample* Rust implementation of a provider registering the signals *ambient air temperature* and *is air conditioning active* and the command *show notification* -1. Reference the [main.rs file of the sample digital twin provider](../../../samples/tutorial/provider/src/main.rs). The main.rs file outlines the behavior of the signals in your digital twin provider sample. This includes a vehicle simulator that can emulate changes in its signals. These changes are then published to any digital twin consumers that have subscribed to your digital twin provider. +1. Refer to the [main.rs file of the sample digital twin provider](../../../samples/tutorial/provider/src/main.rs). 1. One function of particular interest in the [main.rs](../../../samples/tutorial/provider/src/main.rs) file is the `register_entities` function. -```rust -/// Register the entities endpoints. -/// -/// # Arguments -/// * `invehicle_digital_twin_uri` - The In-Vehicle Digital Twin URI. -/// * `provider_uri` - The provider's URI. -async fn register_entities( - invehicle_digital_twin_uri: &str, - provider_uri: &str, -) -> Result<(), Status> { .. } -``` + ```rust + /// Register the entities endpoints. + /// + /// # Arguments + /// * `invehicle_digital_twin_uri` - The In-Vehicle Digital Twin URI. + /// * `provider_uri` - The provider's URI. + async fn register_entities( + invehicle_digital_twin_uri: &str, + provider_uri: &str, + ) -> Result<(), Status> { .. } + ``` The `register_entities` function in this Rust sample digital twin provider shows the process of registering with the In-Vehicle Digital Twin Service. -#### Run the Sample Digital Twin Provider - -1. The best way to run the demo is by using three windows: one running the In-Vehicle Digital Twin, one running the Digital Twin Provider and one running the Digital Twin Consumer. Orientate the three windows so that they are lined up in a column. The top window can be used for the In-Vehicle Digital Twin. The middle window can be used for the Digital Twin Provider. The bottom window can be used for the Digital Twin Consumer. -In each window, change the current directory to the directory containing the build artifacts. Make sure that you replace "{repo-root-dir}" with the repository root directory on the machine where you are running the demo. - -1. cd {repo-root-dir}/target/debug -Create the three config files with the following contents, if they are not already there: - ----- consumer_settings.yaml ---- -`invehicle_digital_twin_uri: "http://0.0.0.0:5010"` - ----- invehicle_digital_twin_settings.yaml ---- -`invehicle_digital_twin_authority: "0.0.0.0:5010"` - ----- provider_settings.yaml ---- -`provider_authority: "0.0.0.0:4010"` -`invehicle_digital_twin_uri: "http://0.0.0.0:5010"` - -1. In the top window, run: - -`./invehicle-digital-twin` - -1. In the middle window, run: - -`./digital-twin-provider-tutorial` - -1. In the bottom window, run: - -`./digital-twin-consumer-tutorial` - -1. Use control-c in each of the windows when you wish to stop the demo. - ## 3. Add Managed Subscribe to Digital Twin Provider >[Managed Subscribe:](../../../samples/managed_subscribe/README.md#introduction) The managed subscribe sample shows how Ibeji can extend its functionality with modules to give providers and consumers more capabilities. This sample utilizes the 'Managed Subscribe' module to allow a consumer to get an MQTT subscription for the AmbientAirTemperature value of a vehicle at a specific frequency in milliseconds. The provider, signaled with the help of the module, will publish the temperature value at the requested frequency for each consumer on its own topic and once the consumer unsubscribes and disconnects it will stop publishing to that dynamically generated topic. @@ -202,7 +173,9 @@ If you decide to incorporate the `Managed Subscribe` module into your digital tw ### 3.1 Rust Sample Implementation of a Managed Subscribe Digital Twin Provider -Please refer to the [sample Rust code for the Managed Subscribe Sample provider](../../../samples/managed_subscribe/provider/src/) to see an example of how to integrate the Managed Subscribe module into a digital twin provider. +Please refer to the [sample Rust code for the Managed Subscribe Sample Provider](../../../samples/managed_subscribe/provider/src/) to see an example of how to integrate the Managed Subscribe module into a digital twin provider. This sample Rust code contains an *ambient air temperature* signal, and does not include the in-vehicle signal *is air conditioning active* and the command *show notification*. ## Next Steps + +- Learn how to create a digital twin consumer in [Tutorial: Create a Digital Twin Consumer](../consumer/README.md) diff --git a/samples/tutorial/provider/src/provider_impl.rs b/samples/tutorial/provider/src/provider_impl.rs index 7cbe2331..ea7686d8 100644 --- a/samples/tutorial/provider/src/provider_impl.rs +++ b/samples/tutorial/provider/src/provider_impl.rs @@ -15,7 +15,7 @@ pub struct ProviderImpl {} #[tonic::async_trait] impl DigitalTwinProviderTutorial for ProviderImpl { - /// Get implementation. + /// Get operation. /// /// # Arguments /// * `request` - Get request. @@ -34,7 +34,7 @@ impl DigitalTwinProviderTutorial for ProviderImpl { Ok(Response::new(get_response)) } - /// Invoke implementation. + /// Invoke operation. /// /// # Arguments /// * `request` - Invoke request.