ConnectTheDots will help you get tiny devices connected to Microsoft Azure, and to implement great IoT solutions taking advantage of Microsoft Azure advanced analytic services such as Azure Stream Analytics and Azure Machine Learning.
This lab is stand-alone, but is used at Microsoft to accompany a presentation about Azure, Windows 10 IoT Core, and our IoT services. If you wish to follow this on your own, you are encouraged to do so. If not, consider attending a Microsoft-led IoT lab in your area.
In this lab you will use a Raspberry Pi 2 device with Windows 10 Iot Core and a FEZ HAT sensor hat. Using a Windows 10 Universal Application, the sensors get the raw data and format it into a JSON string. That string is then shuttled off to the Azure IoT Hub, where it gathers the data and is then displayed in a chart using Power BI. The JSON string is sent to the IoT Hub in one of two ways: packaged into an AMQP message or in a REST packet. If you use AMQP, which is the recommended approach, you will need to have the AMQP port open on your firewall/router.
Note: Although AMQP is the recommended approach, at the time this lab was written that protocol was not supported by the Azure IoT Core SDK for UWP (Universal Windows Platform) applications. However, it is expected to be implemented in a short time, since it's currently under development.
This lab includes the following tasks:
SetupThe following sections are intended to setup your environment to be able to create and run your solutions with Windows 10 IoT Core.
Setting up your SoftwareTo setup your Windows 10 IoT Core development PC, you first need to install the following:
- Windows 10 (build 10240) or better
- Visual Studio 2015 or above – Community Edition is sufficient. NOTE: If you choose to install a different edition of VS 2015, make sure to do a Custom install and select the checkbox Universal Windows App Development Tools -> Tools and Windows SDK. You can validate your Visual Studio installation by selecting Help > About Microsoft Visual Studio. The required version of Visual Studio is 14.0.23107.0 D14Rel. The required version of Visual Studio Tools for Universal Windows Apps is 14.0.23121.00 D14OOB.
- Windows IoT Core Project Templates. You can download them from here. Alternatively, the templates can be found by searching for Windows IoT Core Project Templates in the Visual Studio Gallery or directly from Visual Studio in the Extension and Updates dialog (Tools > Extensions and Updates > Online).
- Make sure you’ve enabled developer mode in Windows 10 by following these instructions.
- To register your devices in the Azure IoT Hub Service and to monitor the communication between them you need to install the Azure Device Explorer.
For this project, you will need the following:
- Raspberry Pi 2 Model B with power supply
- Your PC running Windows 10, RTM build or later
- An Ethernet port on the PC, or an auto-crossover USB->Ethernet adapter like the Belkin F4U047.
- Standard Ethernet cable
- A good 16GB or 32GB Class 10 SD card. We recommend Samsung or Sandisk. Other cards will usually work, but tend to die more quickly.
- A WiFi dongle from the list of devices that are currently supported by Windows 10 IoT Core on the Raspberry Pi 2
To setup your devices perform the following steps:
1. Plug the GHI FEZ HAT into the Raspberry Pi 2.The FEZ hat connected to the Raspberry Pi 2 device
2. Get a Windows 10 IoT Core SD Card or download the Windows 10 IoT Core image as per the instructions on https://developer.microsoft.com/en-us/windows/iot/GetStarted, be sure to follow the steps to mount the image, and run the installer on your development PC. If you already have the OS image on a card, you still need to follow this step to get the IoT Core Watcher and Visual Studio templates on to your PC.
3. Once you have the image on the card, insert the micro SD card in the Raspberry Pi device.
4. Connect the Raspberry Pi to a power supply, optionally a keyboard, mouse and monitor, and use the Ethernet cable to connect your device and your development PC. You can do it by plugging in one end of the spare Ethernet cable to the extra Ethernet port on your PC, and the other end of the cable to the Ethernet port on your IoT Core device. (Do this using an on-board port or an auto-crossover USB->Ethernet interface.)
5. Wait for the OS to boot.
6. Run the Windows 10 IoT Core Watcher utility (installed in step 2) in your development PC and copy your Raspberry Pi IP address by right-clicking on the detected device and selecting Copy IP Address.
Click the windows "Start" button
- Type "WindowsIoTCoreWatcher" to pull it up in the search results
- You may want to right click on the program name and select "Pin to Start" to pin it to your start screen for easy access
- Press Enter to run it
- Your device should appear in the list within 5 seconds or so. If it does not, close the Windows 10 IoT Core Watcher, and relaunch it again.
7. Launch an administrator PowerShell console on your local PC. The easiest way to do this is to type powershell in the Search the web and Windows textbox near the Windows Start Menu. Windows will find PowerShell on your machine. Right-click the Windows PowerShell entry and select Run as administrator. The PS console will show.
8. You may need to start the WinRM service on your desktop to enable remote connections. From the PS console type the following command:net start WinRM
9. From the PS console, type the following command, substituting '<IP Address>' with the IP value copied in prev:Set-Item WSMan:\localhost\Client\TrustedHosts -Value <machine-name or IP Address>
10. Type Y and press Enter to confirm the change.
11. Now you can start a session with you Windows IoT Core device. From you administrator PS console, type:Enter-PSSession -ComputerName <IP Address> -Credential localhost\Administrator
12. In the credential dialog enter the following default password: p@ssw0rd
. Note: The connection process is not immediate and can take up to 30 seconds.If you successfully connected to the device, you should see the IP address of your device before the prompt.
- To change the computer name, use the setcomputername utility. In PowerShell, type the following command.
setcomputername <new-name>
- The date and time on the Pi must be correct for the security tokens used to publish to Azure later in the lab to be valid. To check the current time zone setting on the Pi, type:
tzutil /g
- If the time zone reported is not correct, you can find a list of valid time zones using (you may need to increase the buffer size on your powershell window):
tzutil /l
- To set the time zone, locate the id of the time zone you want from the step above, then use:`tzutil /s "Your TimeZone Name"For example, for "Pacific Standard Time"`tzutil /s "Pacific Standard Time"
- To check the date on the Raspberry Pi, type
Get-Date
- If the date or time is incorrect, use the
Set-Date
utilitySet-Date "mm/dd/yy hh:mm:ss AM/PM"
For Example, if it was 12:15 pm on January 3rd, 2016:Set-Date "01/03/16 12:15 PM"
- Reboot the device for the change to take effect. You can use the shutdown command as follows:
shutdown /r /t 0
- Finally, connect to the Raspberry Pi to the same network as your Windows 10 development PC.
You can also rename the device and set the time zone by using the web server, but certain functions, like actually changing the date and time, are currently available only through PowerShell. Now that you understand how to connect through PowerShell, we'll use the web server to set up WiFi.
Using WiFi on your Device1. To configure your device, run the Windows 10 IoT Core Watcher utility in your development PC and open the web-based management application by right-clicking the detected device and selecting Web Browser Here. To launch the "Windows 10 IoT Core Watcher" utility:
2. To use WiFi, you will need to provide Windows 10 IoT core with the WiFi network credentials.
- Enter Administrator for the username, and supply your password (p@ssw0rd by default).
- Click Networking in the left-hand pane.
- Under Available networks, select network you would like to connect to and supply the connection credentials. Click Connect to initiate the connection. Make sure the "Create profile (auto re-connect)" check box is checked so that the WiFi network will reconnect automatically if the Raspberry Pi reboots.
Note: You can find more info in Using WiFi on your Windows 10 IoT Core device.
Setting up your Azure AccountYou will need a Microsoft Azure subscription (free trial subscription is sufficient)
Creating an IoT Hub1. Enter the Azure portal, by browsing to http://portal.azure.com
2. Create a new IoT Hub. To do this, click New in the jumpbar, then click Internet of Things, then click Azure IoT Hub.Createing a new IoT HubCreating a new IoT Hub
3. Configure the IoT hub with the desired information:
- Enter a Name for the hub e.g. iot-sample,
- Select a Pricing and scale tier (F1 Free tier is enough),
- Create a new resource group, or select and existing one. For more information, see Using resource groups to manage your Azure resources.
- Select the Region such as East US where the service will be located.New IoT Hub settings
4. It can take a few minutes for the IoT hub to be created. Once it is ready, open the blade of the new IoT hub, take note of the URI and select the key icon at the top to access to the shared access policy settings:
5. Select the Shared access policy called iothubowner, and take note of the Primary key and connection string in the right blade. You should copy these into a text file for future use.
To create a Stream Analytics Job, perform the following steps:
1. Currently the new Azure Portal doesn't support all of the features of Stream Analytics required for this lab. For that reason, the Stream Analaytics configuration needs to be done in the classic portal. To open the classic portal, in your browser navigate to https://manage.windowsazure.com and login in with your Azure Subscription's credentials.
2. In the Azure Management Portal, click NEW, then click DATA SERVICES, then STREAM ANALYTICS, and finally QUICK CREATE.
3. Enter the Job Name, select a Region, such as East US (if it is an option, create the Stream Analytics Job in the same region as your IoT Hub) and the enter a NEW STORAGE ACCOUNT NAME if this is the first storage account in the region used for Stream Analitycs, if not you have to select the one already used for that region.
4. Click CREATE A STREAM ANALYTICS JOB.
5. After the Stream Analytics job is created, in the left pane click STORAGE, then click the account you used in the previous step, and click MANAGE ACCESS KEYS. As with the IoT Hub details, copy the STORAGE ACCOUNT NAME and the PRIMARY ACCESS KEY into a text file as you will use those values later.
Registering your deviceYou must register your device in order to be able to send and receive information from the Azure IoT Hub. This is done by registering a Device Identity in the IoT Hub.
1. Open the Device Explorer app (C:\Program Files (x86)\Microsoft\DeviceExplorer\DeviceExplorer.exe) and fill the IoT Hub Connection String field with the connection string of the IoT Hub you created in previous steps and click on Update.
2. Go to the Management tab and click on the Create button. The Create Device popup will be displayed. Fill the Device ID field with a new Id for your device (myFirstDevice for example) and click on Create:
3. Once the device identity is created, it will be displayed in the grid. Right click on the identity you just created, select Copy connection string for selected device and take note of the value copied to your clipboard, since it will be required to connect your device with the IoT Hub. Note: The device identities registration can be automated using the Azure IoT Hubs SDK. An example of how to do that can be found here.
Now that the device is configured, you will see how to create an application to read the value of the FEZ HAT sensors, and then send those values to an Azure IoT Hub.
Read FEZ HAT sensorsIn order to get the information out of the hat sensors, you will take advantage of the Developers' Guide that GHI Electronics published.
1. Download the zipped repositoryghi_elect-windows-iot-183b64180b7c.zip
2. Unblock the .zip file before extracting it. Unblocking the .zip file will keep Visual Studio from prompting you about "Trustworthy Sources". To Unblock the .zip file:
- Right click on the downloaded .zip file
- Select "Properties" from the popup menu.
- In the "Properties" window, on the "General" tab, turn on the checkbox labeled "Unblock"
- Click "OK"
3. Extract the files in your file system and locate the GHIElectronics.UAP.sln solution file (You must have Visual Studio installed in order to open the solution).
4. After opening the solution you will see several projects. The Developers's Guide comes with examples of many of the shields provided by the company. Right-click the one named GHIElectronics.UAP.Examples.FEZHAT, and select Set as Startup Project.
5. Ensure that the target platform for the project is set to "ARM":
6. Build the solution to restore the NuGet packages, and make sure it builds:
7. If after building the solution you still see IntelliSense errors in the code, you may need to close and re-open Visual Studio, then re-open the solution.
Note: Now you will inspect the sample code to see how it works. Bear in mind that this example is intended to show all the available features of the shield, while in this lab you will use just a couple of them (temperature and light sensors).
8. Open the MainPage.xaml.cs file and locate the Setup method.
private async void Setup()
{
this.hat = await GIS.FEZHAT.CreateAsync();
this.hat.S1.SetLimits(500, 2400, 0, 180);
this.hat.S2.SetLimits(500, 2400, 0, 180);
this.timer = new DispatcherTimer();
this.timer.Interval = TimeSpan.FromMilliseconds(100);
this.timer.Tick += this.OnTick; this.timer.Start();
}
In the first line, the program creates an instance of the FEZ HAT driver and stores it in a local variable. The driver is used for interacting with the shield. Then, after setting the limits for the servos (not used in this lab), a new DispatchTimer is created. A timer is often used in projects of this kind to poll the state of the sensors and perform operations. In this case the OnTick method is called every 100 miliseconds. You can see this method below.
private void OnTick(object sender, object e)
{
double x, y, z;
this.hat.GetAcceleration(out x, out y, out z);
this.LightTextBox.Text = this.hat.GetLightLevel().ToString("P2", CultureInfo.InvariantCulture);
this.TempTextBox.Text = this.hat.GetTemperature().ToString("N2", CultureInfo.InvariantCulture);
this.AccelTextBox.Text = $"({x:N2}, {y:N2}, {z:N2})";
this.Button18TextBox.Text = this.hat.IsDIO18Pressed().ToString();
this.Button22TextBox.Text = this.hat.IsDIO22Pressed().ToString();
this.AnalogTextBox.Text = this.hat.ReadAnalog(GIS.FEZHAT.AnalogPin.Ain1).ToString("N2", CultureInfo.InvariantCulture);
}
This sample shows how to use the FEZ HAT driver to get data from the sensors. The data is then shown in the UI. (To see how the UI is designed check the MainPage.xaml file)
9. To deploy the application to the Raspberry Pi, the device has to be on the same network as the development computer. To run the program, select Remote device in the Debug Target dropdown list:
10. If a remote machine has not been selected before, the Select Remote Connection screen will be displayed:
11. If the device is not auto-detected, the Raspberry Pi IP or name can be entered in the Address field. Otherwise, click the desired device. Change the Authentication Mode to Universal (Unencrypted Protocol):
12. If you want to change the registered remote device later it can be done in the project Properties page. Right-click the project name (GHIElectronics.UAP.Examples.FEZHAT) and select Properties. In the project Properties' page, select the Debug tab and enter the new device name or IP in the Remote Machine field.Changing the Remote Connection SettingsNote: Clicking the Find button will display the Remote Connection screen.
13. If you don't have a screen connected to the Raspberry, you can add the following code to the OnTick method in order to show the value of the sensors in the Visual Studio Output Console. (Insert the code after reading the sensors).
// Add diagnostics information
System.Diagnostics.Debug.WriteLine
("
Light: {0},
Temp: {1},
Accel: {2},
Button18: {3},
Button22: {4}",
this.LightTextBox.Text,
this.TempTextBox.Text,
this.AccelTextBox.Text,
this.Button18TextBox.Text,
this.Button22TextBox.Text
);
14. Click the debug button to start the deployment to the Raspberry Pi. The first deployment will take some time as the remote debug tools, frameworks, and your code all need to be deployed. This could take up to a couple of minutes to completely deploy. You can monitor the status in the Visual Studio "Output" window.
15. If the program is successfully deployed to the device, the current value of the different sensors will be displayed on the screen. The shield LEDs will also be turned on and off alternately. In addition, if you added the Debug.Writeline code above to the OnTick method, the "Output" window will display sensor data:
Now that you know how to read the FEZ HAT sensors data, you will send that information to an Azure IoT Hub. To do that, you will use an existing project located in the Code\Begin folder. This project is based on the ConnectTheDots Raspberry Pi with Windows 10 IoT sample project but using the Azure IoT SDK to connect with Azure, instead of using an Event Hub.
1. Open the solution located in the Code\Begin folder.
2. Before running the application, you must set the Device connection information. Go to the MainPage method of the MainPage.xaml.cs file and replace IOT_CONNECTION_STRING with your device connection string, obtained in previous steps using the Device Explorer app:
ctdHelper = new ConnectTheDotsHelper(iotDeviceConnectionString: "IOT_CONNECTION_STRING", organization: "YOUR_ORGANIZATION_OR_SELF", location: "YOUR_LOCATION", sensorList: sensors);
Note: An Organization and Location may also be provided. Those values will be part of the telemetry message payload, and could be used to get a better classification of the data received.
3. Before the app can be deployed you need to change the solution target platform, since the Raspberry Pi is based on the ARM architecture. To do that select ARM in the Solution Platform dropdown:
As you can see in the sample code, the app uses a button in the UI to simulate a real sensor. Every time the user presses the button the value of the sensor is incremented and that info is then sent to Azure.
private void Button_Clic(object sender, RoutedEventArgs e)
{
ConnectTheDotsSensor sensor = ctdHelper.sensors.Find(item => item.measurename == "Temperature");
sensor.value = counter++;
ctdHelper.SendSensorData(sensor);
}
4. For those devices lacking a monitor or display, the button will be replaced by a Timer so the same function can be performed without needing to click any button. If this is your case, perform the following steps.
- Replace the Button_Click method for this one:
private void Timer_Tick(object sender, object e)
{
ConnectTheDotsSensor sensor = ctdHelper.sensors.Find(item => item.measurename == "Temperature");
sensor.value = counter++;
ctdHelper.SendSensorData(sensor);
}
- Then, replace the call to the Button_Click method in the MainPage method for the following piece of code:
//Button_Click(null, null);
var timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(500);
timer.Tick += Timer_Tick;
timer.Start();
Which will make the Timer ticks twice a second.
- Lastly, remove the button from the UI:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBox x:Name="HelloMessage" Text="ConnectTheDots on IoT" Margin="10" IsReadOnly="True"/>
<!--<Button x:Name="ClickMe" Content="Click Me!" Margin="10" HorizontalAlignment="Center" Click="Button_Click"/>-->
</StackPanel>
</Grid>
5. Before adding real sensor information you can run this code to see how the device connects to your Azure IoT Hub and sends information. Run the application.
6. After the app has been successfully deployed, it can start sending messages to the IoT Hub. If the device is connected to a display and a mouse, click the Click Me button several times.The information being sent can be monitored using the Device Explorer application. Run the application and go to the Data tab and select the name of the device you want to monitor (myFirstDevice in your case), then click on Monitor
Note: If the Device Explorer hub connection is not configured yet, you can follow the instructions explained in the Registering your device section
7. If you followed the instructions for devices without a screen attached, you will need to delete the timer created in that flow before you continue. A new timer will be created in the next steps replacing the previous one. Remove the Timer_Tick method you created before and delete the following lines from the MainPage constructor
var timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(500);
timer.Tick += Timer_Tick;
timer.Start();
8. Now that the device is connected to the Azure IoT Hub, add some real sensor information. First, you need to add a reference the FEZ HAT drivers. To do so, instead of manually adding the projects included in the GHI Developer's Guide, you will install the NuGet package that they provide. To do this, open the Package Manager Console (Tools/NuGet Package Manager/Package Manager Console) and execute the following command:
PM> Install-Package GHIElectronics.UWP.Shields.FEZHAT
9. Add a reference to the FEZ HAT library namespace in the MainPage.xaml.cs file:
using GHIElectronics.UWP.Shields;
10. Declare the variables that will hold the reference to the following objects:
- hat: Of the type Shields.FEZHAT, will contain the hat driver object that you will use to communicate with the FEZ hat through the Raspberry Pi hardware.
- telemetryTimer: of the type DispatchTimer, that will be used to poll the hat sensors at regular basis. For every tick of the timer the value of the sensors will be get and sent to Azure.
FEZHAT hat;
DispatcherTimer telemetryTimer;
11. You will add the following method to initialize the objects used to handle the communication with the hat. The TelemetryTimer_Tick method will be defined next, and will be executed every 500 ms according to the value hardcoded in the Interval property.
private async Task SetupHatAsync()
{
this.hat = await FEZHAT.CreateAsync();
this.telemetryTimer = new DispatcherTimer();
this.telemetryTimer.Interval = TimeSpan.FromMilliseconds(500);
this.telemetryTimer.Tick += this.TelemetryTimer_Tick;
this.telemetryTimer.Start();
}
12. The following method will be executed every time the timer ticks, and will poll the value of the hat's temperature sensor, send it to the Azure IoT Hub and show the value obtained.
private void TelemetryTimer_Tick(object sender, object e)
{
// Temperature Sensor var tSensor = ctdHelper.sensors.Find(item => item.measurename == "Temperature"); tSensor.value = this.hat.GetTemperature(); this.ctdHelper.SendSensorData(tSensor); this.HelloMessage.Text = "Temperature: " + tSensor.value.ToString("N2"); System.Diagnostics.Debug.WriteLine("Temperature: {0} °C", tSensor.value);
}
The first statement gets the ConnectTheDots sensor from the sensor collection already in place in the project (the temperature sensor was already included in the sample solution). Next, the temperature is polled out from the hat's temperature sensor using the driver object you initialized in the previous step. Then, the value obtained is sent to Azure using the ConnectTheDots's helper object ctdHelper which is included in the sample solution.The last two lines are used to show the current value of the temperature sensor to the screen and the debug console respectively.Note: To show the value of the sensor in the screen the app is using the Welcome message textbox. In the following steps the UI will be improved.
13. Before running the application you need to add the call to the SetupHatAsync method. Replace the Page_Loaded method with this block of code:
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
// Initialize FEZ HAT shield
await SetupHatAsync();
}
Note that the async modifier was added to the event handler to properly handle the asynchronous call to the FEZ HAT initialization method.
14. Now you are ready to run the application. Connect the Raspberry Pi with the FEZ HAT and run the application. After the app is deployed you will start to see in the output console (also in the screen) the values polled from the sensor. The information sent to Azure is also shown in the console.
You can also check that the messages were successfully received by monitoring them using the Device Explorer
15. Now you will add the information from another sensor. To incorporate the data from the Light sensor you will need to add a new ConnectTheDots sensor:
// Hard coding guid for sensors. Not an issue for this particular application which is meant for testing and demos
List<ConnectTheDotsSensor> sensors = new List<ConnectTheDotsSensor> { new ConnectTheDotsSensor("2298a348-e2f9-4438-ab23-82a3930662ab", "Light", "L"), new ConnectTheDotsSensor("d93ffbab-7dff-440d-a9f0-5aa091630201", "Temperature", "C"),};
16. Next, add the following code to the TelemetryTimer_Tick method to poll the data from the temperature sensor and send it to Azure.
// Light Sensor
ConnectTheDotsSensor lSensor = ctdHelper.sensors.Find(item => item.measurename == "Light");
lSensor.value = this.hat.GetLightLevel();
this.ctdHelper.SendSensorData(lSensor);
this.HelloMessage.Text = String.Format("Temperature: {0} °C, Light {1}", tSensor.value.ToString("N2"), lSensor.value.ToString("P2", System.Globalization.CultureInfo.InvariantCulture));
System.Diagnostics.Debug.WriteLine("Temperature: {0} °C, Light {1}", tSensor.value.ToString("N2"), lSensor.value.ToString("P2", System.Globalization.CultureInfo.InvariantCulture));
Note: If you want to poll the Light sensor data at a different rate, you will need to create another DispatchTimer and set it to different interval.
After running the app you will see the following output in the debug console. In this case two messages are sent to Azure in every timer tick:Output Window after Adding the Light Sensor
17. (Optional) If you have a screen connected to the Raspberry Pi device, you can improve the existing UI to show the sensor information in the screen. To do that, replace the content of the MainPage.xaml file code for this one:
<Page x:Class="WindowsIoTCorePi2FezHat.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:WindowsIoTCorePi2FezHat" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal"> <StackPanel Width="100">
<TextBlock Text="Light: " FontSize="26.667" Margin="10" />
<TextBlock Text="Temp: " FontSize="26.667" Margin="10" />
</StackPanel>
<StackPanel>
<StackPanelMargin="10"> <TextBlock Name="LightTextBox" FontSize="26.667" />
<ProgressBar Name="LightProgress" Value="0" Minimum="0" Maximum="1" Width="150"></ProgressBar>
</StackPanel>
<TextBlock Name="TempTextBox" FontSize="26.667" Margin="10" />
</StackPanel>
</StackPanel>
</Grid>
</Page>
The preceding view code incorporates a new textbox for every sensor and also a progress bar to graphically show the value of the Light sensor.
18. Lastly, you will update the TelemetryTimer_Tick method to adapt it to the new UI structure. Replace the method with the following code:
private void TelemetryTimer_Tick(object sender, object e)
{
// Light Sensor
ConnectTheDotsSensor lSensor = ctdHelper.sensors.Find(item => item.measurename == "Light");
lSensor.value = this.hat.GetLightLevel();
this.ctdHelper.SendSensorData(lSensor);
this.LightTextBox.Text = lSensor.value.ToString("P2", System.Globalization.CultureInfo.InvariantCulture);
this.LightProgress.Value = lSensor.value;
// Temperature Sensor
var tSensor = ctdHelper.sensors.Find(item => item.measurename == "Temperature");
tSensor.value = this.hat.GetTemperature(); this.ctdHelper.SendSensorData(tSensor);
this.TempTextBox.Text = tSensor.value.ToString("N2", System.Globalization.CultureInfo.InvariantCulture);
System.Diagnostics.Debug.WriteLine("Temperature: {0} °C, Light {1}", tSensor.value.ToString("N2", System.Globalization.CultureInfo.InvariantCulture), lSensor.value.ToString("P2", System.Globalization.CultureInfo.InvariantCulture));
Consuming the IoT Hub data
You have seen how to use the Device Explorer to peek the data being sent to the Azure IoT Hub. However, the Azure IoT suite offers many different ways to generate meaningful information from the data gathered by the devices. In the following sections you will explore two of them: You will see how the Azure Services Bus Messaging system can be used in a Website (part of the ConnectTheDots project), and how to use Azure Stream Analytics in combination with Microsoft Power BI to consume the data and to generate meaningful reports.
Using Power BIOne of the most interesting ways to use the information received from the connected device/s is to get near real-time analysis using the Microsoft Power BI tool. In this section you will see how to configure this tool to get an online dashboard showing summarized information about the different sensors.
Setting up a Power BI accountIf you don't have a Power BI account already, you will need to create one (a free account is enough to complete this lab). If you already have an account set you can skip this step.
- Go to the Power BI website and follow the sign-up process.Note: At the moment this lab was written, only users with corporate email accounts are allowed to sign up. Free consumer email accounts (like Outlook, Hotmail, Gmail, Yahoo, etc.) can't be used.
- •You will be asked to enter your email address. Then a confirmation email will be sent. After following the confirmation link, a form to enter your personal information will be displayed. Complete the form and click Start.The preparation of your account will take several minutes, and when it's ready you will see a screen similar to the following:
Now that your account is set, you are ready to set up the data source that will feed the Power BI dashboard.
Create a Service Bus Consumer GroupIn order to allow several consumer applications to read data from the IoT Hub independently at their own pace a Consumer Group must be configured for each one. If all of the consumer applications (the Device Explorer, Stream Analytics / Power BI, the Web site you will configure in the next section) read the data from the default consumer group, one application will block the others.
To create a new Consumer Group for the IoT Hub that will be used by the Stream Analytics job you are about to configure, follow these steps:
- Open the Azure Portal (https://portal.azure.com/), and select the IoT Hub you created.
- From the settings blade, click on Messaging
- At the bottom of the Messaging blade, type the name of the new Consumer Group "PowerBI"
- From the top menu, click on the Save icon
In order to feed the Power BI reports with the information gathered by the hats and to get that information in near real-time, Power BI supports Azure Stream Analytics outputs as data source. The following section will show how to configure the Stream Analytics job created in the Setup section to take the input from the IoT Hub and push that summarized information to Power BI.
Stream Analytics Input Setup
Before the information can be delivered to Power BI, it must be processed by a Stream Analytics Job. To do so, an input for that job must be provided. As the Raspberry devices are sending information to an IoT Hub, it will be set as the input for the job.
1. Go to the classic Azure management portal (https://manage.windowsazure.com) and select the Stream Analytics service. There you will find the Stream Analytics job created during the Azure services setup. Click on the job to enter the Stream Analytics configuration screen.
2. As you can see, the Start button is disabled since the job is not configured yet. To set the job input click on the INPUTS tab and then in the Add an input button.
3. In the Add an input to your job popup, select the Data Stream option and click Next. In the following step, select the option IoT Hub and click Next. Lastly, in the IoT Hub Settings screen, provide the following information:
- Input Alias:TelemetryHub
- Subscription: Use IoT Hub from Current Subscription (you can use an Event Hub from another subscription too by selecting the other option)
- Choose an IoT Hub:iot-sample (or the name used during the IoT Hub creation)
- IoT Hub Shared Access Policy Name:iothubowner
- IoT Hub Consumer Group:powerbi
Stream Analytics Input Configuration
4. Click Next, and then Complete (leave the Serialization settings as they are).
Stream Analytics Output Setup
The output of the Stream Analytics job will be Power BI.
1. To set up the output, go to the Stream Analytics Job's OUTPUTS tab, and click the ADD AN OUTPUT link.
2. In the Add an output to your job popup, select the POWER BI option and the click the Next button.
3. In the following screen you will setup the credentials of your Power BI account in order to allow the job to connect and send data to it. Click the Authorize Now link.
You will be redirected to the Microsoft login page.
5. In this screen you will enter the following information:
- Output Alias: PowerBI
- Dataset Name: Raspberry
- Table Name: Telemetry
- Group Name: My Workspace
6. Click the checkmark button to create the output.
Stream Analytics Query configurationNow that the job's inputs and outputs are already configured, the Stream Analytics Job needs to know how to transform the input data into the output data source. To do so, you will create a new Query.
1. Go to the Stream Analytics Job QUERY tab and replace the query with the following statement:
SELECT iothub.iothub.connectiondeviceid displayname, location, guid, measurename, unitofmeasure, Max(timecreated) timecreated, Avg(value) AvgValue INTO [PowerBI] FROM [TelemetryHUB] TIMESTAMP by timecreated GROUP BY iothub.iothub.connectiondeviceid, location, guid, measurename, unitofmeasure, TumblingWindow(Second, 10)
The query takes the data from the input (using the alias defined when the input was created TelemetryHUB) and inserts into the output (PowerBI, the alias of the output) after grouping it using 10 seconds chunks.
2. Click on the SAVE button and YES in the confirmation dialog.
Starting the Stream Analytics Job
Now that the job is configured, the START button is enabled. Click the button to start the job and then select the JOB START TIME option in the START OUTPUT popup. After clicking OK the job will be started.
Once the job starts it creates the Power BI datasource associated with the given subscription.
Setting up the Power BI Dashboard1. Now that the datasource is created, go back to your Power BI session, and go to My Workspace by clicking the Power BI link.
After some minutes of the job running you will see that the dataset that you configured as an output for the Job, is now displayed in the Power BI workspace Datasets section.
Note: The Power BI dataset will only be created if the job is running and if it is receiving data from the IoT Hub input, so check that the Universal App is running and sending data to Azure to ensure that the dataset be created. To check if the Stream Analytics job is receiving and processing data you can check the Azure management Stream Analytics monitor.
2. Once the datasource becomes available you can start creating reports. To create a new Report click on the Raspberry datasource:
The Report designer will be opened showing the list of fields available for the selected datasource and the different visualizations supported by the tool.
3. To create the Average Light by time report, select the following fields:
- avgvalue
- timecreated
As you can see the avgvalue field is automatically set to the Value field and the timecreated is inserted as an axis. Now change the chart type to a Line Chart:
4. Then you will set a filter to show only the Light sensor data. To do so drag the measurename field to the Filters section and then select the Light value:
5. Now the report is almost ready. Click the SAVE button and set Light by Time as the name for the report.
6. Now you will create a new Dashboard, and pin this report to it. Click the plus sign (+) next to the Dashboards section to create a new dashboard. Set Raspberry Telemetry as the Title and press Enter. Now, go back to your report and click the pin icon to add the report to the recently created dashboard.
7. To create a second chart with the information of the average Temperature follow these steps:
- Click on the Raspberry datasource to create a new report.
- Select the avgvalue field
- Drag the measurename field to the filters section and select Temperature
- Now change the visualization to a gauge chart:
- Change the Value from Sum to Average
- Now the Report is ready:
- Save and then Pin it to the Dashboard.
8. Following the same directions, create a Temperature report and add it to the dashboard.
9. Lastly, edit the reports name in the dashboard by clicking the pencil icon next to each report.Editing the Report TitleAfter renaming both reports you will get a dashboard similar to the one in the following screenshot, which will be automatically refreshed as new data arrives.
1. Before starting you need to create Consumer Groups to avoid colliding with the Stream Analytics job, in the same way you did in the Using Power BI section. The website needs two different consumer groups:
- website
- local (used when debugging)
2. Also take note of the Event Hub-compatible name and Event Hub-compatible endpoint values in the Messaging blade
3. Browse to the Assets/WebSite folder and open the Web Site project (ConnectTheDotsWebSite.sln) in Visual Studio.
4. Edit the Web.config file and add the corresponding values for the following keys:
- Microsoft.ServiceBus.EventHubDevices: Event hub-compatible name.
- Microsoft.ServiceBus.ConnectionStringDevices: Event hub-compatible connection string which is composed by the Event hub-compatible endpoint and the iothubowner Shared access policy Primary Key.
- Microsoft.Storage.ConnectionString: Storage account endpoint, in this case use the storage account name and storage account primary key to complete the endpoint.
5. Deploy the website to an Azure Web Site. To do this, perform the following steps.
- In Visual Studio, right-click on the project name and select Publish.
- Select Microsoft Azure Web Apps.
Click New and use the following configuration.
- Web App name: Pick something unique.
- App Service plan: Select an App Service plan in the same region used for Stream Analytics or create a new one using that region.
- Region: Pick same region as you used for Stream Analytics.
- Database server: No database.
Click Create. After some time the website will be created in Azure.
Click Publish.
Note: You might need to install WebDeploy extension if you are having an error stating that the Web deployment task failed. You can find WebDeploy here.
6. After you deployed the site, it is required that you enable Web sockets. To do this, perform the following steps:
- Browse to https://portal.azure.com and select your _Azure Web App.
- Click All settings.
- Click Applicattion settings
- Then set Web sockets to On and click Save.
7. Browse to your recently deployed Web Application. You will see something like in the following screenshot. There will be 2 real-time graphics representing the values read from the temperature and light sensors. Take into account that the Universal app must be running and sending information to the IoT Hub in order to see the graphics.
Note: At the bottom of the page you should see “Connected.”. If you see “ERROR undefined” you likely didn’t enable WebSockets for the Azure Web Site.
Azure IoT Hub is a service that enables reliable and secure bi-directional communications between millions of IoT devices and an application back end. In this section you will see how to send cloud-to-device messages to your device to command it to change the color of one of the FEZ HAT leds, using the Device Explorer app as the back end.
1. Open the Universal app you created before and add the following method to the ConnectTheDotsHelper.cs file:
public async Task<string> ReceiveMessage()
{
if (this.HubConnectionInitialized)
{
try
{
var receivedMessage = await this.deviceClient.ReceiveAsync();
if (receivedMessage != null)
{
var messageData = Encoding.ASCII.GetString(receivedMessage.GetBytes());
this.deviceClient.CompleteAsync(receivedMessage);
return messageData;
}
else
{
return string.Empty; }
}
catch (Exception e)
{
Debug.WriteLine("Exception when receiving message:" + e.Message);
return string.Empty;
}
}
else
{
return string.Empty;
}
}
The ReceiveAsync method returns the received message at the time that it is received by the device. The call to CompleteAsync() notifies IoT Hub that the message has been successfully processed and that it can be safely removed from the device queue. If something happened that prevented the device app from completing the processing of the message, IoT Hub will deliver it again.
2. Now you will add the logic to process the messages received. Open the MainPage.xaml.cs file and add a new timer to the MainPage class:
DispatcherTimer commandsTimer;
3. Add the following method, which will be on charge of processing the commands:
private async void CommandsTimer_Tick(object sender, object e)
{
string message = await ctdHelper.ReceiveMessage();
if (message != string.Empty)
{
System.Diagnostics.Debug.WriteLine("Command Received: {0}", message);
switch (message.ToUpperInvariant())
{
case "RED":
hat.D2.Color = new FEZHAT.Color(255, 0, 0);
break;
case "GREEN":
hat.D2.Color = new FEZHAT.Color(0, 255, 0);
break;
case "BLUE":
hat.D2.Color = new FEZHAT.Color(0, 0, 255);
break;
case "OFF":
hat.D2.TurnOff();
break;
default:
System.Diagnostics.Debug.WriteLine("Unrecognized command: {0}", message);
break;
}
}
}
It reads the message received, and according to the text of the command, it set the value of the hat.D2.Color attribute to change the color of the FEZ HAT's LED D2. When the "OFF" command is received the TurnOff() method is called, which turns the LED off.
4. Lastly, add the following piece of code to the SetupHatAsync method in order to initialize the timer used to poll for messages.
this.commandsTimer = new DispatcherTimer();
this.commandsTimer.Interval = TimeSpan.FromSeconds(60);this.commandsTimer.Tick += this.CommandsTimer_Tick;this.commandsTimer.Start();
Note: The recommended interval for HTTP/1 message polling is 25 minutes. For debugging and demostration purposes a 1 minute polling interval is fine (you can use an even smaller interval for testing), but bear it in mind for production development. Check this article for guidance. When AMQP becomes available for the IoT Hub SDK using UWP apps a different approach can be taken for message processing, since AMQP supports server push when receiving cloud-to-device messages, and it enables immediate pushes of messages from IoT Hub to the device. The following article explains how to handle cloud-to-device messages using AMQP.
5. Deploy the app to the device and open the Device Explorer app.
- Once it's loaded (and configured to point to your IoT hub), go to the Messages To Device tab, check the Monitor Feedback Endpoint option and write your command in the Message field. Click on Send
6. After a few seconds the message will be processed by the device and the LED will turn on in the color you selected. The feedback will also be reflected in the Device Explorer screen after a few seconds.
In this lab, you have learned how to create a Universal app that reads from the sensors of a FEZ hat connected to a Raspberry Pi 2 running Windows 10 IoT Core, and upload those readings to an Azure IoT Hub. You also learned how to read and consume the information in the IoT Hub using Power BI to get near real-time analysis of the information gathered from the FEZ hat sensors and to create simple reports and how to consume it using a website. You also saw how to use the IoT Hubs Cloud-To-Device messages feature to send simple commands to your devices.
Comments