Skip to content

Commit 7a4a435

Browse files
authored
Merge pull request #120823 from alexkarcher-msft/TSI-TWINS
Twins to TSI Tutorial
2 parents a2d284f + 168bc51 commit 7a4a435

File tree

9 files changed

+236
-0
lines changed

9 files changed

+236
-0
lines changed

articles/digital-twins/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@
7676
href: how-to-manage-routes.md
7777
- name: Integrate with Azure Maps
7878
href: how-to-integrate-maps.md
79+
- name: Integrate with Azure Time Series Insights
80+
href: how-to-integrate-time-series-insights.md
7981
- name: Troubleshoot
8082
items:
8183
- name: Known issues
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
---
2+
# Mandatory fields.
3+
title: Integrate with Time Series Insights
4+
titleSuffix: Azure Digital Twins
5+
description: See how to set up event routes from Azure Digital Twins to Azure Time Series Insights.
6+
author: alexkarcher-msft
7+
ms.author: alkarche # Microsoft employees only
8+
ms.date: 7/14/2020
9+
ms.topic: how-to
10+
ms.service: digital-twins
11+
12+
# Optional fields. Don't forget to remove # if you need a field.
13+
# ms.custom: can-be-multiple-comma-separated
14+
# ms.reviewer: MSFT-alias-of-reviewer
15+
# manager: MSFT-alias-of-manager-or-PM-counterpart
16+
---
17+
18+
# Integrate Digital Twins with Azure Time Series Insights
19+
20+
In this reference, you will learn how to integrate Azure Digital Twins with [Azure Time Series Insights (TSI)](../time-series-insights/overview-what-is-tsi.md). This solution will allow you to gather and analyze historical data about your IoT solution. Azure Digital Twins is a great fit for feeding data into Time Series Insights, as it allows you to correlate multiple data streams and standardize your information before sending it to Time Series Insights.
21+
22+
## Solution architecture
23+
24+
You will be attaching Time Series insights to Azure Digital Twins through the path below.
25+
26+
:::row:::
27+
:::column:::
28+
:::image type="content" source="media/how-to-integrate-time-series-insights/diagram-simple.png" alt-text="A view of Azure services in an end-to-end scenario, highlighting Time Series Insights" lightbox="media/how-to-integrate-time-series-insights/diagram-simple.png":::
29+
:::column-end:::
30+
:::column:::
31+
:::column-end:::
32+
:::row-end:::
33+
34+
## Prerequisites
35+
36+
* You need an Azure Digital Twins instance which you can update twin information a few times in order to see that data tracked in Time Series Insights.
37+
* If you do not have one, follow the Azure Digital Twins [Tutorial: Connect an end-to-end solution](./tutorial-end-to-end.md) to set up an Azure Digital Twins instance and a virtual IoT device to generate twin changes.
38+
39+
## Create a route and filter to twin update notifications
40+
41+
Azure Digital Twins instances can emit [twin update events](how-to-interpret-event-data.md) whenever a twin's state is updated. You will be creating a route that will direct these update events to an event hub for further processing.
42+
43+
The Azure Digital Twins [*Tutorial: Connect an end-to-end solution*](./tutorial-end-to-end.md) walks through a scenario where a thermometer is used to update a temperature attribute attached to a room's twin. This pattern uses the twin updates, rather than forwarding telemetry from an IoT device, which gives you the flexibility to change the underlying data source without needing to update your Time Series Insights logic.
44+
45+
1. Create an event hub namespace, which will receive events from your Azure Digital Twins instance. You can either use the Azure CLI instructions below, or use the Azure portal: [*Quickstart: Create an event hub using Azure portal*](../event-hubs/event-hubs-create.md).
46+
47+
```azurecli-interactive
48+
# Create an Event Hubs namespace. Specify a name for the Event Hubs namespace.
49+
az eventhubs namespace create --name <Event Hubs namespace> --resource-group <resource group name> -l <region, for example: East US>
50+
```
51+
52+
2. Create an event hub.
53+
54+
```azurecli-interactive
55+
# Create an event hub to receive twin change events. Specify a name for the event hub.
56+
az eventhubs eventhub create --name <event hub name> --resource-group <resource group name> --namespace-name <Event Hubs namespace>
57+
```
58+
59+
3. Create an [authorization rule](https://docs.microsoft.com/cli/azure/eventhubs/eventhub/authorization-rule?view=azure-cli-latest#az-eventhubs-eventhub-authorization-rule-create) with send and receive permissions.
60+
61+
```azurecli-interactive
62+
# Create an authorization rule. Specify a name for the rule.
63+
az eventhubs eventhub authorization-rule create --rights Listen Send --resource-group <resource group name> --namespace-name <Event Hubs namespace> --eventhub-name <twins event hub name> --name <twins auth rule>
64+
```
65+
66+
4. Create an endpoint to link your event grid topic to Azure Digital Twins.
67+
68+
```azurecli
69+
az dt endpoint create eventhub --endpoint-name <Event-Hub-endpoint-name> --eventhub-resource-group <resource group name> --eventhub-namespace <Event Hubs namespace> --eventhub <twins event hub name> --eventhub-policy <twins auth rule> -n <your-Azure-Digital-Twins-instance-name>
70+
```
71+
72+
5. Create a route in Azure Digital Twins to send twin update events to your endpoint. The filter in this route will only allow twin update messages to be passed to your endpoint.
73+
74+
```azurecli
75+
az dt route create -n <your-Azure-Digital-Twins-instance-name> --endpoint-name <Event-Hub-endpoint-name> --route-name <my_route> --filter "type = 'Microsoft.DigitalTwins.Twin.Update'"
76+
```
77+
78+
## Create an Azure function
79+
80+
Next, you're going to create an Event Hubs-triggered function inside a new function app, your function app from the [end-to-end tutorial](./tutorial-end-to-end.md). This function will convert those updates from their original form as JSON patch documents to JSON objects containing only updated and added values from your twins.
81+
82+
For more information about using Event Hubs with Azure functions, see [*Azure Event Hubs trigger for Azure Functions*](../azure-functions/functions-bindings-event-hubs-trigger.md).
83+
84+
Inside your published function app, replace the function code with the following code.
85+
86+
```C#
87+
using Microsoft.Azure.EventHubs;
88+
using Microsoft.Azure.WebJobs;
89+
using Microsoft.Extensions.Logging;
90+
using Newtonsoft.Json;
91+
using Newtonsoft.Json.Linq;
92+
using System.Threading.Tasks;
93+
using System.Text;
94+
using System.Collections.Generic;
95+
96+
namespace SampleFunctionsApp
97+
{
98+
public static class ProcessDTUpdatetoTSI
99+
{
100+
[FunctionName("ProcessDTUpdatetoTSI")]
101+
public static async Task Run(
102+
[EventHubTrigger("twins-fx-hub", Connection = "EventHubAppSetting-Twins")]EventData myEventHubMessage,
103+
[EventHub("alkarche-tsi-demo-hub", Connection = "EventHubAppSetting-TSI")]IAsyncCollector<string> outputEvents,
104+
ILogger log)
105+
{
106+
JObject message = (JObject)JsonConvert.DeserializeObject(Encoding.UTF8.GetString(myEventHubMessage.Body));
107+
log.LogInformation("Reading event:" + message.ToString());
108+
109+
// Read values that are replaced or added
110+
Dictionary<string, object> tsiUpdate = new Dictionary<string, object>();
111+
foreach (var operation in message["patch"]) {
112+
if (operation["op"].ToString() == "replace" || operation["op"].ToString() == "add")
113+
//Convert from JSON patch path to a flattened property for TSI
114+
//Example input: /Front/Temperature
115+
// output: Front.Temperature
116+
string path = operation["path"].ToString().Substring(1);
117+
path = path.Replace("/", ".");
118+
tsiUpdate.Add(path, operation["value"]);
119+
}
120+
//Send an update if updates exist
121+
if (tsiUpdate.Count>0){
122+
tsiUpdate.Add("$dtId", myEventHubMessage.Properties["cloudEvents:subject"]);
123+
await outputEvents.AddAsync(JsonConvert.SerializeObject(tsiUpdate));
124+
}
125+
}
126+
}
127+
}
128+
```
129+
130+
From here, the function will then send the JSON objects it creates to a second event hub, which you will connect to Time Series Insights.
131+
132+
## Send telemetry to an event hub
133+
134+
You will now create an second event hub and configure your function to stream its output to that event hub. This event hub will then be connected to Time Series Insights.
135+
136+
### Create an event hub
137+
138+
You can either use the Azure CLI instructions below, or use the Azure portal: [*Quickstart: Create an event hub using Azure portal*](../event-hubs/event-hubs-create.md).
139+
140+
1. Prepare your event hub namespace and resource group name from earlier
141+
142+
2. Create an event hub
143+
```azurecli-interactive
144+
# Create an event hub. Specify a name for the event hub.
145+
az eventhubs eventhub create --name <TSI event hub name> --resource-group <resource group name> --namespace-name <Event Hubs namespace>
146+
```
147+
3. Create an [authorization rule](https://docs.microsoft.com/cli/azure/eventhubs/eventhub/authorization-rule?view=azure-cli-latest#az-eventhubs-eventhub-authorization-rule-create) with send and receive permissions
148+
```azurecli-interactive
149+
# Create an authorization rule. Specify a name for the rule.
150+
az eventhubs eventhub authorization-rule create --rights Listen Send --resource-group <resource group name> --namespace-name <Event Hubs namespace> --eventhub-name <event hub name> --name <TSI auth rule>
151+
```
152+
153+
### Configure your function
154+
155+
You'll need to set one environment variable in your function app from earlier, containing your event hub connection string.
156+
157+
#### Set the Time Series Insights event hub connection string
158+
159+
1. Get the [event hub connection string](../event-hubs/event-hubs-get-connection-string.md) for the authorization rules you created above for the Time Series Insights hub:
160+
161+
```azurecli-interactive
162+
az eventhubs eventhub authorization-rule keys list --resource-group <resource group name> --namespace-name <Event Hubs namespace> --eventhub-name <twins event hub name> --name <twins auth rule>
163+
```
164+
165+
2. In your function app, create an app setting containing your connection string:
166+
167+
```azurecli-interactive
168+
az functionapp config appsettings set --settings "EventHubAppSetting-TSI=<your-event-hub-connection-string> -g <your-resource-group> -n <your-App-Service-(function-app)-name>"
169+
```
170+
171+
#### Set the Twins event hub connection string
172+
173+
1. Get the [event hub connection string](../event-hubs/event-hubs-get-connection-string.md) for the authorization rules you created above for the twins hub.
174+
175+
```azurecli-interactive
176+
az eventhubs eventhub authorization-rule keys list --resource-group <resource group name> --namespace-name <Event Hubs namespace> --eventhub-name <TSI event hub name> --name <TSI auth rule>
177+
```
178+
179+
2. In your function app, create an app setting containing your connection string:
180+
181+
```azurecli-interactive
182+
az functionapp config appsettings set --settings "EventHubAppSetting-Twins=<your-event-hub-connection-string> -g <your-resource-group> -n <your-App-Service-(function-app)-name>"
183+
```
184+
185+
## Create and connect a Time Series Insights instance
186+
187+
Next, you will set up a Time Series Insights instance to receive the data from your second event hub. For more details about this process see [*Tutorial: Set up an Azure Time Series Insights Gen2 PAYG environment*](../time-series-insights/tutorials-set-up-tsi-environment.md)
188+
189+
1. In the Azure portal, begin creating a Time Series Insights resource.
190+
1. Select the **PAYG(Preview)** pricing tier.
191+
2. You will need to choose a time series ID for this environment. Your time series ID can be up to three values that you will use to search for your data in Time Series Insights. For this tutorial, you can use **$dtId**. Read more about selecting an ID value in [*Best practices for choosing a Time Series ID*](https://docs.microsoft.com/azure/time-series-insights/how-to-select-tsid).
192+
193+
:::image type="content" source="media/how-to-integrate-time-series-insights/create-twin-id.png" alt-text="The creation portal UX for a Time Series Insights environment. The PAYG(Preview) pricing tier is selected and the time series ID property name is $dtId":::
194+
195+
2. Select **Next: Event Source** and select your Event Hubs information from above. You will also need to create a new Event Hubs consumer group.
196+
197+
:::image type="content" source="media/how-to-integrate-time-series-insights/event-source-twins.png" alt-text="The creation portal UX for a Time Series Insights environment event source. You are creating an event source with the event hub information from above. You are also creating a new consumer group.":::
198+
199+
## Begin sending IoT data to Azure Digital Twins
200+
201+
To begin sending data to Time Series Insights, you will need to start updating the digital twin properties with changing data values. Use the [az dt twin update](https://docs.microsoft.com/cli/azure/ext/azure-iot/dt/twin?view=azure-cli-latest#ext-azure-iot-az-dt-twin-update) command.
202+
203+
If you are using the end-to-end tutorial to assist with environment setup, you can begin sending simulated IoT data by running the `DeviceSimulator` project from the Azure Digital Twins [*Tutorial: Connect an end-to-end solution*](tutorial-end-to-end.md). The instructions are in the [*Configure and run the simulation*](tutorial-end-to-end.md#configure-and-run-the-simulation) section of the tutorial.
204+
205+
## Visualize your data in Time Series Insights
206+
207+
Now, data should be flowing into your Time Series Insights instance, ready to be analyzed. Follow the steps below to explore the data coming in.
208+
209+
1. Open your Time Series Insights instance in the Azure portal. Visit the Time Series Insights Explorer URL shown in the overview.
210+
211+
:::image type="content" source="media/how-to-integrate-time-series-insights/view-environment.png" alt-text="Click on the Time Series Insights explorer URL in the overview tab of your Time Series Insights environment":::
212+
213+
2. In the explorer, you will see your three twins shown on the left. Click on **thermostat67**, select **patch_value**, and click **add**.
214+
215+
:::image type="content" source="media/how-to-integrate-time-series-insights/add-data.png" alt-text="Click on **thermostat67**, select **temperature**, and click **add**":::
216+
217+
3. You should now be seeing the initial temperature readings from your thermostat, as shown below. That same temperature reading is updated for room21 and floor1, and you can visualize those data streams in tandem.
218+
219+
:::image type="content" source="media/how-to-integrate-time-series-insights/initial-data.png" alt-text="Initial temperature data is graphed in the TSI explorer. It is a line of random values between 68 and 85":::
220+
221+
4. If you allow the simulation to run for much longer, your visualization will look something like this:
222+
223+
:::image type="content" source="media/how-to-integrate-time-series-insights/day-data.png" alt-text="Temperature data for each twin is graphed in three parallel lines of different colors.":::
224+
225+
## Next steps
226+
227+
The digital twins are stored by default as a flat hierarchy in Time Series Insights, but they can be enriched with model information and a multi-level hierarchy for organization. To learn more about this process, read:
228+
229+
* [*Tutorial: Define and apply a model*](../time-series-insights/tutorials-set-up-tsi-environment.md#define-and-apply-a-model)
230+
231+
You can write custom logic to automatically provide this information using the model and graph data already stored in Azure Digital Twins. To read more about managing, upgrading, and retrieving information from the twins graph, see the following references:
232+
233+
* [*How-to: Manage a digital twin*](./how-to-manage-twin.md)
234+
* [*How-to: Query the twin graph*](./how-to-query-graph.md)
220 KB
Loading
488 KB
Loading
327 KB
Loading
340 KB
Loading
277 KB
Loading
242 KB
Loading
207 KB
Loading

0 commit comments

Comments
 (0)