In a previous post a .Net Standard library that can be used in .Net Core, .Net Standard, UWP and Xamarin apps (last yet to be tested) was presented that implements the device and service functionality of IoT Hub Device Streaming that can be used in UWP and other types apps. The previous blog exemplified the use of the library through a UWP-XAML test app. This blog discusses the use of the library’s API from a programmatic perspective.

How to use the Updated UWPXaml app

Device and Service

The SDK documentation uses the terms Service and Client. The Client waits for messages from the Service and responds. Hence the services would typically be the user app and the client the IoT Device. Therefore in this documentation:

  • Service is the app that initiates communiation by sending a message via the IoT Hub to a device
  • Device is the IoT device connected to the IoT Hub that responds to message from the hub.

API calls for Default functionality

In this mode the device and server operate in single shot mode. That is, the service connects to the device via the Iot Hub, sends it message then awaits the reply. The device listens for a connection via the same IoT Hub, receives the message, processes it and sends it back. A socket it created at each end only for the duration of each communication in this mode.

Calls are made to the DeviceStream_Device, DeviceStream_Service and DeviceStreamingCommon classes in the library. All of the Azure IoT Hub Device Streaming functionality, as in the classes in the IoT Hub SDK Echo sample, has been refactored (and extended) into these classes in the library. Where there is app specific functionality required by the classes, a delegate is used.

The main calls to the API are the static calls:

  • Device_Stream_Device.RunDevice()
  • DeviceStream_Svc.RunSvc()

Each call generates an instance of the required entity (Device or Svc). In default mode, there are some manadatory parameters to these calls. There are also some optional parameters for more extended calls. In default node, the code required to set the device to listen for one connection follows:

Device App calls to the library

The call to set the device in one shot listen mode is quite simple:

private async void Button_Click_Device(object sender, RoutedEventArgs e)
{
    DeviceStreamingCommon.DeviceTimeout = TimeSpan.FromMilliseconds(10000);//10 seconds
    string device_cs ="Device connection string"
    await Task.Run(() =>
    {
        DeviceStream_Device.RunDevice(device_cs, OnDeviceRecvText).GetAwaiter().GetResult();
    });
}

The minimum required RunDevice() parameters are:

  • device_cs: The IOTHub Device connection string.
  • OnRecvdText delegate.

The optional parameters, not listed here but discussed in the next blog, default to null for delegates and false for bools (except one *).

The delegate OnRecvText, which can be null, is called whenever the Device receives a message from the Service via the IoTHub. It generates the returned message, typically a response to the received message. It could read sensors requested in the received message. A sample method that implements a simple handling of the received message (uppercasing it) follows:

private string OnDeviceRecvText(string msgIn)
{
    Console.WriteLine(msgIn);
    string msgOut = msgIn.ToUpper();
    Console.WriteLine(msgOut);
    return msgOut;
}

Note that in the implemented code, any delegate that is null is not called.

  • The one optional boolean parameter that defaults to true is Responds which means by default, the Device sends a response; the outcome of the call to OnDeviceRecvText.

Service App calls to the API

The call in the service app to send one message and get the response follows:

private async void Button_Click_Svc(object sender, RoutedEventArgs e)
{
    DeviceStreamingCommon.SvcTimeout = TimeSpan.FromMilliseconds(10000);
    service_cs ="IOT Hub Service connection string";
    device_id ="Device Id"; //Eg "MyDevice"
    string msgOut = "Hello Azure";
    await Task.Run(() =>
    {
        DeviceStream_Svc.RunSvc(service_cs, device_id, msgOut, OnSvcRecvText).GetAwaiter().GetResult();
    });
}

The minimum parameters for a call to RunSvc() are

  • service_cs The service connection string
  • device_id The device id
  • msgOut The message to be sent
  • OnSvcRecvText The delegate for received response.

The OnSvcRecvText delegate handles the reply from the device to sent message. For example:

private static void OnSvcRecvText(string msg)
{
    Console.WriteLine(msg);
}

That’s all that is required in Single Shot mode! :)

Note that with the IoTHub there are several connection strings that can be used. You click on Shared Access Policies for the IoTHub in the Azure Portal where you see 5 “users” for the hub.The one normally used is the service user which is used by the end user app (Service) to communicate with the hub. The iothubowner user can be used but has greater privileges not needed here (but will be needed in a later blog where devices are programatically created and deleted) . Connections
You click on the user, service in this case, and then can copy the Primary Connection String.
Note that that is is not where you get the Device Connection string from. You create the Device by clicking on the IoT Device pane on the IoTHub page and then add one or use an existing one. When you open a Device from there you get its Primary Connection string.

Note that in the sample apps, this code is with in multiple targeted try-catch constructs so a to identify any issues. The library code has similar checks and balances.

To change what the device (which is typically an IoT device) does, you only need to modify OnDeviceRecvText()in the device app. This could for example, read some sensor values and return them.


Next: The API Options


 TopicSubtopic
  Next: > AziothubDeviceStreaming
<  Prev:   AziothubDeviceStreaming
This Category:Azure Device Streaming
  Next: > AziothubDeviceStreaming Under the hood-The API Options 
<  Prev:   AziothubDeviceStreaming