Changes

update link names
Line 117: Line 117:  
====DPS X.509 attestation====  
 
====DPS X.509 attestation====  
 
<ul>
 
<ul>
<div> 1. The initial step generating certificates. The Microsoft guide for generating certificates can be found [https://learn.microsoft.com/en-us/azure/iot-dps/tutorial-custom-hsm-enrollment-group-x509?pivots=programming-language-ansi-c#create-an-x509-certificate-chain here] which explains each step of the process in detail.
+
<div> 1. The initial step generating certificates. Refer to the Microsoft guide, section [https://learn.microsoft.com/en-us/azure/iot-dps/tutorial-custom-hsm-enrollment-group-x509?pivots=programming-language-ansi-c#create-an-x509-certificate-chain "''Create an X.509 certificate chain''"] for in depth information that explains each step of the process in detail.
    
The required certificates and keys:
 
The required certificates and keys:
Line 124: Line 124:  
<li> '''Devices certificates''' </li>
 
<li> '''Devices certificates''' </li>
   −
2. After successfully generating the certificates return to the Azure portal page and navigate to your Azure IoT Hub Device Provisioning Service (DPS) page. From there proceed create an enrollment group. The Microsoft guide for creating enrollment groups can be found [https://learn.microsoft.com/en-us/azure/iot-dps/tutorial-custom-hsm-enrollment-group-x509?pivots=programming-language-ansi-c#create-an-enrollment-group here].
+
2. After successfully generating the certificates return to the Azure portal page and navigate to your Azure IoT Hub Device Provisioning Service (DPS) page. From there proceed create an enrollment group. Refer to the Microsoft guide, section [https://learn.microsoft.com/en-us/azure/iot-dps/tutorial-custom-hsm-enrollment-group-x509?pivots=programming-language-ansi-c#create-an-enrollment-group "''Create an enrollment group''"] for in depth information.
 
</div>
 
</div>
   −
4. The final step is to return to the device WebUI and navigate to '''Services -> Cloud Solutions -> Azure IoT Hub''' page to create a new configuration instance:
+
3. Return to the device WebUI and navigate to '''Services -> Cloud Solutions -> Azure IoT Hub''' page to create a new configuration instance:
   −
4.1 Set connection type as a '''Device Provisioning Service (DPS)''';
+
3.1 Set connection type as a '''Device Provisioning Service (DPS)''';
   −
4.2 Enter '''ID Scope''' of your DPS service page on Azure. This value can be retrieved from the DPS instance found on Azure Portal page or by following the earlier guide;
+
3.2 Enter '''ID Scope''' of your DPS service page on Azure. This value can be retrieved from the DPS instance found on Azure Portal page or by following the earlier guide;
   −
4.3 Specify the '''Registration ID'''. This is the subject common name (CN) of the device leaf certificate that was created using the earlier guide.
+
3.3 Specify the '''Registration ID'''. This is the subject common name (CN) of the device leaf certificate that was created using the earlier guide.
   −
4.4 Upload the certificate chain file and the private key file.  
+
3.4 Upload the certificate chain file and the private key file.  
    
With all the required values in place the configuration pop-up window should resemble the screenshot below:
 
With all the required values in place the configuration pop-up window should resemble the screenshot below:
Line 150: Line 150:  
[[File:Azure RutOSconf 13.png|border|class=tlt-border]]
 
[[File:Azure RutOSconf 13.png|border|class=tlt-border]]
   −
Inspecting the newly created enrollment group will reveal some keys. The primary key will be used to derive each individual device identity. This can be done using a simple script, which is available [https://learn.microsoft.com/en-us/azure/iot-dps/how-to-legacy-device-symm-key?tabs=linux&amp%3Bpivots=programming-language-ansi-c&pivots=programming-language-ansi-c#derive-a-device-key in this Microsoft guide]  
+
Inspecting the newly created enrollment group will reveal some keys. The primary key will be used to derive each individual device identity. This can be done using a script which is available on Microsoft DPS documentation [https://learn.microsoft.com/en-us/azure/iot-dps/how-to-legacy-device-symm-key?tabs=linux&amp%3Bpivots=programming-language-ansi-c&pivots=programming-language-ansi-c#derive-a-device-key here].
   −
In the script, you will notice a couple of important variables: '''KEY''' and '''REG_ID'''. In the KEY field, you must specify the primary key, which can be obtained from the newly created enrollment group.
+
The script contains a couple of variables: '''KEY''' and '''REG_ID'''. The KEY field shall contain the primary key which is obtained from the newly created enrollment group. The '''REG_ID''' field specifies the device identity name that will be created. Upon executing the script a shared access key will be created.
   −
[[File:Azure RutOSconf 14.1.png|border|class=tlt-border]]
+
[[File:Azure symm example 1.png|border|class=tlt-border]]
 
  −
The '''REG_ID''' field specifies the device identity name that will be created. Upon executing the script a shared access key will be created.
  −
 
  −
[[File:Azure_RutOSconf_15.png|border|class=tlt-border]]
      
Go back to the device WebUI '''Services -> Cloud Solutions -> Azure IoT Hub''' configuration page and add a new instance. In the configuration window select DPS connection type and Symmetric Key connection type.
 
Go back to the device WebUI '''Services -> Cloud Solutions -> Azure IoT Hub''' configuration page and add a new instance. In the configuration window select DPS connection type and Symmetric Key connection type.
    
<ul>
 
<ul>
<li> In the '''ID scope''' field, specify your Azure DPS service ID. This value can be retrieved from the DPS instance found on Azure Portal page or by following the earlier guides.</li>
+
<li> In the '''ID scope''' field specify your Azure DPS service ID. This value can be retrieved from the DPS instance found on Azure Portal page or by following the earlier guides from Microsoft.</li>
<li> In the '''Registration ID''' field enter the "REG_ID" value you specified in the script. For example, "wiki-newly-generated-device". </li>
+
<li> In the '''Registration ID''' field enter the "REG_ID" value that was specified in the earlier script.</li>
<li> In the '''Symmetric key''' field enter the "SharedAccessKey" obtained from the script execution output.</li>
+
<li> In the '''Symmetric key''' field enter the output value of the script that was used earlier].</li>
 
</ul>
 
</ul>
    
If you are following this guide your configuration window should look similar to the screenshot below.
 
If you are following this guide your configuration window should look similar to the screenshot below.
[[File:Azure_RutOSconf_16.png|border|class=tlt-border]]
+
 
 +
[[File:Azure symm example 2 modified.png|border|class=tlt-border]]
    
After a few moments the device should establish connection to the Azure server.
 
After a few moments the device should establish connection to the Azure server.
   −
Moreover, we can return to the IoT Hub services in the Azure portal and check the device list. There we will see that the DPS service has created a new device identity named the same as what we specified in the '''REG_ID''' field in the script earlier.
+
After returning to the IoT Hub services in the Azure portal page it can be observed that the DPS service has created a new device identity was named the same as what we specified in the '''REG_ID''' field in the script.
[[File:Azure_RutOSconf_18.png|border|class=tlt-border]]
+
 
 +
[[File:Azure symm example 3.png|border|class=tlt-border]]
    
</ul>
 
</ul>
    
==Direct methods configuration==
 
==Direct methods configuration==
A direct method refers to a process where an action is initiated from the Azure IoT Hub to a specific device identity. The receiving device executes certain actions and returns a response back to the Azure portal. Let's see how this works on our devices.
     −
By default, all configuration instances will have this option disabled. To enable it, navigate on the router WebUI to '''Services -> Cloud Solutions -> Azure IoT Hub''' and press the edit button on the specific instance. There, you will see the "'''Enable Direct Methods'''" button, which you need to press.
+
IoT Hub direct methods enable you to remotely invoke calls on devices from the cloud. Direct methods follow a request-response pattern and are meant for communications that require immediate confirmation of their result.
 +
 
 +
By default, all configuration instances will have this option disabled. To enable it, navigate on the router WebUI to '''Services -> Cloud Solutions -> Azure IoT Hub''' and press the edit button on the specific instance. Afterwards the "'''Enable Direct Methods'''" option needs to be enabled.
    
[[File:Azure RutOSconf 19.png|border|class=tlt-border]]
 
[[File:Azure RutOSconf 19.png|border|class=tlt-border]]
   −
For testing and demonstration purposes, we will use the Azure IoT Explorer application. The Azure IoT Explorer is a graphical tool for interacting with devices connected to your IoT hub. If you are not familiar with it, you can follow [https://learn.microsoft.com/en-us/azure/iot/howto-use-iot-explorer this Microsoft installation and usage guide]  
+
For testing and demonstration purposes we will use the Azure IoT Explorer application. The Azure IoT Explorer is a graphical tool for interacting with devices connected to your IoT hub. To learn more about this tool you can follow the Microsoft documentation [https://learn.microsoft.com/en-us/azure/iot/howto-use-iot-explorer here].
   −
After enabling the Direct Method feature, go to Azure IoT Explorer, select the appropriate device identity, and navigate to the Direct Methods tab. All our RUT devices support the '''api_call''' direct method, which exposes the API interface to be used from the Azure side. In this example, we will make a simple GET request to retrieve the I/O status of the device. Full documentation of Teltonika devices API can be found [https://developers.teltonika-networks.com/ here]  
+
After enabling the Direct Method feature go to Azure IoT Explorer, select the appropriate device identity and navigate to the Direct Methods tab. All our devices support the '''api_call''' direct method which exposes the API interface to be used from the Azure side. In this example we will make a simple GET request to retrieve the I/O status of the device. Full documentation of Teltonika devices API can be found [https://developers.teltonika-networks.com/ here] .
   −
In the Azure IoT Explorer Direct Method tab, you will see a Payload field. It expects to receive JSON-formatted information.
+
The Azure IoT Explorer Direct Method tab will have a Payload field. In this field the '''api_call''' method expects JSON formatted data.
    
[[File:Azure RutOSconf 20.png|border|class=tlt-border]]
 
[[File:Azure RutOSconf 20.png|border|class=tlt-border]]
   −
The API call expects at least two parameters. The first one is called "method," which needs to have an integer value between zero and three, corresponding to the API method type - either "get", "out", "post", or "delete". The second parameter is "endpoint," which expects a string value of the API endpoint. In this case, we will call the /io/status endpoint.
+
The API call expects at least two parameters. The first one is called '''"method"''' which needs to have an integer value between zero and three, corresponding to the API method type - either GET, POST, PUT or DELETE. The second parameter is '''"endpoint"''' which expects a string value of the API endpoint. In this case, we will call the '''/io/status''' endpoint.
    
[[File:Azure RutOSconf 22.1.png|border|class=tlt-border]]
 
[[File:Azure RutOSconf 22.1.png|border|class=tlt-border]]
   −
After pressing the "'''Invoke Method'''" button, you will see the response from the device.
+
After pressing the "'''Invoke Method'''" button the response from the device will be visible which is a standard API response specified in our [https://developers.teltonika-networks.com/fundamentals/#request-and-response-structures documentation].
    
[[File:Azure RutOSconf 21.png|border|class=tlt-border]]
 
[[File:Azure RutOSconf 21.png|border|class=tlt-border]]
   −
The response you see is a standard response as specified in our API documentation.
+
To determine the appropriate payload and method to use we provide an additional file currently called '''teltonikaGenericDevice.json'''. This file is written in '''Digital Twin Definition Language (DTDL)'''. To learn more about DTDLs and Digital Twins read about it in Microsoft documentation [https://learn.microsoft.com/en-us/azure/digital-twins/concepts-models here].
   −
To determine the appropriate payload and method to use, we provide an additional file currently called "teltonikaGenericDevice.json." This file is written in '''Digital Twin Definition Language (DTDL)'''. It is similar to SNMP MIB documents by design, as it also describes device capabilities. In this file, you can see that it supports the api_call method, which accepts three values. The request body is optional, as some methods, such as the GET method, may not require it. JSON files can be downloaded by pressing [[Media:Teltonika-dtmi-docs.zip|here]]
+
In this file you can see that it supports the api_call method, which accepts three values. The request body is optional, as some methods, such as the GET method, may not require it. JSON files can be downloaded [[Media:Teltonika-dtmi-docs.zip|here]].
   −
The IoT Explorer can be configured to parse DTDL files and display them to the user. Let's configure it.
+
The IoT Explorer can be configured to parse DTDL files and display them to the user for easier work:
    
===IoT plug and Play configuration===
 
===IoT plug and Play configuration===
   −
To configure it, navigate to the "'''IoT Plug and Play components'''" tab on the IoT Explorer. Initially, there may be an error stating that it did not retrieve an interface model. To resolve this, click on the "'''Configure'''" button. You will then be able to add a local folder by pressing the "'''Add'''" button.
+
Navigate to the "'''IoT Plug and Play components'''" tab on the IoT Explorer. Initially there may be an error stating that it did not retrieve an interface model. To resolve this click on the "'''Configure'''" button. In this guide a local folder will be added by pressing the "'''Add'''" button.
    
[[File:Azure RutOSconf 23.png|border|class=tlt-border]]
 
[[File:Azure RutOSconf 23.png|border|class=tlt-border]]
   −
In the specified folder, you must have provided '''".json"''' files. After adding the local folder, press the '''"Save"''' button.
+
The specified directory must have the DTDL '''".json"''' files. After adding the local folder press the '''"Save"''' button.
   −
After saving these settings, return to the device identity Plug and Play tab. Now, you will be able to see two components with model IDs named "'''genericDevice'''" and "'''deviceInformation'''". The generic device will display the DTDL interface description.
+
Return to the device identity Plug and Play tab. Now you will be able to see two components with model IDs named "'''genericDevice'''" and "'''deviceInformation'''". The generic device will display the DTDL interface description.
    
[[File:Azure RutOSconf 24.png|border|class=tlt-border]]
 
[[File:Azure RutOSconf 24.png|border|class=tlt-border]]
   −
In the upper toolbar, select the "'''Commands'''" tab. There you will see that IoT Explorer has parsed the API call method and created three new fields. Now, we can try to call the same I/O status method that we called previously.  
+
In the upper toolbar select the "'''Commands'''" tab. There you will see that IoT Explorer has parsed the API call method and created three new fields. Now we can try to call the same I/O status method that we called previously.  
    
[[File:Azure RutOSconf 25.png|border|class=tlt-border]]
 
[[File:Azure RutOSconf 25.png|border|class=tlt-border]]
   −
We can see that some information was correctly retrieved from the router, and everything works without any issues. This method makes it much easier to work with API calls from the Azure side.
+
We can see that some information was correctly retrieved from the router. This workflow makes it easier to work with API calls from the Azure side.
    
==Sending data with "Data to Server" feature==
 
==Sending data with "Data to Server" feature==
The Data to Server feature allows you to set up data senders that collect data from various sources and periodically send it to remote servers. We can configure this feature to send data from the router to Azure.
     −
===Data to server configurations===
+
The Data to Server service allows you to set up collections that collect data from various sources and periodically sends it to various servers. We can configure this feature to send data from the device to Azure IoT Hub.
   −
To configure the "'''Data to Server'''" service on RUT devices, please navigate to '''Services -> Data to Server''' on the WebUI and add a new instance. In the pop-up window, you will need to perform the following steps:
+
===Data to Server configuration===
   −
<ul>
+
To configure the '''Data to Server''' service on Teltonika devices navigate to '''Services -> Data to Server''' on the WebUI. This guide will cover only the collection output part. To learn more about Data to Server features you can find the dedicated guide on our Wiki. From this point it is assumed the collection is properly set up with correct inputs.
<li> In the "'''Name'''" field, specify any name that you want; </li>
  −
<li> In the "'''Type'''" field, we will leave "Base" option for this example; </li>
  −
<li> In the "'''Format type'''" field, choose JSON; </li>
  −
<li> Press "'''Next: Collection edit'''"" button; </li>
  −
 
  −
[[File:Azure RutOSconf 26.png|border|class=tlt-border]]
  −
 
  −
<li> In the collection configuration window, leave "'''Format type'''" as '''JSON''', set the period to your preferred value, and press the "'''Next: Server configuration'''" button.;</li>
  −
 
  −
[[File:Azure RutOSconf 27.png|border|class=tlt-border]]
      
<li> In the server configuration configuration window, choose "'''Type'''" as a "'''Azure IoT Hub'''" option; </li>
 
<li> In the server configuration configuration window, choose "'''Type'''" as a "'''Azure IoT Hub'''" option; </li>
   −
In the "Configuration type" field, you can choose whether to use an existing Azure IoT Hub configuration or configure a new, unique Azure IoT Hub configuration. In this example, we will stick with the previously created, existing Azure IoT Hub instance configuration.
+
In the "Configuration type" field you can choose whether to use an existing Azure IoT Hub configuration or configure a new and unique Azure IoT Hub configuration. In this example we will stick with the previously created Azure IoT Hub instance configuration.
   −
If you choose to create a new unique Azure IoT Hub configuration on the Data to Server instance, you will be able to choose connection types, upload certificates, connection strings, and more, just as we did previously on the '''Cloud Solutions -> Azure IoT Hub''' WebUI page.
+
If you choose to create a new unique Azure IoT Hub configuration on the Data to Server instance you will need to input all the options that were discussed earlier in this guide.
    
<li> Select your preferred Azure IoT Hub instance; </li>
 
<li> Select your preferred Azure IoT Hub instance; </li>
 
<li> Press "'''Save & Apply'''" button. </li>
 
<li> Press "'''Save & Apply'''" button. </li>
   −
If you are following this guide, after saving, your configurations should resemble the screenshot below.
+
If you are following this guide your configuration should resemble something similar to the screenshot below.
    
[[File:Azure RutOSconf 28.png|border|class=tlt-border]]
 
[[File:Azure RutOSconf 28.png|border|class=tlt-border]]
Line 260: Line 248:  
====Checking if data reaches IoT Hub on Azure====
 
====Checking if data reaches IoT Hub on Azure====
   −
To determine whether data successfully reaches Azure IoT Hub, select your device and navigate to the "Telemetry" tab on the Azure IoT Explorer. Ensure that "'''Use built-in event hub'''" option is enabled and press the "'''Start'''" button.
+
To determine whether data successfully reaches Azure IoT Hub select your device and navigate to the "Telemetry" tab on the Azure IoT Explorer. Ensure that "'''Use built-in event hub'''" option is enabled and press the "'''Start'''" button. After some time you should see that data was sent from the device to the Azure IoT Hub.
    
[[File:Azure RutOSconf 29.png|border|class=tlt-border]]
 
[[File:Azure RutOSconf 29.png|border|class=tlt-border]]
   −
After a few seconds, you should see that data was sent from the device to the Azure IoT Hub. If you see a similar response, it indicates that everything was configured correctly.
+
==Example use cases==
 +
 
 +
This section shows some practical examples that combines most of the features that are discussed earlier.
 +
 
 +
===Dynamically monitoring Modbus data===
 +
 
 +
This example shows how to monitor and dynamically control Modbus data purely from the Azure cloud. We will set up a simple Modbus TCP server and client with Data to Server which will forward all the incoming Modbus data to Azure IoT Hub. In the end, using Direct Methods we will showcase how Modbus TCP client can collect and report different data from the cloud.
 +
 
 +
[[File:Azure_drawio_diagram.png|border|class=tlt-border]]
 +
 
 +
For this we will be using the following services:
 +
 
 +
*Azure IoT Hub;
 +
*Data to Server;
 +
*Modbus TCP Server;
 +
*Modbus TCP Client;
 +
*An Azure IoT Hub account.
 +
 
 +
In this example the Azure IoT Hub WebUI service configuration will not be covered since all the necessary information can be found in the earlier sections.
 +
 
 +
====Modbus TCP Server====
 +
 
 +
Enable the service in '''Services -> Modbus -> Modbus TCP Server''' with '''Enable''' option. For more information about this service you can find it on our Modbus Wiki [https://wiki.teltonika-networks.com/view/RUTX11_Modbus#Modbus_TCP_Server TCP server section]
 +
 
 +
====Modbus TCP Client====
 +
 
 +
Go to '''Services -> Modbus -> Modbus TCP Client''' page and create a new instance. This part will assume most of the configuration for this page is already made. For more information about this service you can find it on our Modbus Wiki [https://wiki.teltonika-networks.com/view/RUTX11_Modbus#Modbus_TCP_Client TCP client section].
 +
 
 +
For this use case a single Modbus request configuration will be created to request the current device timestamp:
 +
 
 +
*Data type: '''32bit UINT, Byte order 1,2,3,4'''
 +
*Function: '''Read holding registers (3)'''
 +
*First register number: '''2'''
 +
*Register counter/Values: '''2'''
 +
 
 +
For device specific Modbus register information refer to the appropriate Wiki documentation.
 +
 
 +
====Data to Server====
 +
 
 +
1. Go to '''Services -> Data to Server''' page and create a new collection instance.
 +
 
 +
1.1. Select the input '''Type''' to '''Modbus''';
 +
 
 +
1.2. Change the '''Format type''' to '''Custom''';
 +
 
 +
1.3. In the '''Format string''' we will enter the following data: '''{"Date (Linux timestamp)": %timestamp%, "MODBUS server ID": "%server_id%", "MODBUS server name" : "%server_name%", "Request name": "%name%", "Start register": "%addr%", "Register data (JSON object)": %data%, "Raw data": "%raw_data%"}'''. This will form requests about Modbus data including the register values;
 +
 
 +
1.4. In the '''Collection configuration''' page select the '''Format type''' to custom;
 +
 
 +
1.5. Change the '''Format string''' to '''{ "input1": %input1% }'''. Make sure to change the '''%input1%''' value to your specific input name. Note that this value is not enclosed in braces. This is intentional since the braces are present in the Modbus input '''Format string''' field;
 +
 
 +
1.6. In the '''Server configuration''' select the '''Type''' to '''Azure IoT Hub''' and configure the Azure configuration instance in accordance to your needs.
 +
 
 +
====Monitoring and controlling incoming data====
 +
 
 +
Inspecting the incoming data to the Azure IoT Hub using Azure IoT Explorer reveals that Modbus data is being received successfully.
 +
 
 +
[[File:Azure modbus example 1 modified 1.png|border|class=tlt-border]]
 +
 
 +
In order to change the type of Modbus data sent to the Azure IoT Hub without going to the device WebUI the '''Direct Methods''' feature can be utilized. Using Azure IoT Explorer go to the device identity that was configured on the Teltonika device and select '''Direct method''' tab.
 +
 
 +
Using the '''api_call''' direct method create API requests that update the Modbus TCP Client request configurations (API reference for Modbus services can be found [https://developers.teltonika-networks.com/reference/7.6.10/v1/modbus/ here]. In this example the request configuration will be changed to collect '''Mobile signal strength'''. To do this using only API we will need to resolve the Modbus TCP client instance ID then the request ID of the instance which currently collects the temperature data. Using both of the IDs we will form the last API PUT request to update the register values:
 +
 
 +
2.1. Invoke '''/modbus/client/tcp/config''' GET request and inspect the output on IoT Explorer. The '''"data"''' array will contain JSON objects of every configured client instance. The '''"id"''' value will be used when forming the next API request;
 +
 
 +
[[File:Azure modbus example 2.png|border|class=tlt-border]]
 +
 
 +
2.2. Invoke '''/modbus/client/tcp/{id}/requests/config''' GET request and replace the '''{id}''' with the '''"id"''' value from the previous step. Inspecting the output will reveal the '''"data"''' array which contain JSON objects of every configured request. The '''"id"''' value of the request that collects temperature data will be used when forming the next API request;
 +
 
 +
[[File:Azure modbus example 3.png|border|class=tlt-border]]
 +
 
 +
2.3. Invoke '''/modbus/client/tcp/{id}/requests/config/{request_id}''' PUT request and replace the '''{id}''' with the '''"id"''' value from the 2.1. step and replace the '''{request_id}''' with the '''"id"''' value from the 2.2. step. In the '''request_body''' field add values to change the first register and data type values: '''{"data":{"first_reg":"4","data_type":"32bit_int1234"}}''' which corresponds to mobile signal strength register (other parameters such as number of registers stay the same since the timestamp register count is the same too).
 +
 
 +
[[File:Azure modbus example 4.png|border|class=tlt-border]]
 +
 
 +
2.4. Observe the incoming telemetry data. At this point the register data shall contain the mobile signal strength values.
 +
 
 +
[[File:Azure modbus example 5.png|border|class=tlt-border]]
    +
This concludes the Azure IoT Hub guide. Using Direct Methods with device API is a powerful tool that unlocks new capabilities of device monitoring and control from the cloud. Nearly all features available via device WebUI are also available using API.
    +
'''
 
==External links==
 
==External links==