Skip to content
This repository was archived by the owner on Nov 16, 2023. It is now read-only.

Commit 98ac09e

Browse files
author
David R. Williamson
authored
Merge pull request #169 from Azure-Samples/drwill/DeviceSimulator2
Update DeviceSimulator2
2 parents 39c99b2 + b3fdcb6 commit 98ac09e

File tree

5 files changed

+192
-105
lines changed

5 files changed

+192
-105
lines changed

iot-hub/Quickstarts/Quickstarts.sln

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "read-d2c-messages", "read-d
99
EndProject
1010
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimulatedDevice", "simulated-device\SimulatedDevice.csproj", "{C22BD1F5-D8A7-452A-96C4-FF0C0553EBF3}"
1111
EndProject
12-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "simulated-device-2", "simulated-device-2\simulated-device-2.csproj", "{3B033BD3-38B4-4B92-8871-2787DD7C86CC}"
12+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimulatedDeviceWithCommand", "simulated-device-2\SimulatedDeviceWithCommand.csproj", "{3B033BD3-38B4-4B92-8871-2787DD7C86CC}"
1313
EndProject
1414
Global
1515
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
// This application uses the Azure IoT Hub device SDK for .NET
5+
// For samples see: https://github.com/Azure/azure-iot-sdk-csharp/tree/master/iothub/device/samples
6+
7+
using Microsoft.Azure.Devices.Client;
8+
using System;
9+
using System.Linq;
10+
using System.Text;
11+
using System.Text.Json;
12+
using System.Threading;
13+
using System.Threading.Tasks;
14+
15+
namespace SimulatedDevice
16+
{
17+
/// <summary>
18+
/// This sample illustrates the very basics of a device app sending telemetry and receiving a command.
19+
/// For a more comprehensive device app sample, please see
20+
/// <see href="https://github.com/Azure-Samples/azure-iot-samples-csharp/tree/master/iot-hub/Samples/device/DeviceReconnectionSample"/>.
21+
/// </summary>
22+
internal class Program
23+
{
24+
private static DeviceClient s_deviceClient;
25+
private static readonly TransportType s_transportType = TransportType.Mqtt;
26+
27+
// The device connection string to authenticate the device with your IoT hub.
28+
// Using the Azure CLI:
29+
// az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id MyDotnetDevice --output table
30+
private static string s_connectionString = "{Your device connection string here}";
31+
32+
private static TimeSpan s_telemetryInterval = TimeSpan.FromSeconds(1); // Seconds
33+
34+
private static async Task Main(string[] args)
35+
{
36+
Console.WriteLine("IoT Hub Quickstarts #1 - Simulated device.");
37+
38+
// This sample accepts the device connection string as a parameter, if present
39+
ValidateConnectionString(args);
40+
41+
// Connect to the IoT hub using the MQTT protocol
42+
s_deviceClient = DeviceClient.CreateFromConnectionString(s_connectionString, s_transportType);
43+
44+
// Create a handler for the direct method call
45+
await s_deviceClient.SetMethodHandlerAsync("SetTelemetryInterval", SetTelemetryInterval, null);
46+
47+
// Set up a condition to quit the sample
48+
Console.WriteLine("Press control-C to exit.");
49+
using var cts = new CancellationTokenSource();
50+
Console.CancelKeyPress += (sender, eventArgs) =>
51+
{
52+
eventArgs.Cancel = true;
53+
cts.Cancel();
54+
Console.WriteLine("Device simulator exit requested...");
55+
};
56+
57+
// Run the telemetry loop
58+
await SendDeviceToCloudMessagesAsync(cts.Token);
59+
60+
s_deviceClient.Dispose();
61+
Console.WriteLine("Device simulator finished.");
62+
}
63+
64+
private static void ValidateConnectionString(string[] args)
65+
{
66+
if (args.Any())
67+
{
68+
try
69+
{
70+
var cs = IotHubConnectionStringBuilder.Create(args[0]);
71+
s_connectionString = cs.ToString();
72+
}
73+
catch (Exception)
74+
{
75+
Console.WriteLine($"Error: Unrecognizable parameter '{args[0]}' as connection string.");
76+
Environment.Exit(1);
77+
}
78+
}
79+
else
80+
{
81+
try
82+
{
83+
_ = IotHubConnectionStringBuilder.Create(s_connectionString);
84+
}
85+
catch (Exception)
86+
{
87+
Console.WriteLine("This sample needs a device connection string to run. Program.cs can be edited to specify it, or it can be included on the command-line as the only parameter.");
88+
Environment.Exit(1);
89+
}
90+
}
91+
}
92+
93+
// Handle the direct method call
94+
private static Task<MethodResponse> SetTelemetryInterval(MethodRequest methodRequest, object userContext)
95+
{
96+
var data = Encoding.UTF8.GetString(methodRequest.Data);
97+
98+
// Check the payload is a single integer value
99+
if (int.TryParse(data, out int telemetryIntervalInSeconds))
100+
{
101+
s_telemetryInterval = TimeSpan.FromSeconds(telemetryIntervalInSeconds);
102+
103+
Console.ForegroundColor = ConsoleColor.Green;
104+
Console.WriteLine($"Telemetry interval set to {s_telemetryInterval}");
105+
Console.ResetColor();
106+
107+
// Acknowlege the direct method call with a 200 success message
108+
string result = $"{{\"result\":\"Executed direct method: {methodRequest.Name}\"}}";
109+
return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
110+
}
111+
else
112+
{
113+
// Acknowlege the direct method call with a 400 error message
114+
string result = "{\"result\":\"Invalid parameter\"}";
115+
return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 400));
116+
}
117+
}
118+
119+
// Async method to send simulated telemetry
120+
private static async Task SendDeviceToCloudMessagesAsync(CancellationToken ct)
121+
{
122+
// Initial telemetry values
123+
double minTemperature = 20;
124+
double minHumidity = 60;
125+
var rand = new Random();
126+
127+
while (!ct.IsCancellationRequested)
128+
{
129+
double currentTemperature = minTemperature + rand.NextDouble() * 15;
130+
double currentHumidity = minHumidity + rand.NextDouble() * 20;
131+
132+
// Create JSON message
133+
string messageBody = JsonSerializer.Serialize(
134+
new
135+
{
136+
temperature = currentTemperature,
137+
humidity = currentHumidity,
138+
});
139+
using var message = new Message(Encoding.ASCII.GetBytes(messageBody))
140+
{
141+
ContentType = "application/json",
142+
ContentEncoding = "utf-8",
143+
};
144+
145+
// Add a custom application property to the message.
146+
// An IoT hub can filter on these properties without access to the message body.
147+
message.Properties.Add("temperatureAlert", (currentTemperature > 30) ? "true" : "false");
148+
149+
// Send the telemetry message
150+
await s_deviceClient.SendEventAsync(message);
151+
Console.WriteLine($"{DateTime.Now} > Sending message: {messageBody}");
152+
153+
try
154+
{
155+
await Task.Delay(s_telemetryInterval, ct);
156+
}
157+
catch (TaskCanceledException)
158+
{
159+
// User canceled
160+
return;
161+
}
162+
}
163+
}
164+
}
165+
}

