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

Commit

Permalink
Merge pull request #169 from Azure-Samples/drwill/DeviceSimulator2
Browse files Browse the repository at this point in the history
Update DeviceSimulator2
  • Loading branch information
David R. Williamson authored Dec 9, 2020
2 parents 39c99b2 + b3fdcb6 commit 98ac09e
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 105 deletions.
2 changes: 1 addition & 1 deletion iot-hub/Quickstarts/Quickstarts.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "read-d2c-messages", "read-d
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimulatedDevice", "simulated-device\SimulatedDevice.csproj", "{C22BD1F5-D8A7-452A-96C4-FF0C0553EBF3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "simulated-device-2", "simulated-device-2\simulated-device-2.csproj", "{3B033BD3-38B4-4B92-8871-2787DD7C86CC}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimulatedDeviceWithCommand", "simulated-device-2\SimulatedDeviceWithCommand.csproj", "{3B033BD3-38B4-4B92-8871-2787DD7C86CC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
165 changes: 165 additions & 0 deletions iot-hub/Quickstarts/simulated-device-2/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

// This application uses the Azure IoT Hub device SDK for .NET
// For samples see: https://github.com/Azure/azure-iot-sdk-csharp/tree/master/iothub/device/samples

using Microsoft.Azure.Devices.Client;
using System;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace SimulatedDevice
{
/// <summary>
/// This sample illustrates the very basics of a device app sending telemetry and receiving a command.
/// For a more comprehensive device app sample, please see
/// <see href="https://github.com/Azure-Samples/azure-iot-samples-csharp/tree/master/iot-hub/Samples/device/DeviceReconnectionSample"/>.
/// </summary>
internal class Program
{
private static DeviceClient s_deviceClient;
private static readonly TransportType s_transportType = TransportType.Mqtt;

// The device connection string to authenticate the device with your IoT hub.
// Using the Azure CLI:
// az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id MyDotnetDevice --output table
private static string s_connectionString = "{Your device connection string here}";

private static TimeSpan s_telemetryInterval = TimeSpan.FromSeconds(1); // Seconds

private static async Task Main(string[] args)
{
Console.WriteLine("IoT Hub Quickstarts #1 - Simulated device.");

// This sample accepts the device connection string as a parameter, if present
ValidateConnectionString(args);

// Connect to the IoT hub using the MQTT protocol
s_deviceClient = DeviceClient.CreateFromConnectionString(s_connectionString, s_transportType);

// Create a handler for the direct method call
await s_deviceClient.SetMethodHandlerAsync("SetTelemetryInterval", SetTelemetryInterval, null);

// Set up a condition to quit the sample
Console.WriteLine("Press control-C to exit.");
using var cts = new CancellationTokenSource();
Console.CancelKeyPress += (sender, eventArgs) =>
{
eventArgs.Cancel = true;
cts.Cancel();
Console.WriteLine("Device simulator exit requested...");
};

// Run the telemetry loop
await SendDeviceToCloudMessagesAsync(cts.Token);

s_deviceClient.Dispose();
Console.WriteLine("Device simulator finished.");
}

private static void ValidateConnectionString(string[] args)
{
if (args.Any())
{
try
{
var cs = IotHubConnectionStringBuilder.Create(args[0]);
s_connectionString = cs.ToString();
}
catch (Exception)
{
Console.WriteLine($"Error: Unrecognizable parameter '{args[0]}' as connection string.");
Environment.Exit(1);
}
}
else
{
try
{
_ = IotHubConnectionStringBuilder.Create(s_connectionString);
}
catch (Exception)
{
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.");
Environment.Exit(1);
}
}
}

// Handle the direct method call
private static Task<MethodResponse> SetTelemetryInterval(MethodRequest methodRequest, object userContext)
{
var data = Encoding.UTF8.GetString(methodRequest.Data);

// Check the payload is a single integer value
if (int.TryParse(data, out int telemetryIntervalInSeconds))
{
s_telemetryInterval = TimeSpan.FromSeconds(telemetryIntervalInSeconds);

Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"Telemetry interval set to {s_telemetryInterval}");
Console.ResetColor();

// Acknowlege the direct method call with a 200 success message
string result = $"{{\"result\":\"Executed direct method: {methodRequest.Name}\"}}";
return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
}
else
{
// Acknowlege the direct method call with a 400 error message
string result = "{\"result\":\"Invalid parameter\"}";
return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 400));
}
}

// Async method to send simulated telemetry
private static async Task SendDeviceToCloudMessagesAsync(CancellationToken ct)
{
// Initial telemetry values
double minTemperature = 20;
double minHumidity = 60;
var rand = new Random();

while (!ct.IsCancellationRequested)
{
double currentTemperature = minTemperature + rand.NextDouble() * 15;
double currentHumidity = minHumidity + rand.NextDouble() * 20;

// Create JSON message
string messageBody = JsonSerializer.Serialize(
new
{
temperature = currentTemperature,
humidity = currentHumidity,
});
using var message = new Message(Encoding.ASCII.GetBytes(messageBody))
{
ContentType = "application/json",
ContentEncoding = "utf-8",
};

// Add a custom application property to the message.
// An IoT hub can filter on these properties without access to the message body.
message.Properties.Add("temperatureAlert", (currentTemperature > 30) ? "true" : "false");

// Send the telemetry message
await s_deviceClient.SendEventAsync(message);
Console.WriteLine($"{DateTime.Now} > Sending message: {messageBody}");

try
{
await Task.Delay(s_telemetryInterval, ct);
}
catch (TaskCanceledException)
{
// User canceled
return;
}
}
}
}
}
96 changes: 0 additions & 96 deletions iot-hub/Quickstarts/simulated-device-2/SimulatedDevice.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.*" />
<PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.33.1" />
</ItemGroup>

</Project>
28 changes: 23 additions & 5 deletions iot-hub/Quickstarts/simulated-device/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace SimulatedDevice
internal class Program
{
private static DeviceClient s_deviceClient;
private static readonly TransportType s_transportType = TransportType.Mqtt;

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

// This sample accepts the device connection string as a parameter, if present
CheckForConnectionStringArgument(args);
ValidateConnectionString(args);

// Connect to the IoT hub using the MQTT protocol
s_deviceClient = DeviceClient.CreateFromConnectionString(s_connectionString, TransportType.Mqtt);
s_deviceClient = DeviceClient.CreateFromConnectionString(s_connectionString, s_transportType);

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

s_deviceClient.Dispose();
Console.WriteLine("Device simulator finished.");
}

private static void CheckForConnectionStringArgument(string[] args)
private static void ValidateConnectionString(string[] args)
{
if (args.Any())
{
try
{
var cs = IotHubConnectionStringBuilder.Create(args.First());
var cs = IotHubConnectionStringBuilder.Create(args[0]);
s_connectionString = cs.ToString();
}
catch (Exception) { }
catch (Exception)
{
Console.WriteLine($"Error: Unrecognizable parameter '{args[0]}' as connection string.");
Environment.Exit(1);
}
}
else
{
try
{
_ = IotHubConnectionStringBuilder.Create(s_connectionString);
}
catch (Exception)
{
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.");
Environment.Exit(1);
}
}
}

Expand Down

0 comments on commit 98ac09e

Please sign in to comment.