Sei sulla pagina 1di 28
Lab 2- Using Custom Devices for Remote Monitoring
Lab 2- Using Custom Devices for Remote Monitoring
Lab 2- Using
Custom Devices
for Remote
Monitoring

Contents

Goals and Requirements

3

Creating a Custom Device for Azure IoT Suite’s Remote Monitoring Solution

3

Device Explorer Overview

12

Save IoT Hub Messages to Azure Table Storage

 

19

Terms of Use

27

Lab 2- Using Custom Devices for Remote Monitoring

Goals and Requirements

Estimated time to complete lab is 40-45 minutes.

Goals

1. Learn how to connect a device to Microsoft Azure IoT Suite and the Remote Monitoring Solution using the SDK.

2. See how to inspect device telemetry and interact with existing devices using the Device Explorer tool.

3. Act on messages sent to Azure IoT Hub using Azure Functions.

Requirements

1. Access to an Azure subscription (with subscription administrator permissions)

2. Visual Studio 2015 or later

3. Provisioned instance of the Azure IoT Suite’s Remote Monitoring Solution (from https://www.azureiotsuite.com)

Creating a Custom Device for Azure IoT Suite’s Remote Monitoring Solution

Creating a Custom Device for Azure IoT Suite’s Remote Monitoring

Part 1: Connect a Custom Device

1. Open the MSIOT_Hub_sample_device_lab_2.sln solution. This is

located in the Lab2\SampleDevice directory.

This is the same sample device you used in lab 1 but with missing components you will need to write. You will find the location where each code snippet is to be added clearly marked in this manner:

// See exercise 1.1.4 // ** Paste code snippet here **

2. In the Solution Explorer pane of Visual Studio right click on

the MSIOT_Hub_sample_device_lab_2 project and then select

Manage NuGet packages.

3. Click on the Browsetab, check the "Include prerelease" checkbox, search for and then add the Microsoft.Azure.Devices and Microsoft.Azure.Devices.Client NuGet packages.

Once you have found each package click the “Installbutton.

During this process you may be advised of changes to your solution and prompted to

During this process you may be advised of changes to your solution and prompted to accept the license terms for the packages. If so, click OK and I Accept respectively.

4. Open the MainWindow.xaml.cs file in Visual Studio.

4. Open the MainWindow.xaml.cs file in Visual Studio. 5. Implement missing the code for the ConnectDevice

5. Implement missing the code for the ConnectDevice method in the MainWindow.xaml.cs code behind file.

The authentication method uses the device id and the device primary key generated in the Remote Monitoring Solution device creation page.

var authMethod = new DeviceAuthenticationWithRegistrySymmetricKey(_dev iceId, _devicePrimaryKey);

This authentication mechanism requires that the device stores a symmetric key which is used for authentication. If physical device security and/or key management are an issue it would

be best to investigate other mechanisms of performing device authentication.

6. Create the device connection string using the Remote Monitoring Solution's IoT Hub host name and the authMethod variable created above.

var deviceConnectionString = Microsoft.Azure.Devices.Client.IotHubConnectionSt ringBuilder.Create(_deviceHostName, authMethod).ToString();

7. Instantiate the two device clients: one for receiving and one for sending messages. Both device clients use the same connection string. Both uses AMQP as its transport protocol.

We are using separate device clients for receiving and sending messages. This allows us to use separate tasks to send and receive messages. It is not required otherwise.

_sendDeviceClient = DeviceClient.CreateFromConnectionString(deviceCon nectionString, TransportType.Amqp); _receiveDeviceClient = DeviceClient.CreateFromConnectionString(deviceCon nectionString, TransportType.Amqp);

8. Next implement the SendMessageAsync() method contents. We will call this method whenever we send telemetry data to the Remote Monitoring Solution and when we update the device information in Cosmos DB.

This method uses a deviceClient connected to the IoT Hub to send its data to the Remote Monitoring Solution.

var message = new

Message(Encoding.UTF8.GetBytes(messageJson));

await deviceClient.SendEventAsync(message);

9. Now that SendMessageAsync is implemented correctly we can use it to send the telemetry events.

In the SendTelemetryEventsAsync method's async delegate body add the code to send telemetry data.

var monitorData = new RemoteMonitorTelemetryData

{

DeviceId = DeviceIdTextBox.Text, Temperature = TempSlider.Value, Humidity = HumiditySlider.Value, ExternalTemperature = null }; var message = JsonConvert.SerializeObject(monitorData); await SendMessageAsync(message, _sendDeviceClient);

This code creates a telemetry data object with the values from the sliders on the main page, then serializes the data as JSON and passes it to the SendMessageAsync method we completed before. Notice that we are using the _sendDeviceClient for sending data.

The RemoteMonitorTelemetryData class is used to format the telemetry data.

10. Press F5 to build and run the sample device program.

11. Open the https://www.azureiotsuite.com website and launch your Remote Monitoring Solution portal.

12. Click on the Devices link in the left hand navigation and find the device you created in Lab 1.

hand navigation and find the device you created in Lab 1. 13. In the Device properties

13. In the Device properties pane copy the DeviceID and the HostName.

Copy these into the corresponding boxes on the “ Settings ” tab of the device

Copy these into the corresponding boxes on the Settingstab of the device app.

14. Click on the View Authentication Keyslink.

14. Click on the “ View Authentication Keys ” link. 15. Copy Key 1. Copy this

15. Copy Key 1.

“ View Authentication Keys ” link. 15. Copy Key 1. Copy this into the “ Device

Copy this into the Device Primary Keybox in the device app and click Connect.

Once connected you will be able to manually start the device to send telemetry. It will show on the web dashboard as well as in the Events tab of the device application.

Part 2: Register the device In order for the device to be shown in the Remote Monitoring Solution we need register the device in our Cosmos DB account. To do so we

will send a specific message that the existing EventProcessor WebJob will pick up and use to update an entry in the Cosmos DB. This entry will be used by the Remote Monitoring Portal to show the device as connected in the devices window and allow telemetry data to be rendered in the dashboard.

1. The startup event message is generated in the DeviceSchemaHelper helper class. There are 3 parts to the device schema message that we need to generate:

Device message type

Device properties

Device commands

The device message type is used by the WebJob in the Remote Monitoring Solution to determine how to interpret and act on the message.

The device properties contain the metadata for the device that is stored in Cosmos DB (such as the device ID, the status, the available RAM, and processor type). Device properties can also be stored in IoT Hub (as part of the device twin).

The device commands describe the remote commands the device can receive and process. These are shown in the Remote Monitoring Solution. Commands can be a simple message such as turn on, or they can have parameters such as a specific temperature which the device will be set to.

2. Paste the following code snippet into the SendStartupEventMessage method in the MainWindow.xaml.cs file. In the snippet we are creating the device schema json then sending it as a message to the Remote Monitoring Solution.

var deviceSchema = DeviceSchemaHelper.BuildDeviceStructure(deviceId); var message = JsonConvert.SerializeObject(deviceSchema); await SendMessageAsync(message, deviceClient);

3. Now we must implement the device schema in the Device Schema Helper. Open the DeviceSchemaHelper.cs file and find the BuildDeviceStructure method.

4. Create the base DeviceInfo message:

// must be DeviceInfo or will not work, checked for in event webjob device.Add(DeviceModelConstants.OBJECT_TYPE, "DeviceInfo");

// must be 1.0 or will not work, checked for in event webjob device.Add(DeviceModelConstants.VERSION, "1.0");

device.Add(DeviceModelConstants.IS_SIMULATED_DEVIC E, "false");

5. Add this snippet to the method to add the device properties to the message that will be sent:

// deviceProps is just a JObject JObject deviceProps = new JObject();

// the device properties are read out of the device properties object

deviceProps.Add(DevicePropertiesConstants.DEVICE_I D, deviceId);

deviceProps.Add(DevicePropertiesConstants.HUB_ENAB LED_STATE, true);

deviceProps.Add(DevicePropertiesConstants.DEVICE_S TATE, "normal");

deviceProps.Add(DevicePropertiesConstants.UPDATED_ TIME, DateTime.UtcNow);

// add the device properties and the empty command history

device.Add(DeviceModelConstants.DEVICE_PROPERTIES, deviceProps); device.Add(DeviceModelConstants.COMMAND_HISTORY, new JArray());

6. Next add the set of commands that the device will be able to receive and process:

// create on and off commands commands var switchOnCommand = new JObject { { CommandModelConstants.NAME, CommandNames.TURN_ON_COMMAND_NAME } }; var switchOffCommand = new JObject { { CommandModelConstants.NAME, CommandNames.TURN_OFF_COMMAND_NAME } };

var commands = new JArray(); commands.Add(switchOnCommand); commands.Add(switchOffCommand);

device.Add(DeviceModelConstants.COMMANDS,

commands);

7. Now your device schema message is good to go. When the device is connected it will send this message which in turn is processed by the Remote Monitoring Solution.

8. Press F5 to build and run the device application. Connect and start the device as you have done previously.

9. In the Remote Monitoring site, refresh the page and observe that the device status is now ‘Running’

Take note of the message on the Events tab sent when the device is started. This should match what you have just set up. Note that the device also shows as “Running” in the portal.

Part 3: Receive Commands In the last section you sent a message to the IoT Suite. Now you are going to implement receiving commands in your device. You will be doing three things with the received data:

Displaying the raw JSON message in the Received Events text box on the Events tab.

If a message matches one of the device's supported commands, then log the command being received in the Received Events text box.

Then alter the device status in some way and show it on the main tab (turn device on or off).

1. Open MainWindow.xaml.cs of the sample and complete the ReceiveCommandsAsync method by replacing the code snippet comment in the async delegate body with the following code snippet:

var receivedMessage = await _receiveDeviceClient.ReceiveAsync(); if (receivedMessage?.Properties.Count > 0)

{

StreamReader reader = new StreamReader(receivedMessage.BodyStream); string receivedText = reader.ReadToEnd();

// check received message for a command ProcessCommand(receivedText);

AddLineToTextbox(ReceivedEventsTextBox,

receivedText);

}

// completing the message to cause the command to show as completed in the portal await _receiveDeviceClient.CompleteAsync(receivedMessage );

The _receiveDeviceClient.ReceiveAsync() call receives the next message off the message queue for this device.

If a message is received, we then:

o

Read the message text out of the message body

o

Send the text to the ProcessCommand method

o

Log the message in the received events textbox

o

Call _receiveDeviceClient.CompleteAsync(receivedMessa ge) to acknowledge the message has been processed.

It is important to complete the message so that we can register the command as received. You will notice in the Remote Monitoring Solution commands page that the command's status will change from pending to completed once the device completes the message.

2. Now implement the body of the ProcessCommand method by replacing the code snippet area with the following code. Here we are only implementing the turn on and turn off commands:

// deserialize object dynamic command = JsonConvert.DeserializeObject(jsonString);

if (command.Name.Value == CommandNames.TURN_ON_COMMAND_NAME)

{

// turn on the device StartDevice(); // print command info in commands text box AddLineToTextbox(ReceivedEventsTextBox, "Received switch on command");

}

else if (command.Name.Value ==

CommandNames.TURN_OFF_COMMAND_NAME)

{

// turn off the device StopDevice(); // print command info in commands text box AddLineToTextbox(ReceivedEventsTextBox, "Received switch off command");

}

In this code block we are calling into the existing StartDevice() and StopDevice() methods. This ensures that the remote command behaves exactly the same as the manual button click start and stop behaviors.

3. Press F5 to build and run the sample device program. Connect the device application. Go to the device portal and send the “Turn on” and “Turn off” device commands as you did in Lab 1. Notice the status of the device application (top right corner).

Congratulations, your sample device now behaves correctly!

Device

Explorer

Overview

Device Explorer Overview The Device Explorer application is a valuable troubleshooting and debugging tool which you can use for any IoT solution based on IoT Suite. The Device Explorer connects directly to a hub and can interact with it directly, work with devices registered with the IoT Hub, and monitor messages being sent to and from.

Part 1: Setup

1. Download the Device Explorer from:

https://github.com/Azure/azure-iot-sdk-csharp/releases

2. Install Device Explorer.

3. Navigate to install directory (C:\Program Files

(x86)\Microsoft\DeviceExplorer\).

4.

Run DeviceExplorer.exe.

Part 2: Configuration

1. Open a browser and navigate to the Azure Portal (https://portal.azure.com).

2. Open Resource Groups, select your IoT Suite Resource Group, and then select the IoT Hub.

your IoT Suite Resource Group, and then select the IoT Hub. 3. Copy the primary connection

3. Copy the primary connection string for the generated access policy name "iothubowner" in the IoT Hub.

access policy name "iothubowner" in the IoT Hub. 4. Paste the connection string into the Device

4. Paste the connection string into the Device Explorer configuration text area.

5. Click "Update" We are not using protocol gateway in this demo so leave this

5. Click "Update"

We are not using protocol gateway in this demo so leave this blank. You can find more information on protocol gateways at:

Part 3: Device Management Here we will show how to get the connection details for devices, update the access keys, create, and delete new devices in the IoT Suite using the Device Explorer.

1. Click the "Management" tab at the top of the application.

2. Wait 5-20 seconds for the device data to be retrieved.

3. Click "SAS Token " to generate a device-specific connection string with SAS token. 4.

3. Click "SAS Token

"

to generate a device-specific connection

string with SAS token.

4. To get a specific device connection string:

Click on the device row.

Right click and select "Copy connection string for selected device".

5. To create a new device:

Click "Create"

Enter a Device Id or select "Auto Generate Id"

Click "Create" (this can take a second or two to process)

Click "Done" once the Device Created message box appears

As we are creating a device directly against the IoT Suite the device will not show in the portal because no metadata is saved to Cosmos DB. Storing metadata is part of the Remote Monitoring Solution workflow.

6. To update a device:

Click "Update"

Select the device to update

Update the Primary Key or Secondary Key

Click "Update"

7. To Delete a device:

Click on the device row for the device you created above

Click "Delete"

Confirm you want to delete the device

If you were to delete a device that is registered in the Remote Monitoring Solution this will not remove the device metadata stored in Cosmos DB. To completely remove one of these devices you will have delete from the portal to ensure that the metadata is removed.

Part 4: Data Monitoring Using Device Explorer, you can inspect events that a device is sending to the IoT Suite. We receive the events from the IoT Suite as they are ingested. We can also retrieve events from a specific start time.

1. Click the "Data" tab at the top of the application.

2. Select the device that you want to monitor from the Device ID dropdown.

3. Click "Monitor".

4. After a couple of minutes, the device event data will be displayed:

Part 5: Messages to Devices You can use the Device Explorer to send commands to

Part 5: Messages to Devices You can use the Device Explorer to send commands to a device via the Azure IoT Suite.

For this exercise you will need to have the test device app from Part 1 of this lab, running and connected.

1. Switch back to Visual Studio.

2. Press F5 to build and run the sample device application.

You will be able to connect it to the Remote Monitoring Solution using the steps followed at the end of Exercise 1 - Part 1 of this lab.

1. Switch to the Device Explorer.

2. Click the Messages To Devicetab at the top of the application.

3. Select your test device to send a command to it.

4. Enter your command for the device in json: { "Name": "Turn on device" } and press Send.

5. Switch to the Device Explorer and click on the “ Events ” tab to

5. Switch to the Device Explorer and click on the Eventstab to check that your device received the command.

” tab to check that your device received the command. 6. Close the Device Explorer and

6. Close the Device Explorer and the test Device Application.

Save IoT Hub Messages to Azure Table Storage

Save IoT Hub Messages to Azure Table Storage Once our device is successfully sending messages, the next step is to act on them in the cloud. The Remote Monitoring Solution provides

a range of analytics capabilities out of the box – which we’ll explore in

a later lab – but for now we’ll show how you can use Azure Functions to act on incoming messages.

IoT Hub exposes a built-in Event Hub-compatible endpoint to enable applications to read IoT Hub messages. Meanwhile, applications use consumer groups to read data from IoT Hub. Before creating an Azure Function App to read data from your IoT Hub, you need to:

Get the Event Hub-compatible name from your IoT Hub.

Create a consumer group for your IoT Hub.

Part 1: Get the Event Hub-compatible Name From Your IoT Hub

1. Open your IoT Hub in Azure Portal.

From Your IoT Hub 1. Open your IoT Hub in Azure Portal . 2. In the

2. In the IoT Hub pane, under Messaging in the menu, open Endpoints. Under the Built-in endpoint select Events and write down the Event Hub-compatible name. This will be used later in this tutorial.

Hub-compatible name. This will be used later in this tutorial. Lab 2- Using Custom Devices for

Part 2: Create a consumer group for your IoT Hub

1. While in the IoT Hub pane under Endpoints > Events

2. In the Properties pane, enter a name under Consumer groups and write down the name.

3. Click Save.

Consumer groups and write down the name. 3. Click Save . Part 3: Create and Deploy

Part 3: Create and Deploy an Azure Function App

1. In Azure Portal, click New > Compute > Function App.

2. Enter the necessary information for the Function App.

App name: the name of the Function App. The name must be globally unique.

Resource group: Use the same resource group that your IoT Hub uses.

Hosting Plan: Use consumption plan (where available).

Location: Select the same location as your IoT Suite instance

Storage: Click Select Existing and choose the storage account that is part of your IoT Suite intance

Pin to Dashboard: Select this option if you wish to have easy access to the Function App from the dashboard.

Leave the other fields as default

3. Click Create . 4. Open the Function App once it is created. 5. Create

3. Click Create.

4. Open the Function App once it is created.

5. Create a new function in the Function App.

a. Click Functions > New Function. b. IMPORTANT: Depending on whether you’ve created a Function
a.
Click Functions > New Function.
b.
IMPORTANT: Depending on whether you’ve created a
Function before, you may reach a Quickstart page. If
so, click the custom function link at the bottom. If you
do not see this page, skip this step and go to Step C.
c. From the Custom Function template page, select JavaScript for Language , and Data Processing

c. From the Custom Function template page, select JavaScript for Language, and Data Processing for Scenario and click the EventHubTrigger-JavaScript template.

and click the EventHubTrigger-JavaScript template. d. Enter the necessary information for the template. Name

d. Enter the necessary information for the template.

Name your function: The name of the function. NOTE: In this case, we’ve just chosen the default- generated name.

Event Hub name: The Event Hub-compatible name you noted down earlier.

Event Hub connection: Click new to select the IoT built-in Events endpoint.

: Click new to select the IoT built-in Events endpoint . Lab 2- Using Custom Devices
e. Click Create. 6. Configure an output for the function. a. Click Integrate > New

e. Click Create.

6. Configure an output for the function.

a. Click Integrate > New Output > Azure Table Storage > Select.

New Output > Azure Table Storage > Select . b. Enter the necessary information (Note: you

b. Enter the necessary information (Note: you may need to scroll to the right too see the Azure Table Storage fields mentioned below)

Table parameter name: Use

name, which will be used in the Azure Function’s code.

outputTable

for the

Table name: Use

deviceData

for the name.

Storage account connection: Click new and select or input your storage account. If you cannot see the storage account, please refer to Storage account requirements.

c. Click Save.

7. Under Triggers , click Azure Event Hub (eventHubMessages). 8. Under Event Hub consumer group

7. Under Triggers, click Azure Event Hub (eventHubMessages).

8. Under Event Hub consumer group, enter the name of the consumer group that you created, and then click Save.

the consumer group that you created, and then click Save . 9. Click the Function you

9. Click the Function you created, and then click View files on the right.

10. Replace the code in click Save.

index.js

with the following, and then

'use strict' ; // This function is triggered each time a message is revieved in
'use strict'
;
// This function is triggered each time a message
is revieved in the IoTHub.
// The message payload is persisted in an Azure
Storage Table
module
.exports =
function (context, iotHubMessage)
{
context.log(
'Message received: '
+
JSON
.stringify(iotHubMessage));
var
date =
Date
.now();
var
partitionKey =
Math
.floor(date / (
24
*
60
*
60
*
1000
)) +
''
;
var
rowKey = date +
''
;
context.bindings.outputTable = {
"partitionKey"
: partitionKey,
"rowKey"
: rowKey,
"message"
:
JSON
.stringify(iotHubMessage)
};
context.done();
};

By now, you have created the Function App. It stores messages that your IoT Hub receives in your Azure table storage.

NOTE: You can use the Run button to test the Function App. When you click Run, the test message is sent to your IoT Hub. The arrival of the message should trigger the Function App to start and then save the message to your Azure table storage. The Logs pane records the details of the process.

Part 4: Verify Your Message in Your Table Storage

1. Run the sample application on your device to send messages

to your IoT Hub.

3.

Open Microsoft Azure Storage Explorer, click Add an Azure Account > Sign in, and then sign in to your Azure account.

4. Click your Azure subscription > Storage Accounts > your storage account > Tables > deviceData.

5. You should see messages sent from your device to your IoT

Hub logged in the below).

deviceData

table. (See the screenshot

IoT Hub logged in the below). deviceData table. (See the screenshot Lab 2- Using Custom Devices

Terms of Use

© 2017 Microsoft Corporation. All rights reserved.

By using this Hands-on Lab, you agree to the following terms:

The technology/functionality described in this Hands-on Lab is provided by Microsoft Corporation in a “sandbox” testing environment for purposes of obtaining your feedback and to provide you with a learning experience. You may only use the Hands-on Lab to evaluate such technology features and functionality and provide feedback to Microsoft. You may not use it for any other purpose. You may not modify, copy, distribute, transmit, display, perform, reproduce, publish, license, create derivative works from, transfer, or sell this Hands-on Lab or any portion thereof.

COPYING OR REPRODUCTION OF THE HANDS-ON LAB (OR ANY PORTION OF IT) TO ANY OTHER SERVER OR LOCATION FOR FURTHER REPRODUCTION OR REDISTRIBUTION IS EXPRESSLY PROHIBITED.

THIS HANDS-ONLAB PROVIDES CERTAIN SOFTWARE TECHNOLOGY/PRODUCT FEATURES AND FUNCTIONALITY, INCLUDING POTENTIAL NEW FEATURES AND CONCEPTS, IN A SIMULATED ENVIRONMENT WITHOUT COMPLEX SET-UP OR INSTALLATION FOR THE PURPOSE DESCRIBED ABOVE. THE TECHNOLOGY/CONCEPTS REPRESENTED IN THIS HANDS-ON LAB MAY NOT REPRESENT FULL FEATURE FUNCTIONALITY AND MAY NOT WORK THE WAY A FINAL VERSION MAY WORK. WE ALSO MAY NOT RELEASE A FINAL VERSION OF SUCH FEATURES OR CONCEPTS. YOUR EXPERIENCE WITH USING SUCH FEATURES AND FUNCITONALITY IN A PHYSICAL ENVIRONMENT MAY ALSO BE DIFFERENT.

FEEDBACK. If you give feedback about the technology features, functionality and/or concepts described in this Hands-on Lab to Microsoft, you give to Microsoft, without charge, the right to use, share and commercialize your feedback in any way and for any purpose. You also give to third parties, without charge, any patent rights needed for their products, technologies and services to use or interface with any specific parts of a Microsoft software or service that includes the feedback. You will not give feedback that is subject to a license that requires Microsoft to license its software or documentation to third parties because we include your feedback in them. These rights survive this agreement.

MICROSOFT CORPORATION HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS WITH REGARD TO THE HANDS-ON LAB , INCLUDING ALL WARRANTIES AND CONDITIONS OF MERCHANTABILITY, WHETHER EXPRESS, IMPLIED OR STATUTORY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. MICROSOFT DOES NOT MAKE ANY ASSURANCES OR REPRESENTATIONS WITH REGARD TO THE ACCURACY OF THE RESULTS, OUTPUT

THAT DERIVES FROM USE OF THE VIRTUAL LAB, OR SUITABILITY OF THE INFORMATION CONTAINED IN THE VIRTUAL LAB FOR ANY PURPOSE.