This post has been republished via RSS; it originally appeared at: New blog articles in Microsoft Tech Community.
Prerequisites
- Install the software prerequisites on your PC that are listed here
- Create an IoT Hub in either Central US, North Europe, or Japan East.
- Add an IoT Device to your IoT Hub. Make a note of the connection string.
- Setup your Azure Cloud Shell as described here
- Raspberry Pi 3 Model B+ with Raspbian GNU/Linux 9 (stretch) installed
- Sense HAT installed on the Raspberry Pi device
The Sense HAT device has a LED display and number of sensors built into it including: temperature, humidity and pressure. It also has a well documented Python API. But the biggest reason I like to use it is to avoid fiddling with breadboards, resistors and jumper cables .
Getting Started
Once you have the Sense Hat installed on the Raspberry Pi along with Raspbian 9 (stretch), the next step is to install the Sense HAT Python API.
Note: I haven't found a decently documented C-based API for the Sense HAT. If you know of one, please send me a link to it!
Let's also ensure we have Python 3 installed.
Now test that the Sense HAT is working with the following Python commands.
If all is successful, a "Hello world!" message should scroll across the LED display.
Model your device
If you are familiar with DTDL (which is based on JSON-LD) you'll know we need to first develop an Interface for the Sense HAT and then create a Model file. Together these form a Device Capability Model (DCM).
Creating an Interface
A Interface describes the capabilities that are implemented by a device. Interfaces are reusable and can be used across different capability models.
In our case, the Interface we will develop will describe the Sense HAT's:
- temperature sensor
- humidity sensor
- pressure sensor
- LED display
In DTDL, the three (3) sensors are considered a Telemetry data type since they emit data from the sensor. The LED display will be a Command data type, as our IoT solution will send a command to the Sense HAT to display a message on the LED.
Follow the "Create the interface file" instructions, substituting the following:
-
SenseHat as the name of the interface and press Enter. VS Code creates a sample interface file called SenseHat.interface.json.
-
Replace the contents of the sample SenseHat.interface.json file with the following JSON:
As you can see we've modeled the 3 sensors and the LED display in the Interface using DTDL. For each data type there are a number of DTDL properties which can be set. In the above example I have configured a few, but there are more.
IntelliSense is available when editing the DTDL using VS Code. Try changing any of the "unit" values and you'll see what I mean.
Creating a Model file
Next, we will want to create a Model file. The model file specifies the interfaces that your device implements. There are typically at least two interfaces in a model - one or more that define the specific capabilities of your device, and a standard interface that all IoT Plug and Play devices must implement.
Follow the "Create the model file" instructions, substituting the following:
- Enter SenseHatModel as the name of the model. VS Code creates a sample interface file called SenseHatModel.capabilitymodel.json.
- Replace the contents of the sample SenseHatModel.capabilitymodel.json file (filename must end with .capabilitymodel.json) with the following JSON:
Notice the DeviceInformation interface (known as a standard interface) was automatically added and is required (e.g. for Device Certification).
Lastly download the DeviceInformation interface from the public model repository using the instructions.
Publish the model
As part of the release of Plug and Play, Microsoft is hosting an Azure Certified for IoT repository for you to host your model. Using the model repository is optional; you can store the model on the local device (not covered in this Blog post).
There are two sides to the repository:
- Public repository - where publicly published Models and Interfaces are stored.
- Company repository - where private Models and Interfaces are stored (e.g. prior to publishing publicly or when you have feature/device that is specific to your organization).
Follow the "Publish your model" instructions to publish the following two files to your Company repository:
- SenseHat.interface.json
- SenseHatModel.capabilitymodel.json
By default, the model will be stored in the Company repository. You can optionally publish it to the Public repository.
Generate stub code
Using VS Code you can generate stub code for your IoT device. However, there are some limitations with this at the moment:
- You will need to use Azure IoT Device SDKs that are Plug and Play-aware. Currently, only the C and Node Device SDKs are Plug and Play-aware. The other SDKs (e.g. Python) will be updated to be Plug and Play-aware in the future.
- VS Code only generates stub code in C (sorry Node ).
These limitations pose a problem for us, as you will see later (recall, the Sense HAT only ships with a Python API!).
Follow the "Generate code" instructions to generate the stub C code, substituting the following:
- SenseHatModel.capabilitymodel.json as the model file
- sensehat_app as the app name
Once you have finished generating the stub code you will find the following files in a new sensehat_app folder:
The primary file you need to concern yourself with is SenseHatModel_impl.c. This is the file where we will add our implementation code.
Update the stub code
Now let's add our implementation code to SenseHatModel_impl.c.
- Using VS Code, open the sensehat_app\SenseHatModel_impl.c file.
- Paste in the implementation code from https://github.com/khilscher/SenseHATPnP/blob/master/sensehat_app/SenseHatModel_impl.c
Recall that I mentioned earlier that the Sense HAT API is Python-based. To work around this, I am using popen to run the Python 3 process and pass in one of several Python scripts I developed for interacting with the Sense HAT hardware. Popen returns pointer to an open stream, which contains the return value from the Python script. I admit it's a bit of a hack, but it works.
Configure the Raspberry Pi
Now it's time to configure your Raspberry Pi.
- SSH into your Raspberry Pi. Note: I am logged in as the user "pi" and I will save everything to the pi user home directory.
- Run the following commands:
The last command will copy the Sense HAT Python scripts from GitHub to the /home/pi/SenseHatPnP/python_scripts/ folder.
Note: The Python script paths are hard coded in the SenseHatModel_impl.c file. It expects them to be saved under /home/pi/SenseHATPnP/python_scripts/. If you use another location, please update SenseHatModel_impl.c accordingly.
Build the code
The final step is to build your code on the Raspberry Pi device.
Follow the Ubuntu instructions in the Readme.md file in the sensehat_app folder, substituting the following:
- The Readme.md references a azure-iot-sdk-c-pnp folder. This is incorrect. It is azure-iot-sdk-c.
- Open a cmd prompt in your working folder on your PC.
- Use scp to copy the sensehat_app folder from your PC to the azure-iot-sdk-c folder on you Pi device.
Run the remaining build steps contained in the Readme.md. Ignore warnings but fix any errors encountered during the build process.
Running the code
Running your code involves executing the sensehat_app.
After executing the above commands the sensehat_app should be running and sending telemetry to Azure IoT Hub. During startup, watch how it logs the registration of its PnP interfaces with IoT Hub.
Using Device Explorer, you will see messages arriving at your IoT Hub that resemble:
The above shows that Plug and Play information is passed between the device and IoT Hub using message properties.
Plug and Play testing with IoT explorer
IoT explorer is a new tool that allows you to test Plug and Play interfaces as well as view the telemetry being received by IoT Hub from the device. Think of it as Device Explorer with Plug and Play support.
- Download and install IoT explorer on you PC.
- Launch IoT explorer and connect to your IoT Hub using the connection string.
- Select Settings in the top right corner.
- Under "We'll look for your model definition in the following locations (in order)" click New and add the connection string to your Company model repository from the Azure Certified for IoT repository If you've published your device model to the Public repository, you can skip this step.
- Select Save and close Settings.
- Select your Plug and Play device and select Device Twin.
Notice how the device information is now available from the IoT Hub device twin!
Under Digital Twin, expand urn:sense_hat:SenseHat:1 and select Commands. Send a message to the LED on the Sense HAT.
To view the telemetry from the Sense HAT, select Telemetry and click Start.
Congratulations! You have successfully Plug and Play-enabled your Sense HAT device. But wait, that's not all!
IoT Central
IoT Central has preview support for Plug and Play as well! In my next blog post I will show you how to connect the Sense HAT to IoT Central using Plug and Play.
Conclusion
Hopefully this blog post has provided you the details needed to get your device working with Plug and Play and helps you avoid some of the pitfalls I ran into. I would also love to hear your feedback on what you like (and don't like) about Plug and Play.
Cheers,
Kevin
Twitter: @khilscher
LinkedIn: https://www.linkedin.com/in/kevinhilscher
References
- Code samples https://github.com/khilscher/SenseHATPnP
- Deep Dive: Build Solutions and Certify Devices with IoT Plug and Play https://channel9.msdn.com/Shows/Internet-of-Things-Show/Deep-Dive-IoT-Plug-and-Play
- Sense Hat Overview https://www.raspberrypi.org/products/sense-hat/
- Sense Hat Python Examples https://projects.raspberrypi.org/en/projects/getting-started-with-the-sense-hat
- Sense Hat API https://pythonhosted.org/sense-hat/api/
- DTDL https://github.com/Azure/IoTPlugandPlay/tree/master/DTDL
- Plug and Play Announcement https://azure.microsoft.com/en-ca/blog/iot-plug-and-play-is-now-available-in-preview/
- MXChip Plug and Play Code Sample https://github.com/MXCHIP/IoTDevKit/tree/master/pnp