How to generate custom telemetry string data for a simulated device sensor in IoT Central and in ADT

GuidoL 310 Reputation points
2023-05-11T11:05:10.5266667+00:00

Hi,

i configured some devices in Iot Central from device templates in Iot Central to simulate rfid physical devices in smart library.

An example:

[
    {
        "@id": "dtmi:digitaltwins:org:archive:download:rfidsmartlibrary:RfidSmartLibraryowl:LibraryItemGateCheckSensor;1",
        "@type": "Interface",
        "contents": [
            {
                "@id": "dtmi:digitaltwins:org:archive:download:rfidsmartlibrary:RfidSmartLibraryowl:LibraryItemGateCheckSensor:ItemId;1",
                "@type": [
                    "Telemetry",
                    "StringValue"
                ],
                "displayName": {
                    "en": "ItemId"
                },
                "name": "ItemId",
                "schema": "string"
            },
            {
                "@id": "dtmi:digitaltwins:org:archive:download:rfidsmartlibrary:RfidSmartLibraryowl:LibraryItemGateCheckSensor:Description;1",
                "@type": [
                    "Telemetry",
                    "StringValue"
                ],
                "displayName": {
                    "en": "Description"
                },
                "name": "Description",
                "schema": "string"
            },
            {
                "@id": "dtmi:digitaltwins:org:archive:download:rfidsmartlibrary:RfidSmartLibraryowl:LibraryItemGateCheckSensor:Location;1",
                "@type": [
                    "Telemetry",
                    "StringValue"
                ],
                "displayName": {
                    "en": "Location"
                },
                "name": "Location",
                "schema": "string"
            },
            {
                "@id": "dtmi:digitaltwins:org:archive:download:rfidsmartlibrary:RfidSmartLibraryowl:LibraryItemGateCheckSensor:DateTimeGateEvent;1",
                "@type": [
                    "Telemetry",
                    "DateTimeValue"
                ],
                "displayName": {
                    "en": "DateTimeGateEvent"
                },
                "name": "DateTimeGateEvent",
                "schema": "dateTime"
            }
        ],
        "displayName": {
            "en": "LibraryItemGateCheckSensor"
        },
        "@context": [
            "dtmi:iotcentral:context;2",
            "dtmi:dtdl:context;2"
        ]
    }
]

So using IoT Central device simulation i have the following raw data:

{
    "_eventcreationtime": "2023-05-08T09:42:28.953Z",
    "ItemId": "Tempore eaque et occaecati sit.",
    "Description": "Incidunt ut doloremque quisquam.",
    "Location": "Corrupti consectetur perspiciatis a et quas.",
    "DateTimeGateEvent": "2023-05-10T21:10:48.803Z",
    "_eventtype": "Telemetry",
    "_timestamp": "2023-05-08T09:42:29.007Z"
}

Randomly generated data clearly is not meaningful: for analysis and statistics of library services i need to have data more similar to real ones; in my case data telemetry are not numeric: they have all string or complex schema and concern a limit library archive: think library rfid assets and rfid user cards .

So i ask if there is a way to simulate telemetry starting from a default database, even using Azure Function.

Simulate telemetry could be starting from an IoT Central device to the related rfid device sensor twin in Azure Digital Twins or in the other direction (from Azure Digital Twins to IoT Central device).

My goal is to update related sensor in Azure Digital Twins using these data and then make a data explorer in IoT (to use queries to analyze historical trends and visualize telemetry from my library devices over custom time periods).

So far I haven't been able to find a way to to accomplish what I indicated; i think it's not convenient to define a device templates that have lots of "enum" schema to specify book descriptions or other library fields or to make use of properties in the IoT device and update them using Device properties panel.

Any suggestions and code examples are welcome.

Thanks in advance.

Guido

Azure Digital Twins
Azure Digital Twins
An Azure platform that is used to create digital representations of real-world things, places, business processes, and people.
219 questions
Azure IoT Central
Azure IoT Central
An Azure hosted internet of things (IoT) application platform.
342 questions
0 comments No comments
{count} votes

