logo
Menu

Build a Real-Time Asset Tracking Application with Amazon Location Service

This web app will display an Amazon Location Service tracker's position ingested via MQTT.

Zach Elliott
Amazon Employee
Published Jun 20, 2024

Introduction

Asset tracking is critical to supply chain operations. Whether it is tracking trucks across the country or last mile deliveries around a neighborhood, knowing where your fleet is located can add business value around loss prevention, sustainability, and overall cost savings. In this tutorial, we will deploy a simple web application that shows current locations of assets, as well as historical location. We'll then use AWS IoT Core to simulate a vehicle, making use of the MQTT protocol, a lightweight messaging protocol designed for IoT use cases. This tutorial walks through setting up the Guidance for Tracking Assets & Locating Devices Using AWS IoT and how to deploy an easy to use asset tracking application.

Architecture

Architecture Diagram
Architecture Diagram
This diagram shows an overview of the solution we will be building.

Installing the Application

To install the application, we will be utilizing AWS Cloud9. However you are welcome to use any IDE or Development environment that meets the requirements described here.
First, clone the application repo, including submodules:
1
git clone https://github.com/aws-solutions-library-samples/guidance-for-tracking-assets-and-locating-devices-using-aws-iot.git --recurse-submodules
Next, navigate to the application directory:
1
cd guidance-for-tracking-assets-and-locating-devices-using-aws-iot/
Next, we need to install the visualization components. Navigate to the amazon-location-samples-react/tracking-data-streaming directory and run npm install
1
cd amazon-location-samples-react/tracking-data-streaming && npm install
Once the packages are installed, we need to install some infrastructure including Amazon Location Service Tracker and Geofence resources. From the amazon-location-samples-react/tracking-data-streamingdirectory, run the following, replacing <your region> with your AWS region:
1
chmod +x deploy_cloudformation.sh && export AWS_REGION=<your region> && ./deploy_cloudformation.sh
A successful deployment will look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Deploying kinesis data stream template for sample app.

Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - TrackingAndGeofencingSampleKinesisStack
Retrieving TrackingAndGeofencingSampleKinesisDataStreamARN from the created CloudFormation stack.
Creating changeset kinesis-stream-device-data-to-location-tracker Serverless Application with kinesis data stream: arn:aws:kinesis:us-east-1:1234567891012:stream/TrackingAndGeofencingSampleKinesisDataStream.
Resource RESOURCECHANGE Add LocationTracker AWS::Location::Tracker Resource RESOURCECHANGE Add TrackingDataConsumerLambdaFunctionKinesisEvent AWS::Lambda::EventSourceMapping Resource RESOURCECHANGE Add TrackingDataConsumerLambdaFunctionRole AWS::IAM::Role Resource RESOURCECHANGE Add TrackingDataConsumerLambdaFunction AWS::Lambda::Function
Executing change set: arn:aws:cloudformation:us-east-1:1234567891012:changeSet/kinesis-stream-device-data-to-location-tracker-change-set/1eb00921-967b-482a-a218-02fa9598102a
Attempt 1 of 5: Executing change set arn:aws:cloudformation:us-east-1:1234567891012:changeSet/kinesis-stream-device-data-to-location-tracker-change-set/1eb00921-967b-482a-a218-02fa9598102a
Change set executed successfully: arn:aws:cloudformation:us-east-1:1234567891012:changeSet/kinesis-stream-device-data-to-location-tracker-change-set/1eb00921-967b-482a-a218-02fa9598102a. You can go to CloudFormation's console to monitor the deployment progress.
Deploying cloudformation template for sample app using TrackerName: SampleTracker and region: us-east-1.

Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - TrackingAndGeofencingSample
All deployments complete!

Configuring IoT Resources

