Skip to content

Instantly share code, notes, and snippets.

@sandervandevelde
Created August 14, 2020 15:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sandervandevelde/06bbcd8136f864890e208a9b5bac1eb0 to your computer and use it in GitHub Desktop.
Save sandervandevelde/06bbcd8136f864890e208a9b5bac1eb0 to your computer and use it in GitHub Desktop.
Azure IoT device client SDK Example (.Net C#)
using Azure.Storage.Blobs;
using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Client.Transport;
using Microsoft.Azure.Devices.Shared;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace DeviceClientConsoleApp
{
internal class Program
{
private static void Main(string[] args)
{
var connectionString = "[your device connection string]";
using var deviceClient = DeviceClient.CreateFromConnectionString(connectionString);
//// Set various callback messages: connection status, device twin, a single named method, multiple methods
SetVariousCallbackMethods(deviceClient);
//// open connection explicitly
deviceClient.OpenAsync().Wait();
//// Force the retrieval of the devicetwin
ForceDeviceTwinRetrieval(deviceClient);
//// send a single message
SendSingleMessage(deviceClient);
//// send multiple message in batch in one call
SendBatchOfMessages(deviceClient);
//// Send a file to the Blob storage configured in the IoT Hub
SendFileToBlobStorage(deviceClient);
//// Stall application closing
Console.WriteLine("Press a key to exit...");
Console.ReadKey();
}
private static void SendFileToBlobStorage(DeviceClient deviceClient)
{
//// Send a file
using var stream = File.OpenRead("upload.txt");
var fileUploadSasUri = deviceClient.GetFileUploadSasUriAsync(
new FileUploadSasUriRequest
{
BlobName = $"upload-{DateTime.Now.Ticks}.txt"
}).Result;
var correlationId = fileUploadSasUri.CorrelationId;
var isSuccess = false;
try
{
var blobClient = new BlobClient(fileUploadSasUri.GetBlobUri());
var response = blobClient.UploadAsync(stream).Result;
isSuccess = (response.GetRawResponse().Status == 201);
}
catch
{
// ignore all exceptions
}
finally
{
// Be sure to complete the fileupload so we prevent : Number of active file upload requests exceeded limit
var fileUploadCompletionNotification = new FileUploadCompletionNotification { CorrelationId = correlationId, IsSuccess = isSuccess };
deviceClient.CompleteFileUploadAsync(fileUploadCompletionNotification).Wait();
Console.WriteLine($"A file is sent; success={isSuccess} - {fileUploadSasUri.BlobName}");
}
}
private static void ForceDeviceTwinRetrieval(DeviceClient deviceClient)
{
var twin = deviceClient.GetTwinAsync().Result;
OnDesiredPropertyChanged(twin.Properties.Desired, deviceClient).Wait();
Console.WriteLine("The Devicetwin is forced retrieved");
}
private static void SetVariousCallbackMethods(DeviceClient deviceClient)
{
deviceClient.SetConnectionStatusChangesHandler(ConnectionStatusChangeHandler);
deviceClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChanged, deviceClient).ConfigureAwait(false);
deviceClient.SetMethodHandlerAsync("Ping", HandleMethodPing, deviceClient).ConfigureAwait(false);
deviceClient.SetMethodDefaultHandlerAsync(HandleDefaultMethods, deviceClient).ConfigureAwait(false);
var thread = new Thread(() => ThreadBody(deviceClient));
thread.Start();
Console.WriteLine("Callback methods are set");
}
private static void SendBatchOfMessages(DeviceClient deviceClient)
{
string jsonDataOne = "{ \"number\": \"one\" }";
var messageOne = new Message(Encoding.ASCII.GetBytes(jsonDataOne));
messageOne.Properties.Add("batch", "true");
string jsonDataTwo = "{ \"number\": \"two\" }";
var messageTwo = new Message(Encoding.ASCII.GetBytes(jsonDataTwo));
messageTwo.Properties.Add("batch", "true");
deviceClient.SendEventBatchAsync(new List<Message> { messageOne, messageTwo }).Wait();
Console.WriteLine("Messages are sent in batch");
}
private static void SendSingleMessage(DeviceClient deviceClient)
{
string jsonData = "{ \"single\":true }";
var message = new Message(Encoding.ASCII.GetBytes(jsonData));
message.Properties.Add("messagetype", "normal");
deviceClient.SendEventAsync(message).Wait();
Console.WriteLine("A single message is sent");
}
private static async void ThreadBody(object deviceClient)
{
var client = deviceClient as DeviceClient;
Console.WriteLine("Waiting for C2D messages (aka commands)");
while (true)
{
// The following line is blocking until a timeout occurs
using var message = await client.ReceiveAsync();
if (message == null)
{
Console.WriteLine("Timeout. Command is null");
continue;
}
string data = Encoding.UTF8.GetString(message.GetBytes());
Console.WriteLine($"A message is received with body {data}");
await client.CompleteAsync(message); // mark the message as handled
//await client.RejectAsync(message); // drops the message as unhandled
//await client.AbandonAsync(message); // puts message back on queue
}
}
private static Task<MethodResponse> HandleMethodPing(MethodRequest methodRequest, object userContext)
{
Console.WriteLine($"method {methodRequest.Name} handled with body {methodRequest.DataAsJson}");
return Task.FromResult(new MethodResponse(new byte[0], 200));
}
private static Task<MethodResponse> HandleDefaultMethods(MethodRequest methodRequest, object userContext)
{
Console.WriteLine($"Default method {methodRequest.Name} handled with body {methodRequest.DataAsJson}");
return Task.FromResult(new MethodResponse(new byte[0], 200));
}
private static void ConnectionStatusChangeHandler(ConnectionStatus status, ConnectionStatusChangeReason reason)
{
Console.WriteLine($"Connection Status Changed to {status} ({reason}) at {DateTime.Now}");
}
private static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext)
{
Console.WriteLine("One or more device twin desired properties changed:");
Console.WriteLine(JsonConvert.SerializeObject(desiredProperties));
var client = userContext as DeviceClient;
var reportedProperties = new TwinCollection
{
["DateTimeLastDesiredPropertyChangeReceived"] = DateTime.Now
};
await client.UpdateReportedPropertiesAsync(reportedProperties).ConfigureAwait(false);
Console.WriteLine("Sent current time as reported property to device twin");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment