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 Jul 31, 2023
Last Modified Mar 13, 2024
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 an asset's current location, 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. We will cover how to:

Prerequisites

Before starting this tutorial, you will need the following:
About
โœ… AWS Level200 - Intermediate
โฑ Time to complete45 minutes
๐Ÿ’ฐ Cost to completeFree tier eligible
๐Ÿงฉ Prerequisites- AWS Account
๐Ÿ’ป Code SampleCode sample used in tutorial on GitHub
๐Ÿ“ข FeedbackAny feedback, issues, or just a ๐Ÿ‘ / ๐Ÿ‘Ž ?
โฐ Last Updated2023-05-10

Deploy a Cloud9 Instance

To deploy our asset tracking app, we will be using AWS Cloud9. Cloud9 is a cloud-based IDE that lets you write, run, and debug your code with just a browser. Using Cloud9 makes it easy to build and deploy applications while reducing the need for local development on builder workstations. Cloud9 also comes bundled with many AWS builder tools to get started developing quickly.
Navigate to the AWS Console and select Cloud9. Next select Create environment.
AWS Console showing how to create an environment
Set the instance type to t3.small and provide a name. Select Create.
AWS Cloud9 Console showing deployment options
Once the Cloud9 instance has launched, we can begin deploying our app.

Deploy the Tracking App

Now that the Cloud9 instance has been launched, we can download the code to build our application. From your Cloud9 terminal, clone the repo:
1
git clone https://github.com/aws-samples/amazon-location-samples.git
Next, navigate to the app directory:
1
cd amazon-location-samples/maplibre-js-react-iot-asset-tracking/
Install our dependencies:
1
npm install
In order to configure Amplify, we need to set up an AWS Profile on the Cloud9 instance. To do this, enter the following command, making sure to replace the region with the region you are running the lab in. For example, for us-east-1:
1
echo $'[profile default]\nregion=us-east-1' > ~/.aws/config
Next we need to ensure Amplify is installed:
1
npm install -g @aws-amplify/cli
Now we can initialize our Amplify environment:
1
amplify init
Accept the default options.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project maplibrejsreactiotas
The following configuration will be applied:

Project information
| Name: maplibrejsreactiotas
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: react
| Source Directory Path: src
| Distribution Directory Path: build
| Build Command: npm run-script build
| Start Command: npm run-script start

? Initialize the project with the above configuration? Yes
Using default provider awscloudformation
? Select the authentication method you want to use: AWS profile

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html

? Please choose the profile you want to use default
Successful Amplify Init
Now we can use AWS Amplify to add our Amazon Location Service resources:
1
amplify add geo
And select the following options. Note we change the map data provider due to Terms of Service that require us to use the HERE data provider for asset tracking use cases. Also make sure to select Authorized and Guest users when choosing who can access the map. If your app has authentication such as a login portal, you can choose that only authorized users can view the map resource. However for our application, we do not have a login, so unauthenticated users can access the map.
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
29
30
? Select which capability you want to add: Map (visualize the geospatial data)
โœ” geo category resources require auth (Amazon Cognito). Do you want to add auth now? (Y/n) ยท yes
Using service: Cognito, provided by: awscloudformation

The current configured provider is Amazon Cognito.

Do you want to use the default authentication and security configuration? Default configuration
Warning: you will not be able to edit these selections.
How do you want users to be able to sign in? Username
Do you want to configure advanced settings? No, I am done.
โœ… Successfully added auth resource maplibrejsreactiotase08797a2 locally

โœ… Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud

โœ” Provide a name for the Map: ยท mapiottracker
โœ” Who can access this Map? ยท Authorized and Guest users
Available advanced settings:
- Map style & Map data provider (default: Streets provided by Esri)

โœ” Do you want to configure advanced settings? (y/N) ยท yes
โœ” Specify the map style. Refer https://docs.aws.amazon.com/location-maps/latest/APIReference/API_MapConfiguration.html ยท Explore (data provided by HERE)
โš ๏ธ Auth configuration is required to allow unauthenticated users, but it is not configured properly.
โœ… Successfully updated auth resource locally.
โœ… Successfully added resource mapiottracker locally.

โœ… Next steps:
"amplify push" builds all of your local backend resources and provisions them in the cloud
"amplify publish" builds all of your local backend and front-end resources (if you added hosting category) and provisions them in the cloud
Successful Amplify Init
Before we push our Amplify configuration, we need to make one small change to allow our application to work with Amazon Location Service Trackers.
1
amplify override project
Successful Amplify Override
Now navigate to the amplify/backend/awscloudformation/override.ts file that was just created, and replace the contents with the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { AmplifyRootStackTemplate } from "@aws-amplify/cli-extensibility-helper";

export function override(resources: AmplifyRootStackTemplate) {
resources.unauthRole.addOverride("Properties.Policies", [
{
PolicyName: "trackerPolicy",
PolicyDocument: {
Version: "2012-10-17",
Statement: [
{
Effect: "Allow",
Action: ["geo:GetDevicePositionHistory"],
Resource: {
"Fn::Sub":
"arn:aws:geo:${AWS::Region}:${AWS::AccountId}:tracker/trackerAsset01",
},
},
],
},
},
]);
}
This will update the policy used by Amazon Cognito to display the tracker position on the map.
Configuring the Amplify Override
Save the override.ts file and now we can push our Amplify configuration and create our resources in the cloud.
1
amplify push
Select y for the options presented here:
1
2
3
4
5
6
7
8
9
10
11
12
โœ” Successfully pulled backend environment dev from the cloud.

Current Environment: dev

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Category โ”‚ Resource name โ”‚ Operation โ”‚ Provider plugin โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Auth โ”‚ maplibrejsreactiotas543a61f5 โ”‚ Create โ”‚ awscloudformation โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Geo โ”‚ mapiottracker โ”‚ Create โ”‚ awscloudformation โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โœ” Are you sure you want to continue? (Y/n) ยท yes
Successful Amplify Push
Next start the application by running:
1
npm start
Keep npm start running throughout this tutorial in order to keep the asset tracking app running.
In your Cloud9, navigate to Run and then select Preview running application to view the app.
Selecting Preview Running Application
You should now see your application running inside Cloud9, like this.
Application running in Cloud9

Setting up IoT Core Resources

Now that we have our Amazon Location Service resources configured and our web app up and running, we need to configure an IoT Rule to send MQTT events to our new Amazon Location Service Tracker. This rule will watch for messages on the assets/tracker MQTT topic, parse the message, and send the location information to the AssetTracker Amazon Location Service tracker which updates the thing123 device that is displayed on the map.
Navigate to the IoT Core Console, and click on Message Routing then Rules.
AWS IoT Core Console showing location of Rules Engine
Click on Create Rule.
AWS IoT Core Console showing how to create a rule
Now let's give our rule the name AssetTrackingRule and click Next.
AWS IoT Core Console showing specifying a rules properties
Now we need our SQL statement. We will be using the topic assets/trackers. Enter SELECT * FROM 'assets/trackers'.
AWS IoT Core Console showing configuration of the SQL statement
Then click Next.
Now it's time to set up our Location Action. Select Location from the Choose an action dropdown.
AWS IoT Core Console showing configuration of the location action
Select Create a Tracker and enter the name AssetTracker.
AWS IoT Core Console showing configuration of the location action
Select Create tracker.
Now we can configure mapping of our payload to the rule. In order to do this, we will use substitution templates in IoT Core. Select trackerAsset01 for the Tracker name dropdown, then, for each field, copy/paste the following values:
Device ID: thing123
Longitude: ${longitude}
Latitude: ${latitude}
Timestamp value: ${timestamp()}
Finally, we need to create a new IAM Role that will give IoT Core Rules Engine permissions to update the Amazon Location Service Tracker resource. Click Create new role, give it the name AssetTrackerIoTRule and click Create.
AWS IoT Core Console showing configuration of the location action IAM Role
Our configuration should look like this.
AWS IoT Core Console showing configuration of the location action
Select Next.
AWS IoT Core Console showing final configuration of our IoT Core rule
Now select Create.
Now that we've created our IoT Core Rule, we can start sending messages.

Sending MQTT Messages

Now we will send a device location to AWS IoT Core and our MQTT Topic. This simulates a message that would come from an IoT Device such as an asset tracker.
From the IoT Core console, navigate to MQTT test client and select the Publish to a topic tab.
For the Topic name enter assets/tracker
Enter the following in Message payload to send our first point:
1
2
3
4
5
{
"deviceId": "thing123",
"latitude": "49.282301",
"longitude": "-123.118408"
}
Then select Publish.
AWS IoT Core Console showing the MQTT test client with a message published
Navigate back to Cloud9 and your running application. Refresh the application and you should see the point on the map.
Cloud9 showing the application running with a point on the map
Now let's enter another point. In the MQTT test client enter the following, then select Publish:
1
2
3
4
5
{
"deviceId": "thing123",
"latitude": "49.282144",
"longitude": "-123.117574"
}
Refresh the page and you will see a second pin, with a line connecting it with the previous point.
Cloud9 showing the application running with a point on the map

Cleaning up your AWS Environment

In order to remove resources created as part of this tutorial, we need to complete the following steps.

Delete Cloud9

In order to avoid incurring charges from our Cloud9 Instance, we need to delete the environment. Follow the steps here to remove the AssetTracking environment.

Delete Amazon Location Service Tracker

Navigate to the Amazon Location Service console, select Trackers, select trackerAsset01, and select Delete, confirming you wish to delete it.

Delete IoT Core Rule

Navigate to the IoT Core Console, select Message Routing and Rules. Select AssetTrackingRule and select Delete, confirming you wish to delete it.

Next Steps

Now that you've built an asset tracking solution, think about ways to send location information to AWS IoT Core. If you're interested in physical asset tracking devices, check out the AWS Partner Device Catalog or if you are interested in setting up more simulated devices at scale, check out the IoT Device Simulator Solution provided by AWS, which has the ability to simulate a moving device. Finally if you want to learn more about how the web app is built, check out the Amplify Geo documentation.

Conclusion

Congratulations! You just built a simple asset tracking app using AWS Amplify, Amazon Location Service, and AWS IoT Core. If you enjoyed this tutorial, found any issues, or have feedback us, please send it our way!

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