Now that we have our base infrastructure setup, we can deploy the IoT Resources. This includes a rules engine action to update Location Service with a Lambda Function, as well as associated IAM permissions.
Navigate to guidance-for-asset-tracking-using-aws-iot-core-and-amazon-location-services/cf and run the following command:
1
aws cloudformation create-stack --stack-name TrackingAndGeofencingIoTResources --template-body file://iotResources.yml --capabilities CAPABILITY_IAM
Get the status of the stack deployment by running the following command:
1
aws cloudformation describe-stacks --stack-name TrackingAndGeofencingIoTResources
A successful deployment will look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"Stacks": [
{
"StackId": "arn:aws:cloudformation:us-east-1:1234567891012:stack/TrackingAndGeofencingIoTResources/856b3280-2f32-11ef-8e5a-0affc5f60061",
"StackName": "TrackingAndGeofencingIoTResources",
"Description": "A Template to provision AWS IoT Core Resources for the Amazon Location Live Device Tracking and Geofencing sample app.",
"Parameters": [
{
"ParameterKey": "TrackerName",
"ParameterValue": "SampleTracker"
}
],
"CreationTime": "2024-06-20T18:25:50.569000+00:00",
"RollbackConfiguration": {},
"StackStatus": "CREATE_COMPLETE",
"DisableRollback": false,
"NotificationARNs": [],
"Capabilities": [
"CAPABILITY_IAM"
],
"Tags": [],
"EnableTerminationProtection": false,
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
}
}
]
}

Configuring Visualization

Now that we have set up our IoT Ingestion, we can move onto the frontend application.
Navigate to guidance-for-asset-tracking-using-aws-iot-core-and-amazon-location-services/amazon-location-samples-react/tracking-data-streaming/src and open the configuration.js file in a text editor of your choice.
Run the following commands in the terminal to get the Cloudformation Stack Outputs
1
aws cloudformation describe-stacks --stack-name TrackingAndGeofencingSample --query "Stacks[0].Outputs[*].[OutputKey, OutputValue]"
Which will produce output similar to this:
1
2
3
4
5
6
7
8
9
10
[
[
"TrackingAndGeofencingSampleReadOnlyCognitoPoolId",
"us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
],
[
"TrackingAndGeofencingSampleWriteOnlyCognitoPoolId",
"us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
]
]
Set the values in configuration.js to match the values from CloudFormation, as well as your AWS Region. Final configuration should look similar to this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT-0

// This configuration file is a single place to provide any values to set up the app

export const READ_ONLY_IDENTITY_POOL_ID= "us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; // REQUIRED - Amazon Cognito id for readonly role
export const WRITE_ONLY_IDENTITY_POOL_ID= "us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; // REQUIRED - Amazon Cognito id for writeonly role
export const REGION = "us-east-1"; // REQUIRED - Amazon Cognito Region

export const MAP = {
NAME: "TrackingAndGeofencingSampleMapHere", // REQUIRED - Amazon Location Service map resource name
STYLE: "VectorHereExplore", // REQUIRED - String representing the style of map resource
};

export const GEOFENCE = "TrackingAndGeofencingSampleCollection"; // REQUIRED - Amazon Location Service geofence collection resource name

export const TRACKER = "SampleTracker"; // REQUIRED - Amazon Location Service tracker resource name

export const DEVICE_POSITION_HISTORY_OFFSET = 3600; // REQUIRED - Relative time range of Device Position History to display in seconds. Default to 1 hour.

export const KINESIS_DATA_STREAM_NAME = "TrackingAndGeofencingSampleKinesisDataStream"; // REQUIRED for running the demo - defined in ./cfn_template/kinesisResources.yml
Save the configuration.js file.
In the terminal, ensure you are in the guidance-for-asset-tracking-using-aws-iot-core-and-amazon-location-services/amazon-location-samples-react/tracking-data-streaming directory, and run npm start to start the local web server.
Navigate to localhost:8080 in your browser, or Preview running application if using AWS Cloud9 and verify the map is loading.
Map Preview Loading
Map Preview

Viewing IoT Positions on the Map

Now that our map is deployed. We can view positions of IoT Devices on it. In order to do this, we will simulate an IoT Device, using the MQTT test client in the AWS IoT Core console.
Navigate to the AWS IoT Core console, and select MQTT test client on the left side.
Select the Publish to a topic tab, and enter the topic locationand for the Message payload enter the following, with the timestamp set to the current Epoch time.
1
2
3
4
5
6
7
8
{
"payload": {
"deviceid": "Vehicle-1",
"timestamp": <CurrentTimeStamp>,
"location": { "lat": 47.54372304079714, "long": -122.32275832917712 },
"accuracy": { "Horizontal": 20.5 }
}
}
Select Publish.
Now navigate back to your map preview, and you should see a Vehicle-1 that is set to the location we sent via the MQTT message.
Map Preview showing device locations
Map Preview showing device locations
Feel free to send more location updates with updated timestamps to the same topic, and watch the location move on the map. You can also select View History to view past locations for each device on the map.
To view more devices on the map, simply change the deviceid in the MQTT message. This simulates multiple devices uploading positions to MQTT and AWS IoT Core.

