Skip to content

Latest commit

 

History

History
394 lines (276 loc) · 17.4 KB

README.md

File metadata and controls

394 lines (276 loc) · 17.4 KB

IoT - Asset Tracking with Leaflet and ArcGIS

In this Code Pattern composite, we'll demonstrate how to track assets and visualize incoming sensor data from the Watson IoT Platform on a mapping application using Leaflet.js and ArcGIS. This is a continuation of the "Smart City" code pattern composite. This application targets two primary use cases:

The first use case is tracking moving IoT assets. This can be anything that has a GPS module attached, whether that be a shipping truck, a tagged wild animal, etc.

The second use case is to visualize sensor data associated with various connected IoT devices. This sensor data can represent any measurable physical property, such as temperature, sound, air quality, humidity, etc.

"d" : {
  "node_id": "asset1",
  "lat": "-118.417392",
  "long": "34.0057",
  "timestamp": "2018-06-30T07:10:55.174Z",
  "sensor": {
    "sound": "72",
  }
}

Application Workflow Diagram

Workflow

  1. User registers an "end node" via the mapping UI or a MQTT message. This end node represents a trackable asset capable of publishing location and sensor data.

  2. Express backend subscribes to Watson IoT Platform channel corresponding to one or more end nodes.

  3. End Node continuously publishes JSON object containing location, time, and sensor data to Watson IoT Platform

{
  d: {
    node_id: "asset1",
    longitude: "-118.417392",
    latitude: "34.100057",
    timestamp: "2018-06-30T07:10:55.174Z",
    sensor: {
      sound: "72"
    }
  }
}
  1. Message persists in Cloudant DB

  2. Front end (Leaflet.js) updates marker location on map

Install Prerequisites:

Node.js packages

If expecting to run this application locally, please continue by installing Node.js runtime and NPM. If your system requires multiple versions of Node for other projects, we'd suggest using nvm to easily switch between Node versions. NVM can be installed with the following commands

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
# Place next three lines in ~/.bash_profile
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
nvm install v8.9.0
nvm use 8.9.0

To run the UI locally, we'll need to install a few node libraries which are listed in our package.json file.

  • Leaflet.js: Open source library for interactive mapping
  • MQTT: Client package to subscribe to Watson IoT Platform and handle incoming messages

Install the listed node packages by running npm install in the project root directory.

npm install

Start the application with

node app.js

Included components

Prerequisites

Steps

There are two methods we can use to deploy the application, either use the Deploy to IBM Cloud steps OR create the services and run locally.

  1. Clone repository
  2. Setup repository codebase locally OR Deploy to IBM Cloud
  3. Create Watson services with IBM Cloud
  4. Retrieve service credentials
  5. Configure and run the application
  6. Visualize assets in UI

1. Clone the repository

Clone the iot-mapping project locally. In a terminal, run:

git clone github.com/IBM/iot-mapping

2. Deploy Application to IBM Cloud

  1. To deploy the application to IBM Cloud, we'll need to leverage the IBM Cloud CLI. Ensure the cli is installed using the prerequisites section above, and then run the following command to deploy the application
ibmcloud cf push
  1. To see the app and services created and configured for this Code Pattern, use the IBM Cloud dashboard, or run ibmcloud cf apps and ibmcloud cf services in the terminal. The app should be named iot-mapping with a unique suffix.

2. Deploy Application locally

Install the IoT Mapping node packages by running npm install in the project root directory.

npm install

Start the application with

npm start

NOTE: These steps are only needed when running locally instead of using the Deploy to IBM Cloud button.

3. Create Services

Next, we'll need to deploy our service instances using the IBM Cloud dashboard.

Watson IoT Platform

Navigate to the IBM Cloud dashboard at https://console.bluemix.net/ and click the "Catalog" button in the upper right

In the search bar type "IoT" and click the icon titled "Internet of Things Platform Starter".

Select the pricing plan and click "Create". If deploying on an IBM Lite account, be sure to select the free "Lite" plan

Additional Configuration: Generate Watson IoT service credentials

After being provisioned, the Watson IoT Platform service will need a bit of additional configuration, as we'll need to generate a set of credentials for connecting to the broker. We can do so by entering the IoT Platform dashboard, selecting "Devices" from the left hand menu, and then clicking the "Add Device" button.

Next, provide a device type and ID.

The next few tabs (Device Information, Groups, Security) can be left as is with the default settings.

Clicking the "Finish" button will register a device and generate a set of credentials that can be used to publish messages to the IoT Platform. Be sure to take note of the Device type and Device ID, and place both in the cfcreds.env file.

We'll need to generate a different set of credentials to be able to publish and subscribe to the MQTT Broker

We can do so by selecting the "Apps" option in the left hand menu. Then, click the "Generate API Key" button

We can leave the fields in the "Information" blank and click next. In the "Permissions" tab, we'll select the "Backend Trusted Application" role. Once this is selected, click "Generate Key"

The result will give us an API Key and Authentication Token. These can be supplied as the username and password for a MQTT client. To make setup a bit easier, place these values in the cfcreds.env file as IOT_API_KEY and IOT_APP_AUTH_TOKEN

4. Obtain service credentials

Now that we've instantiated our Watson IoT Platform service instance and the corresponding MQTT credentials, we'll next need to place the credentials into a .env file in our application root directory. This will allow for the application to authenticate to the MQTT broker and listen for updates from registered IoT devices.

IOT_API_KEY=
IOT_AUTH_TOKEN=
IOT_ORG_ID=
IOT_DEVICE_ID=
IOT_DEVICE_TYPE=
IOT_EVENT=

5. Run the application

  1. Start the app locally with node app.js.

  2. Enter the following URL in a browser: http://localhost:3000/
    Note: If you run into an issue with the port already being used, set the PORT environment variable to the port you'd like to use.

6. Visualize assets in UI

Now, we can actually confirm that the UI is able to visualize asset locations and sensor data.

There are a few ways to import data to be viewed in the mapping application.

Each option requires the following

  • A unique string identifier, corresponding to the specific IoT device.
  • A set of Longitude/Latitude coordinates
  • A timestamp, which should be represented as either the UTC epoch format or the ISO-8601 format.
  • Sensor value(s) in a key/value format, ex. sound: 65 (Optional)

The first option is to create a node manually. This can be done by clicking the "Add Node" button and entering the required values. Once they have been entered, pressing "Create" should render a marker like so. A transparent circle will also be added if a sensor is provided, and the radius length is determined by the sensor value

In a live scenario, these updates should come in the form of MQTT messages sent by associated IoT devices. Each device can broadcast an update by publishing a MQTT message with the following payload:

mqtt_pub -v -i "a:${IOT_ORG_ID}:client_pub1" -u "${IOT_API_KEY}" -P "${IOT_AUTH_TOKEN}" -h 'agf5n9.messaging.internetofthings.ibmcloud.com' -p 1883 -t "iot-2/type/${IOT_DEVICE_TYPE}/id/${IOT_DEVICE_ID}/evt/assetMapper/fmt/json" -m '{
    "d" : {
    "node_id": "node2",
    "lat": "-118.317392",
    "long": "34.100057",
    "timestamp": "2018-06-30T07:10:55.174Z",
    "sensor": {
      "sound": "72"
    }
  }
}'

We can also bulk import CSV datasets. In this example, we'll use data from tracking a herd of zebra in Botswana, which can be downloaded here. This file can be loaded by clicking the "Import CSV File" button.

Once the file is loaded, headers will need to be selected to identify which columns correspond to each individual node id, location, and timestamp. This can be done by manually inspecting the file

Next, select the headers in the "Select Dataset Columns" form

Once the columns have been selected, markers for each node id should be visible like so.

We can also click the "Show all paths" button to draw the path traversed by each asset.

If there are multiple datapoints associated with an asset, we can use a "range slider" to trace back and view an assets path. As the slider is adjusted, each marker should update their location and sensor identifier. Also, the corresponding timestamp should be shown in the bottom right corner of the map.

Now, we can actually confirm that the UI is able to visualize asset locations and sensor data.

There are a few ways to import data to be viewed in the mapping application.

Each option requires the following

  • A unique string identifier, corresponding to the specific IoT device.
  • A set of Longitude/Latitude coordinates
  • A timestamp, which should be represented as either the UTC epoch format or the ISO-8601 format.
  • Sensor value(s) in a key/value format, ex. sound: 65 (Optional)

The first option is to create a node manually. This can be done by clicking the "Add Node" button and entering the required values. Once they have been entered, pressing "Create" should render a marker like so. A transparent circle will also be added if a sensor is provided, and the radius length is determined by the sensor value

In a live scenario, these updates should come in the form of MQTT messages sent by associated IoT devices. Each device can broadcast an update by publishing a MQTT message with the following payload:

mqtt_pub -v -i "a:${IOT_ORG_ID}:client_pub1" -u "${IOT_API_KEY}" -P "${IOT_AUTH_TOKEN}" -h 'agf5n9.messaging.internetofthings.ibmcloud.com' -p 1883 -t "iot-2/type/${IOT_DEVICE_TYPE}/id/${IOT_DEVICE_ID}/evt/assetMapper/fmt/json" -m '{
    "d" : {
    "node_id": "node2",
    "lat": "-118.317392",
    "long": "34.100057",
    "timestamp": "2018-06-30T07:10:55.174Z",
    "sensor": {
      "sound": "72"
    }
  }
}'

We can also bulk import CSV datasets. In this example, we'll use data from tracking a herd of zebra in Botswana, which can be downloaded here. This file can be loaded by clicking the "Import CSV File" button.

Links

Once the file is loaded, headers will need to be selected to identify which columns correspond to each individual node id, location, and timestamp. This can be done by manually inspecting the file

Next, select the headers in the "Select Dataset Columns" form

Once the columns have been selected, markers for each node id should be visible like so.

We can also click the "Show all paths" button to draw the path traversed by each asset.

If there are multiple datapoints associated with an asset, we can use a "range slider" to trace back and view an assets path. As the slider is adjusted, each marker should update their location and sensor identifier. Also, the corresponding timestamp should be shown in the bottom right corner of the map.

Troubleshooting

License

This code pattern is licensed under the Apache Software License, Version 2. Separate third party code objects invoked within this code pattern are licensed by their respective providers pursuant to their own separate licenses. Contributions are subject to the Developer Certificate of Origin, Version 1.1 (DCO) and the Apache Software License, Version 2.

Apache Software License (ASL) FAQ