iot-hub/Quickstarts/simulated-device-2/SimulatedDevice.cs

Lines changed: 0 additions & 96 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>netcoreapp2.1</TargetFramework>
5+
<TargetFramework>net5.0</TargetFramework>
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.*" />
9+
<PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.33.1" />
1010
</ItemGroup>
1111

1212
</Project>

iot-hub/Quickstarts/simulated-device/Program.cs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace SimulatedDevice
2121
internal class Program
2222
{
2323
private static DeviceClient s_deviceClient;
24+
private static readonly TransportType s_transportType = TransportType.Mqtt;
2425

2526
// The device connection string to authenticate the device with your IoT hub.
2627
// Using the Azure CLI:
@@ -32,10 +33,10 @@ private static async Task Main(string[] args)
3233
Console.WriteLine("IoT Hub Quickstarts #1 - Simulated device.");
3334

3435
// This sample accepts the device connection string as a parameter, if present
35-
CheckForConnectionStringArgument(args);
36+
ValidateConnectionString(args);
3637

3738
// Connect to the IoT hub using the MQTT protocol
38-
s_deviceClient = DeviceClient.CreateFromConnectionString(s_connectionString, TransportType.Mqtt);
39+
s_deviceClient = DeviceClient.CreateFromConnectionString(s_connectionString, s_transportType);
3940

4041
// Set up a condition to quit the sample
4142
Console.WriteLine("Press control-C to exit.");
@@ -50,19 +51,36 @@ private static async Task Main(string[] args)
5051
// Run the telemetry loop
5152
await SendDeviceToCloudMessagesAsync(cts.Token);
5253

54+
s_deviceClient.Dispose();
5355
Console.WriteLine("Device simulator finished.");
5456
}
5557

56-
private static void CheckForConnectionStringArgument(string[] args)
58+
private static void ValidateConnectionString(string[] args)
5759
{
5860
if (args.Any())
5961
{
6062
try
6163
{
62-
var cs = IotHubConnectionStringBuilder.Create(args.First());
64+
var cs = IotHubConnectionStringBuilder.Create(args[0]);
6365
s_connectionString = cs.ToString();
6466
}
65-
catch (Exception) { }
67+
catch (Exception)
68+
{
69+
Console.WriteLine($"Error: Unrecognizable parameter '{args[0]}' as connection string.");
70+
Environment.Exit(1);
71+
}
72+
}
73+
else
74+
{
75+
try
76+
{
77+
_ = IotHubConnectionStringBuilder.Create(s_connectionString);
78+
}
79+
catch (Exception)
80+
{
81+
Console.WriteLine("This sample needs a device connection string to run. Program.cs can be edited to specify it, or it can be included on the command-line as the only parameter.");
82+
Environment.Exit(1);
83+
}
6684
}
6785
}
6886

0 commit comments

Comments
 (0)