Hosting Application in CloudFront

Having our application running locally is great, but having it hosted and accessible from anywhere would be even better. In order to do this, we will upload our completed application to an S3 bucket, then host it with Amazon CloudFront.

Creating Bucket

First, we'll create our bucket. We'll do this via the console, but you are welcome to create it via the CLI.
First, navigate to S3 and select Create bucket
Now select a name for the bucket. Note these names need to be unique and follow bucket naming rules. Leave all other options as default, and select Create bucket.

Building and uploading application files

Now, back in our Cloud9 or local development instance, we need to build the application for hosting. In the terminal, navigate to guidance-for-tracking-assets-and-locating-devices-using-aws-iot/amazon-location-samples-react/tracking-data-streaming and run npm run build. A successful build will look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ npm run build

>
amazon-location-position-data-streaming-sample-app@1.0.0 build
> vite build

vite v4.5.3 building for production...
✓ 2200 modules transformed.
build/index.html 0.83 kB │ gzip: 0.49 kB
build/assets/index-1209c093.css 629.23 kB │ gzip: 184.71 kB
build/assets/__vite-optional-peer-dep_mapbox-gl_react-map-gl-b25bb000.js 0.03 kB │ gzip: 0.05 kB
build/assets/loadCognitoIdentity-b884bda7.js 16.71 kB │ gzip: 4.86 kB
build/assets/index-475155f1.js 738.73 kB │ gzip: 216.60 kB
build/assets/maplibre-gl-0af3d37b.js 762.39 kB │ gzip: 208.21 kB

(!) Some chunks are larger than 500 kBs after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
✓ built in 20.86s
Now we need to push these files up to our Amazon S3 bucket we just created. Navigate to guidance-for-tracking-assets-and-locating-devices-using-aws-iot/amazon-location-samples-react/tracking-data-streaming/build and run the following command:
1
aws s3 cp . s3://<BucketName>/ --recursive
Now our files are in S3, but they still can't be accessed quite yet. We need to deploy a CloudFront distribution in front of the bucket.

Deploying CloudFront distribution

In the AWS console, navigate to CloudFront and select Create distribution.
For Origin domain, select the S3 bucket we created.
For Origin access, select Origin access control settings (recommended) and then Create new OAC. Select the defaults and select Create.
Cloudfront Distribution Configuration
Cloudfront Distribution Configuration
Leave all other options as default, and select Enable security protections in the Web Application Firewall (WAF) settings. Select Create distribution. It will take some time to create, and while we are doing that, we can update our Bucket Policy.
Navigate to our new Distribution and select the Origins tab. Select the radio button next to our S3 bucket origin, and select Edit. You will see an info box similar to this one, prompting you to update your S3 bucket policy. Select Copy policy and then select Go to S3 bucket permissions.
S3 Bucket Policy Info Box
S3 Bucket Policy Info Box
On the Permissions tab, scroll down to Bucket policy and select Edit.
Paste in the bucket policy you copied in the previous step. It should look like this:
Bucket Policy for Cloudfront
Bucket Policy for Cloudfront
Select Save changes.

Viewing Application via CloudFront

Now that our CloudFront distribution has deployed, we can view our application anywhere. Navigate back to the CloudFront console. In the Details section, you will find the Distribution domain name. Copy that and paste it into your web browser, adding /index.htmlto the end.
Map via Cloudfront
CloudFront hosted Application

From here, you can perform the same IoT updates via the MQTT Test Client as before, and view your assets on the map.

Next Steps

Now that we have a simple asset tracking application deployed, we can expand past the simulations and dive into tracking using real IoT Devices connected to AWS IoT Core. The AWS Partner Solutions Finder maintains a list of Asset Tracking devices that are certified to work with AWS IoT Core.

Conclusion

In this blog, we have walked through the steps required to set up a simple Asset Tracking solution using AWS IoT Core and Amazon Location Service. This application can be used with many devices to show their current location, as well as interactions with geofences. We encourage you to set this application up for yourself, as well as make customizations that are applicable to your business case and asset tracking needs.
 

Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.

Comments