How to connect an IoT Plug and Play bridge sample running on Linux or Windows to IoT Hub

This article shows you how to build the IoT Plug and Play bridge's sample environmental adapter, connect it to your IoT hub, and use the Azure IoT explorer tool to view the telemetry it sends. The IoT Plug and Play bridge is written in C and includes the Azure IoT device SDK for C. By the end of this tutorial you should be able to run the IoT Plug and Play bridge and see it report telemetry in Azure IoT explorer:

A screenshot showing Azure IoT explorer with a table of reported telemetry (humidity, temperature) from Iot Plug and Play bridge.

Prerequisites

You can run the sample in the article on Windows or Linux. The shell commands in this how-to guide follow the Windows convention for path separators '\', if you're following along on Linux be sure to swap these separators for '/'.

Azure IoT explorer

To interact with the sample device in the second part of this article, you use the Azure IoT explorer tool. Download and install the latest release of Azure IoT explorer for your operating system.

Prepare an IoT hub

You need an Azure IoT hub in your Azure subscription to complete the steps in this article. If you don't have an Azure subscription, create a free account before you begin.

If you're using the Azure CLI locally, first sign in to your Azure subscription using az login. If you're running these commands in the Azure Cloud Shell, you're signed in automatically.

If you're using the Azure CLI locally, the az version should be 2.8.0 or later; the Azure Cloud Shell uses the latest version. Use the az --version command to check the version installed on your machine.

Run the following command to add the Microsoft Azure IoT Extension for Azure CLI to your instance:

az extension add --name azure-iot

If you don't already have an IoT hub to use, run the following commands to create a resource group and a free-tier IoT hub in your subscription. Replace <YourIoTHubName> with a hub name of your choice:

az group create --name my-pnp-resourcegroup \
    --location centralus
az iot hub create --name <YourIoTHubName> \
    --resource-group my-pnp-resourcegroup --sku F1

Run the following command to create the device identity in your IoT hub. Replace the <YourIoTHubName> and <YourDeviceID> placeholders with your own IoT Hub name and a device ID of your choice.

az iot hub device-identity create --hub-name <YourIoTHubName> --device-id <YourDeviceID>

Run the following command to get the IoT Hub connection string for your hub. Make a note of this connection string, you use it later in this article:

az iot hub show-connection-string --hub-name <YourIoTHubName> --output table

Run the following command to get the device connection string for the device you added to the hub. Make a note of this connection string, you use it later in this article:

az iot hub device-identity show-connection-string --hub-name <YourIoTHubName> --device-id <YourDeviceID> --output table

Download and run the bridge

In this article, you have two options to run the bridge. You can:

  • Download a prebuilt executable and run it as described in this section.
  • Download the source code and then build and run the bridge as described in the following section.