Accepted answer
  1. LeelaRajeshSayana-MSFT 13,456 Reputation points
    2023-05-11T23:03:30.2633333+00:00

    Hi @GuidoL Greetings! You can certainly simulate the Data using a C# SDK. Perhaps one of the easiest ways to simulate this scenario is by creating a List of strings that you anticipate the Telemetry data would hold and iterate the lists to pick a random value before passing the telemetry.

    I have used the template you provided above and created a Device on my IoT Central app. I have used the Github repository and modified the TemperatureControllerSample.cs file under the directory \azure-iot-sdk-csharp-main\iothub\device\samples\solutions\PnpDeviceSamples\TemperatureController to the following to simulate the data.

    // Copyright (c) Microsoft. All rights reserved.
    // Licensed under the MIT license. See LICENSE file in the project root for full license information.
    
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.Devices.Shared;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    using PnpHelpers;
    
    namespace Microsoft.Azure.Devices.Client.Samples
    {
    
        public class TemperatureControllerSample
        {
            // The default reported "value" and "av" for each "Thermostat" component on the client initial startup.
            // See https://docs.microsoft.com/azure/iot-develop/concepts-convention#writable-properties for more details in acknowledgment responses.        
            
    
            private readonly DeviceClient _deviceClient;
            private readonly ILogger _logger;
    
            //private string ItemID = "Item";
            
    
            List<string> ItemID = new List<string>() { "Item1", "Item2", "Item3", "Item4" };
            List<string> Description = new List<string>() { "Des 1", "Des 2", "Des 3", "Des 4", "Des 5", "Des 6", "Des 7" };
            List<string> Location = new List<string>() { "Downingtown", "Midtown", "Redmond", "Hyderabad" };
            Random randNum = new Random();
    
            public TemperatureControllerSample(DeviceClient deviceClient, ILogger logger)
            {
                _deviceClient = deviceClient ?? throw new ArgumentNullException(nameof(deviceClient));
                _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            }
    
            public async Task PerformOperationsAsync(CancellationToken cancellationToken)
            {                   
                while (!cancellationToken.IsCancellationRequested)
                {                
                    await SendTemperatureAsync(cancellationToken);                
                    Thread.Sleep(30000);                                
                    await Task.Delay(5 * 1000, cancellationToken);
                }
            }
    
            private async Task SendTemperatureAsync(CancellationToken cancellationToken)
            {
                string telemetryName = "ItemId";
                int index = randNum.Next(ItemID.Count);
                using Message msg = PnpConvention.CreateMessage(telemetryName, ItemID[index]);
                await _deviceClient.SendEventAsync(msg, cancellationToken);
                _logger.LogDebug($"Telemetry: Sent - {{ \"{telemetryName}\": {ItemID[index]} }}.");
                
                
                telemetryName = "Description";
                index = randNum.Next(Description.Count);
                using Message msg1 = PnpConvention.CreateMessage(telemetryName, Description[index]);
                await _deviceClient.SendEventAsync(msg1, cancellationToken);
                _logger.LogDebug($"Telemetry: Sent - {{ \"{telemetryName}\": {Description[index]} }}.");
    
                telemetryName = "Location";
                index = randNum.Next(Location.Count);
                using Message msg3 = PnpConvention.CreateMessage(telemetryName, Location[index]);
                await _deviceClient.SendEventAsync(msg3, cancellationToken);
                _logger.LogDebug($"Telemetry: Sent - {{ \"{telemetryName}\": {Location[index]} }}.");
    
                telemetryName = "DateTimeGateEvent";
                DateTime time = DateTime.Now;
                using Message msg4 = PnpConvention.CreateMessage(telemetryName, time);
                await _deviceClient.SendEventAsync(msg4, cancellationToken);
                _logger.LogDebug($"Telemetry: Sent - {{ \"{telemetryName}\": {time} }}.");
    
    
            }
    
        }
    }
    
    

    I have also made a change in Line 23 of Program.cs file under the same directory to make sure the Model ID is set to reflect the Model ID of the above template. Please find the change below

    private const string ModelId = "dtmi:digitaltwins:org:archive:download:rfidsmartlibrary:RfidSmartLibraryowl:LibraryItemGateCheckSensor;1";
    

    You can then follow the steps provided in Configure your environment to set the required values for the device and run the code to simulate the data. Please find the below image displaying the telemetry data received on the IoT Central device.

    enter image description here

    You can then export the data from IoT Central to one of the supported Data end points and Create an Azure Function to ingest the data into the Azure Digital Twin.

    Hope this helps. Please let us know if the above approach is useful and do let us know if you have any further questions.


    If the response helped, please do click Accept Answer and Yes. Doing so would help other community members with similar issue identify the solution. I highly appreciate your contribution to the community.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful