The iotQi-App-RPiUWP template\sample provides the structure and concrete examples of typical IoT functions for a Raspberry PI running Windows 10 IoT Core.  This guide takes you through the process of creating your own Raspberry PI device application and customizing different parts of the application. 


Development Environment

To start, you will need a development environment; working with projects for Raspberry PI running Windows 10 IoT Core requires Microsoft Visual Studio.  Any edition of Visual Studio will work, including the Community edition; LooUQ recommends version VS2017.


The remainder of this guide assumes you have Visual Studio installed with the Windows 10 IoT Core SDK also installed.  If you haven’t done that yet, below are some helpful links.
https://developer.microsoft.com/en-us/windows/iot

While not a requirement, we recommend you download and install the Windows 10 IoT Core Dashboard utility to allow you to create Raspberry PI system images on SD cards and work with your PI’s.  You can download the latest version here…
https://developer.microsoft.com/en-us/windows/iot/downloads


Getting Started

At minimum, you will need to perform the following steps to build a running iotQi device application on your Raspberry PI or other UWP device such as a DragonBoard 410C…

  • Download the iotQi application template\sample from the LooUQ GitHub and place it in a local development folder. 
    • From the library click the Clone or download button
    • You use the GitHub desktop (Open in Desktop) -or-
    • Download entire library as a zip file (Download ZIP)
  • Open the iotQi-App-RPiUWP.sln solution file in Visual Studio.
  • Open the Startuptask.cs file to set the iotQi connection string. 
    • Find the line near the top of Run() with “var connectionString =” this is line 44 in the image below.
    • Copy\paste your device’s connection string from iotQi Setup (https://setup.loouq.com/Devices)
  • To see your application running on the Raspberry PI, set a Breakpoint on a line in StartupTask.cs to verify your application launches and that Visual Studio attaches as a debugging console to your application. A good place for this breakpoint is line 60 on the screen image below.



  • Now you are ready to build and then deploy the sample to your Raspberry PI.   
    • In VS the toolbar set the Solution Configuration to Debug
    • In VS the toolbar set the Solution Platform to ARM
    • Press F5 (Run) or Click the Remote Machine control.
  • If this is the very first time you have attempted to run the sample you will be asked to specify the remote machine name.  You can set the remote target by IP address or device name.  This is covered in more detail below.
  • The deploy can take 60 to 90 seconds so be patient.  After this time you should begin to see "processes" starting to execute in the Visual Studio Output windows and shortly after that your breakpoint should be hit (yellow arrow in the red circle on line 60 above).
  • You can continue or step-through the application but you will likely move on quickly to adapting the sample application to be whatever you want it to be.


You can also verify your application was deployed by using the Windows IoT Core Dashboard application.


Customizing Your Device Application

Setting the Remote Machine (the Remote Connection Deploy Target)

You will likely be working with multiple Raspberry PI devices, this section shows you how to switch between them.  From within Visual Studio, you select the Raspberry PI you want to install your device application to (deploy to) with the following steps…

  • Open your project’s Properties
  • Select the Debug category
  • Under Start options 
    • Enter the IP address or device name in the Remote machine field -OR-
    • Click Find to search for your Raspberry PI
    • Ensure that Authentication Mode is set to “Universal (Unencrypted Protocol)”



Clicking "Find" will bring up the Remote Connections dialog (shown below).  



Setting up Telemetry (Data Samples)

A key function for an iotQi device is to send telemetry information (aka data samples) to the cloud.  This could be done at periodic intervals or when an event takes place.  The sample follows the periodic interval model.  


To modify the telemetry functionality start by opening the SampleWeatherSimulator.cs file.  This file houses the logic for telemetry and alerts, in the sample.  The periodic interval is determined by the weatherSampleTimer periodic timer, when this timer "ticks" a new sample is generated and sent to iotQi.


The actual job of generating\sending the sample is built in the OnWeatherSampleSimulatedAsync() method. The OnWeatherSampleSimulatedAsync() method uses a random number generator and some math to derive an new wind sample. Once the sample is created it is evaluated to see if the wind is above a threshold, if so send and alert (covered next).


To send the telemetry sample the SendTelemetryAsync() method is called using the information generated. We use a reference to the iotqiClient object that was created the StartupTask. This line is shown here.


await StartupTask.iotqiClient.SendTelemetryAsync(simulatorName, LastWeatherReading, messageBody);


If your application needs to send telemetry based on an external event, rather than a periodic interval, you would replace the sample's timer trigger, OnWeatherSampleSimulatedAsync(ThreadPoolTimer timer), with a trigger originating from your device's hardware. This is beyond the scope of this getting started guide.


Setting up Alerts

Sending alerts is nearly identical to sending telemetry.  Typically alerts are not periodic, but are triggered by a data pattern or device hardware event.  In the sample, the "high wind alert" is triggered by the sample being above 90% of the maximum range.  


Once triggered, sending the alert is simply composing the information to send and calling the iotQi SendAlertAsync() method (nearly identical to the telemetry tasks).


await StartupTask.iotqiClient.SendAlertAsync("Wind Alert", notificationText, notificationBody);


Setting up Device Commands

To enable custom commands on your device you need to perform 2 tasks...

  • Create a public, static method that implements your command
  • Register the class containing your method with iotQi

Creating your method
Command methods are pretty much the same as any other C# method.  Command methods may take parameters, but this is not a requirement.  Command methods must however return a specific iotQi class named CommandMethodResult.


The CommandMethodResult class encapsulates a couple values to ensure the outcome of your device command makes it back to iotQi and in-turn your connected systems.  The key items within CommandMethodResult are the StatusCode and ResultBody properties.  


StatusCode: This property is an integer value indicating the status outcome of your command logic.  The value is determine by matching the standard HTTP status codes.  So a StatusCode value of 200 signifies sucess, you can set the StatusCode to other values to signify error conditions.


https://en.wikipedia.org/wiki/List_of_HTTP_status_codes


Result: This object property is converted into a JSON object representing a value or values generated by your command.  It can be an empty object {}, a structured JSON object or a single value.  If you pass in a single value it will be converted to {"result":<valueSupplied>}.


Registering Your Command Methods

Once your commands are created, you need to register them with iotQi in the StartupTask.  You register the commands by passing their parent class name into the iotQi RegisterCommandClass() method; this method will register all public, static methods within the class with iotQi and they will all be advertised as available to iotQi WebAPI clients.  For this reason, we recommend that command classes be limited to only including commands methods, or care be taken for making only appropriate methods public.


Sample register command class statments found in StartupTask.cs
 iotqiClient.RegisterCommandClass(typeof(SampleCommands)); 
iotqiClient.RegisterCommandClass(typeof(SampleWeatherApiCommands));


Changing the Application Name\Namespace

To change the name or namespace of your application you need to follow some Universal Windows Program (UWP) rules.  This section covers changing the device application name and the namespace.

  • Changing the Visual Studio Solution or Project Name
    • Do this inside Visual Studio, right-click, Rename.  
    • Note: This does not change the application name you would see when looking at your device using its Windows Device Portal (web browser).
    • If you change the name of the directory containing the project, you will need remove and re-add the project back to the solution.
  • Changing the Application Name
    • In Visual Studio open the project file Package.appxmanifest, we recommend the Designer view to get started (see below) and change the Display Name.


  • Changing the Namespace
    • In Visual Studio, open the project Properties view and select the Library panel.
    • Change the Assembly name and Default namespace to your preference.  We strongly recommend that they are the same, but absolutely the namespace must be the same or subordinate to the Assembly name.  
    • Next change the Namespace and using statements in the source code to match your changes on the Properties form.


Some Assembly and Namespace Examples


Example    Is This Valid?
Assembly name: MyDevApps

Default namespace: MyDevApps
Yes, This is good
Assembly name: MyDevApps

Default namespace: MyDevApps.App1
Yes, This is good
Assembly name: MyDevApps

Default namespace: MyDev.Apps
No, This is BAD.  
The namespace is not the same
or an extension to the assembly name.