Your Resource for All Things Apps, Ops, and Infrastructure

Using AWS IoT as a Running Buddy

At the end of 2016 I made the decision to leave Amazon Web Services and move into the role of Chief Architect of Public Cloud at AHEAD. Part of this transition included relocation from the mild climate of the Bay Area to a *slightly* chillier Chicago (well, in the winter at least).

I’ve been an avid jogger for years, and while I was living in Oakland, I grew accustomed to being able to run outside essentially every day of the year. I detest treadmills, so when I moved to Chicago I needed to find somewhere that I could jog without freezing my extremities off. Fortunately, there’s a gym in my area that has an indoor track. At this particular track, nine laps equals roughly one mile. Time permitting, I try to get ~four miles in daily, and when I’m jogging, my mind tends to wander and counting laps often becomes an afterthought. And after about 30 minutes, I only have a rough idea of how much distance I’ve actually covered. I figured I could use some help.

There are plenty of lap counters out there, both electronic and mechanical. What I wanted to do is see if I could build something a little better – something that I could use to track my progress, and learn something new at the same time. As I was unpacking boxes in my new house, I stumbled upon a 1st Generation AWS IoT Button. Given that my gym also has wifi, perhaps I could use the button as a starting point for building my own lap counter.

The Design

While the button can handle the process of sending events to the cloud just fine (clicking the button sends a message to the AWS IoT service over wifi), it doesn’t store any information about my jog. I’d need something in the cloud to store my lap count, as well as a way of viewing that data.

running_buddy_arch v2 (1)

Here’s how the lap counter application is designed:

  • The button is connected to a local wifi network. In the absence of a local wifi network, I can use my phone as a hotspot. Data usage for the button is… microscopic.
  • The button can record several different types of presses, and for this app, they do different things:

    • Single click – add a lap
    • Double click – reset the counter
    • Long press – reset the counter
  • A DynamoDB table counts the number of laps per button (referred to in the table by the buttons serial number, or DSN).
  • When a press event takes place, the press info is sent to the AWS IoT service, and a Lambda function is invoked. This function will update the DynamoDB table based on the type of button press that was received.
  • A [very ugly and very simple] HTML dashboard is hosted in Amazon S3 leveraging S3’s static website feature.
  • The dashboard polls a serverless API endpoint (built with AWS Lambda & Amazon API Gateway), which reads the lap count from the DynamoDB table.

Do It Yourself

If you have an AWS IoT Button of your own that’s looking for a purpose in life, or you’ve been looking for an excuse to buy one, I wanted to make it easy to spin up your own version. To do that, I modeled *most* of the lap tracker application infrastructure in a CloudFormation template. All of the code for doing this, including that CloudFormation template, is available in a GitHub repository here. Note: you’ll also need an active AWS account.

The steps for getting things going are as follows:

    • Complete the Getting Started with the AWS IoT Button walkthrough. This will get your button connected to the network, as well as configure it to talk to your personal AWS IoT endpoint securely.

      • There is a module in the “Getting Started” walkthrough for testing the button by sending an email when the button is pressed. After you have it all set up, I would disable the trigger for that Lambda function. Otherwise, you’ll be getting an email every time you complete a lap!
    • In the CloudFormation console, create your stack using the template provided above. You will be asked for the DSN of your device:AWSIOT-1
    • Continue to click “Next” through the options until you arrive at the Review screen. You’ll need to create a Change Set and acknowledge IAM changes the CloudFormation may make. A Change Set is required because this CloudFormation template makes use of the Serverless Application Model. Complete the creation by clicking on “Execute”:AWSIOT2
    • Once the stack has been provisioned, you’ll need to find the URL of your API. In the API Gateway console, find the API (the name will match the name of your stack). Click on “Stages” and click on the “Prod” stage. The “Invoke URL” field contains your API endpoint location:AWSIOT3
    • In your index.html dashboard file, update the “myUrl” variable to reflect the API Gateway URL and save it:AWSIOT4
    • In the S3 console, upload the modified index.html document and the favicon.ico image to the base of the S3 bucket created as part of your stack. Make sure to give them public access. Then, on the bucket, enable Static Website Hosting and set “index.html” as your Index Document, and “Save”. Note the “Endpoint”, as that is how you will access your dashboard:AWSIOT5
  • The last major step is to set up your AWS IoT Button as a trigger for the Lambda function that writes to the DynamoDB table. In the Lambda console, select the “ButtonPressFunction” function. In the “Triggers” tab, add a trigger. Select “AWS IoT” at the integrations prompt, and in the resulting dialog box select an IoT Type of “IoT Button” and provide your DSN. Click “Submit” to complete:
  • Everything should be good to start counting! As you click your button, your dashboard should reflect the incrementing within a few seconds:


Again, a single click will increment the counter – a double click or long press will reset the counter.


Cleaning up your environment is really easy. All you have to do (in this order is):

  • Remove index.html and favicon.ico from your S3 bucket. Note – you can’t delete an S3 bucket if there are objects in it.
  • Delete the CloudFormation stack. This will clean up all of the other resources created (although leave the info about your AWS IoT Button untouched).


This is a simple use case for the AWS IoT Button, and hopefully you’ve picked up a bit about other AWS services that can be easily integrated to build an app. I have the app code up in a public GitHub repository, so if you have some ideas on how to enhance the app, by all means put in a PR.

For more information on AWS, AHEAD’s relationship with AWS, or how our experts can help optimize your AWS environment, contact us today to learn more about our solutions and offerings.

portrait. Photo by Andrew Collings.

Subscribe to the AHEAD i/o Newsletter