To download and run the bridge:

  1. Go to the IoT Plug and Play releases page.

  2. Download the prebuilt executable for your operating system: pnpbridge_bin.exe for Windows, or pnpbridge_bin for Linux.

  3. Download the sample config.json configuration file for the environmental sensor sample. Make sure that the configuration file is in the same folder as the executable.

  4. Edit the config.json file:

    • Add the connection-string value that's the device connection string you made a note of previously.
    • Add the symmetric_key value that's shared access key value from the device connection string.
    • Replace the root_interface_model_id value with dtmi:com:example:PnpBridgeEnvironmentalSensor;1.

    The first section of the config.json file now looks like the following snippet:

    {
      "$schema": "../../../pnpbridge/src/pnpbridge_config_schema.json",
      "pnp_bridge_connection_parameters": {
        "connection_type" : "connection_string",
        "connection_string" : "HostName=youriothub.azure-devices.net;DeviceId=yourdevice;SharedAccessKey=TTrz8fR7ylHKt7DC/e/e2xocCa5VIcq5x9iQKxKFVa8=",
        "root_interface_model_id": "dtmi:com:example:PnpBridgeEnvironmentalSensor;1",
        "auth_parameters": {
            "auth_type": "symmetric_key",
            "symmetric_key": "TTrz8fR7ylHKt7DC/e/e2xocCa5VIcq5x9iQKxKFVa8="
        },
    
  5. Run the executable in you command-line environment. The bridge generates output that looks like:

    c:\temp\temp-bridge>dir
     Volume in drive C is OSDisk
     Volume Serial Number is 38F7-DA4A
    
     Directory of c:\temp\temp-bridge
    
    10/12/2020  12:24    <DIR>          .
    10/12/2020  12:24    <DIR>          ..
    08/12/2020  15:26             1,216 config.json
    10/12/2020  12:21         3,617,280 pnpbridge_bin.exe
                   2 File(s)      3,618,496 bytes
                   2 Dir(s)  12,999,147,520 bytes free
    
    c:\temp\temp-bridge>pnpbridge_bin.exe
    Info:
     -- Press Ctrl+C to stop PnpBridge
    
    Info: Using default configuration location
    Info: Starting Azure PnpBridge
    Info: Pnp Bridge is running as am IoT egde device.
    Info: Pnp Bridge creation succeeded.
    Info: Connection_type is [connection_string]
    Info: Tracing is disabled
    Info: WARNING: SharedAccessKey is included in connection string. Ignoring symmetric_key in config file.
    Info: IoT Edge Device configuration initialized successfully
    Info: Building Pnp Bridge Adapter Manager, Adapters & Components
    Info: Adapter with identity environment-sensor-sample-pnp-adapter does not have any associated global parameters. Proceeding with adapter creation.
    Info: Pnp Adapter with adapter ID environment-sensor-sample-pnp-adapter has been created.
    Info: Pnp Adapter Manager created successfully.
    Info: Pnp components created successfully.
    Info: Pnp components built in model successfully.
    Info: Connected to Azure IoT Hub
    Info: Environmental Sensor: Starting Pnp Component
    Info: IoTHub client call to _SendReportedState succeeded
    Info: Environmental Sensor Adapter:: Sending device information property to IoTHub. propertyName=state, propertyValue=true
    Info: Pnp components started successfully.
    

Build and run the bridge

If you prefer to build the executable yourself, you can download the source code and build scripts.

Open a command prompt in a folder of your choice. Run the following command to clone the IoT Plug and Play bridge GitHub repository into this location:

git clone https://github.com/Azure/iot-plug-and-play-bridge.git

After you clone the repository, update the submodules. The submodules include the Azure IoT SDK for C:

cd iot-plug-and-play-bridge
git submodule update --init --recursive

Expect this operation to take several minutes to complete.

Tip

If you run into issues with the git clone sub module update failing, this is a known issue with Windows file paths. You can try the following command to resolve the issue: git config --system core.longpaths true

The prerequisites for building the bridge differ by operating system:

Windows

To build the IoT Plug and Play bridge on Windows, install the following software:

Linux

This article assumes you're using Ubuntu Linux. The steps in this article were tested using Ubuntu 18.04.

To build the IoT Plug and Play bridge on Linux, install GCC, Git, cmake, and all the required dependencies using the apt-get command:

sudo apt-get update
sudo apt-get install -y git cmake build-essential curl libcurl4-openssl-dev libssl-dev uuid-dev

Verify the version of cmake is above 2.8.12 and the version of GCC is above 4.4.7.

cmake --version
gcc --version

Build the IoT Plug and Play bridge

Navigate to the pnpbridge folder in the repository directory.

For Windows run the following in a Developer Command Prompt for Visual Studio:

cd scripts\windows
build.cmd

Similarly for Linux run the following:

cd scripts/linux
./setup.sh
./build.sh

Tip

On Windows, you can open the solution generated by the cmake command in Visual Studio 2019. Open the azure_iot_pnp_bridge.sln project file in the cmake directory and set the pnpbridge_bin project as the startup project in the solution. You can now build the sample in Visual Studio and run it in debug mode.

Edit the configuration file

You can learn more about config files in the IoT Plug and Play bridge concepts document.

Open the the iot-plug-and-play-bridge\pnpbridge\src\adapters\samples\environmental_sensor\config.json file in a text editor.

  • Add the connection-string value that's the device connection string you made a note of previously.
  • Add the symmetric_key value that's shared access key value from the device connection string.
  • Replace the root_interface_model_id value with dtmi:com:example:PnpBridgeEnvironmentalSensor;1.

The first section of the config.json file now looks like the following snippet:

{
  "$schema": "../../../pnpbridge/src/pnpbridge_config_schema.json",
  "pnp_bridge_connection_parameters": {
    "connection_type" : "connection_string",
    "connection_string" : "HostName=youriothub.azure-devices.net;DeviceId=yourdevice;SharedAccessKey=TTrz8fR7ylHKt7DC/e/e2xocCa5VIcq5x9iQKxKFVa8=",
    "root_interface_model_id": "dtmi:com:example:PnpBridgeEnvironmentalSensor;1",
    "auth_parameters": {
        "auth_type": "symmetric_key",
        "symmetric_key": "TTrz8fR7ylHKt7DC/e/e2xocCa5VIcq5x9iQKxKFVa8="
    },

Run the IoT Plug and Play bridge

Start the IoT Plug and Play bridge environmental sensor sample. The parameter is the path to config.json file you edited in the previous section:

REM Windows
cd iot-plug-and-play-bridge\pnpbridge\cmake\pnpbridge_x86\src\pnpbridge\samples\console
Debug\pnpbridge_bin.exe ..\..\..\..\..\..\src\adapters\samples\environmental_sensor\config.json

The bridge generates output that looks like:

c:\temp>cd iot-plug-and-play-bridge\pnpbridge\cmake\pnpbridge_x86\src\pnpbridge\samples\console

c:\temp\iot-plug-and-play-bridge\pnpbridge\cmake\pnpbridge_x86\src\pnpbridge\samples\console>Debug\pnpbridge_bin.exe ..\..\..\..\..\..\src\adapters\samples\environmental_sensor\config.json
Info:
 -- Press Ctrl+C to stop PnpBridge

Info: Using configuration from specified file path: ..\..\..\..\..\..\src\adapters\samples\environmental_sensor\config.json
Info: Starting Azure PnpBridge
Info: Pnp Bridge is running as am IoT egde device.
Info: Pnp Bridge creation succeeded.
Info: Connection_type is [connection_string]
Info: Tracing is disabled
Info: WARNING: SharedAccessKey is included in connection string. Ignoring symmetric_key in config file.
Info: IoT Edge Device configuration initialized successfully
Info: Building Pnp Bridge Adapter Manager, Adapters & Components
Info: Adapter with identity environment-sensor-sample-pnp-adapter does not have any associated global parameters. Proceeding with adapter creation.
Info: Pnp Adapter with adapter ID environment-sensor-sample-pnp-adapter has been created.
Info: Pnp Adapter Manager created successfully.
Info: Pnp components created successfully.
Info: Pnp components built in model successfully.
Info: Connected to Azure IoT Hub
Info: Environmental Sensor: Starting Pnp Component
Info: IoTHub client call to _SendReportedState succeeded
Info: Environmental Sensor Adapter:: Sending device information property to IoTHub. propertyName=state, propertyValue=true
Info: Pnp components started successfully.
Info: IoTHub client call to _SendEventAsync succeeded
Info: PnpBridge_PnpBridgeStateTelemetryCallback called, result=0, telemetry=PnpBridge configuration complete
Info: Processing property update for the device or module twin
Info: Environmental Sensor Adapter:: Successfully delivered telemetry message for <environmentalSensor>

Use the following commands to run the bridge on Linux:

cd iot-plug-and-play-bridge/pnpbridge/cmake/pnpbridge_x86/src/pnpbridge/samples/console
./pnpbridge_bin ../../../../../../src/adapters/samples/environmental_sensor/config.json

Download the model files

You use Azure IoT Explorer later to view the device when it connects to your IoT hub. Azure IoT Explorer needs a local copy of the model file that matches the Model ID your device sends. The model file lets the IoT Explorer display the telemetry, properties, and commands that your device implements.

To download the models for Azure IoT explorer:

  1. Create a folder called models on your local machine.
  2. Save EnvironmentalSensor.json to the models folder you created in the previous step.
  3. If you open this model file in a text editor, you can see the the model defines a component with dtmi:com:example:PnpBridgeEnvironmentalSensor;1 as its ID. This is the same model ID you used in the config.json file.

Use Azure IoT explorer to validate the code

After the bridge starts, use the Azure IoT explorer tool to verify it's working. You can see the telemetry, properties, and commands defined in the dtmi:com:example:PnpBridgeEnvironmentalSensor;1 model.

  1. Open Azure IoT explorer.

  2. On the IoT hubs page, if you haven't already added a connection to your IoT hub, select + Add connection. Enter the connection string for the IoT hub you created previously and select Save.

  3. On the IoT Plug and Play Settings page, select + Add > Local folder and select the local models folder where you saved your model files.

  4. On the IoT hubs page, click on the name of the hub you want to work with. You see a list of devices registered to the IoT hub.

  5. Click on the Device ID of the device you created previously.

  6. The menu on the left shows the different types of information available for the device.

  7. Select IoT Plug and Play components to view the model information for your device.

  8. You can view the different components of the device. The default component and any additional ones. Select a component to work with.

  9. Select the Telemetry page and then select Start to view the telemetry data the device is sending for this component.

  10. Select the Properties (read-only) page to view the read-only properties reported for this component.

  11. Select the Properties (writable) page to view the writable properties you can update for this component.

  12. Select a property by it's name, enter a new value for it, and select Update desired value.

  13. To see the new value show up select the Refresh button.

  14. Select the Commands page to view all the commands for this component.

  15. Select the command you want to test set the parameter if any. Select Send command to call the command on the device. You can see your device respond to the command in the command prompt window where the sample code is running.

Clean up resources

If you plan to continue with additional IoT Plug and Play articles, you can keep and reuse the resources you used in this article. Otherwise, you can delete the resources you created in this article to avoid additional charges.

You can delete both the hub and registered device at once by deleting the entire resource group with the following Azure CLI command. Don't use this command if these resources are sharing a resource group with other resources you want to keep.

az group delete --name <YourResourceGroupName>

To delete just the IoT hub, run the following command using Azure CLI:

az iot hub delete --name <YourIoTHubName>

To delete just the device identity you registered with your IoT hub, run the following command using Azure CLI:

az iot hub device-identity delete --hub-name <YourIoTHubName> --device-id <YourDeviceID>

You may also want to remove the cloned sample files from your development machine.

Next steps

In this article, you've learned how to connect an IoT Plug and Play device to an IoT hub. To learn more about how to build a solution that interacts with your IoT Plug and Play devices, see: