Infectious Ideas: Scaling the Physical Web.

Creating physical+digital experiences at events with beacons, smartphones and the web.

Lately I’ve been interested in the physical computing opportunities of the web on mobile. While IoT gets all the attention, forcing newbie programmers to write C-like code to get a single LED to light up off under-powered “developer boards”, we’re all carrying around incredibly powerful computers jam-packed with physical sensors… and web browsers that can access a good number of those sensors!

So I’ve been playing in the space a bit, exploring what we can do with the sensors in our phones, with experiments in AR and IoT, like this A-Frame + getUserMedia() test:

Mozfest, Magnet, and Beacons Galore

I’d ordered a bunch of Bluetooth beacons when Project Magnet, Mozilla’s Connected Devices beacon app, put in a bulk order. I figured I’d use them at some point, as they’re an interesting intersection of Web and physical computing.

Mozfest was coming up around the time they’d be delivered. Mozfest is the Mozilla Foundation’s annual festival for the open internet movement. Imagine a nine floor art school taken over for a weekend, packed with digital artists, journalists, scientists, web makers and activists… and now imagine it covered in beacons…

I started working with Katie Caldwell and Liz Hunt from the Connected Devices group at Mozilla on ideas for beaconizing Mozfest.

Given the presence of beacons throughout an event, and a way to interact with them, there a bunch of questions by organizers that we can answer: Where do people go? What do they like? What do they miss out on? And for attendees there are different questions: What did I see? What did I like? What do I want to remember? I know that when I go to Mozfest (or anywhere, to be honest), I end up with a slew of emails to myself or a stream of undecipherable notes in an Evernote. Surely we can do better.

What if instead, attendees left with a record of what they saw, ambiently collected by the experience itself?

The Cooper Hewitt Pen

I’d been inspired by the Cooper Hewitt’s attempt at something similar, after talking with Aaron Straup Cope about his project a few years ago. They designed a physical “pen” that you use to touch markers on exhibits you want to “save”. You get a QR code and URL for a page on their website that has all your saved items. It was pretty cool, a huge step up from the typical museum experience.

But when I went there, the physical interactions were pretty rough. The pen itself feels large and clunky, and the ergonomics of “saving” are awkward. You “save” by turning the pen around and tapping the “eraser” on the marker, which is counter-intuitive. Choosing to model the device after a banal office implement, instead of a magic wand seems bizarre. Oh, and to top it off… now we’re all walking around carrying devices in both hands. Conceptually interesting, and kudos to them for pushing on the museum experience, but it could be much better.

I wanted us to do something similar, but which required less (or even zero) work by the user, and felt like it belonged to the user. I also wanted to create a touch of excitement by poking at our goal-reaching wetware with some gamification.

So into the rabbit hole we went.

Project Concept: IDEA INFESTATION!

Katie submitted our proposal for the project. The idea was to set up the dynamic to encourage people to collect all the beacons, thus being exposed to whole areas of the festival they might not have ever thought to go… to be INFECTED BY NEW IDEAS. Thus, Mozfestation!

Project Topology

The physical computing stack gets weird fast. We had little time or resources, so I designed the architecture as lazily as possible.

  • Beacons: 100 beacons, each configured with a URL for a specific exhibit or location at Mozfest. We configured the beacons in URL mode, per the Project Magnet instructions.
  • Back-end: The “database” is a Google spreadsheet with a sheet that logs all unique user+beacon visits, a sheet containing all the beacon data (pulled mostly from the Mozfest schedule spreadsheet), and a couple of pivot tables that join those first two sheets into useful things like user and beacon leaderboards.
  • User management: We didn’t want to deal with account creation or integration or anything like that, so each user got a unique ID generated when the app is installed. Users can look at that ID in the app and search for it on the leaderboard. Yeah, not great. But it requires zero setup by the user and they still get most of the intended benefits. A side-benefit is that the user is basically anonymous in an app where we’re tracking their physical location — very sensitive information! If a motivated attacker wanted to track the movements of the user, they’d have to either control the whole network and do a bunch of piecing back together of network communication, or have access to the app on the user’s device and extract the ID and match it up with the public data set.
  • Website Part #1 — Landing Page: A landing page that checks for iOS or Android user agent and automatically routes to the correct app store. Source code.
  • Website Part #2 — Beacon Pages: This was 100 individual static pages for each beacon, with URL matching what the beacon was configured to. I wrote a simple node.js script that pulled the data from our back-end and generated the pages based on a template HTML page. Source code.
  • Website Part #3 — Leaderboards: Homepage with leaderboards of users with most beacons visited and beacons with most visitors. This was a single HTML page with a bit of JS that polled our back-end for the leaderboard data and displayed the results. I used Tabletop to easily access the Google sheets API. Source code, and the site is still live.
  • Native Apps: I took the Project Magnet client source code (a React Native app) and skinned it with the Mozfestation header image to match our designs, added data persistence via Redux-Persist, added unique user ID generation on install, and added some code to push data to IFTTT each time a user encountered a beacon for the first time. Source code.
  • IFTTT: I created an IFTTT trigger that for each request from a native app to the Maker channel URL, would append that data to our Google spreadsheet. I guess I could’ve written the code to connect to the Google API directly from the native app… but why? With IFTTT I can send all the data in GET request and completely ignore the response, making it one line of code in the native app, and let IFTTT deal with all the bother of authenticating with Google, managing keys, appending to the right sheet, etc.

And there it is — a hodge-podge mish-mash of duct tape and bubblegum that pretty much just worked as expected. Mischief managed.

On Large Scale Beacon Deployment

Ok 100 beacons isn’t super large, but it’s not small either. If you don’t set things up right, you’re gonna have a bad time. We had some things right, and definitely needed to tweak some things.

  • Start by writing a number on each beacon with a sharpie.
  • Keep numbered beacons separated in bags in groups of ten by their number. Otherwise you find yourself digging through 100 beacons looking for #37. Like we did.
  • Create the URL for each beacon with its number, eg: If you have #23 written on it, configure the beacon with URL
  • Configuration of each beacon is manual, and takes some time. Get a team together and parallelize the process… but in different rooms, because it gets confusing fast when multiple beacons are in editable mode.
  • Make sure your highest number fits on the beacon. Beacons have VERY limited storage, and of course I was testing single digits but had a 100 beacons. I had a rude awakening at beacon #10 when the save failed, and had to rename the our short URL string prefix and go back and redo those first nine…
  • Make sure you use a short URL service that lets you create enough custom URLs. free accounts max out at 30, so we had to create new accounts. What a pain. Also, URLs spread across multiple accounts messes up your metrics.
  • Beacon batteries die. Some are already dead out of the box. Buy lots of extra batteries.
  • For that matter, the beacons themselves die. And some are already dead out of the box. Buy extra beacons, if you need a specific number. For example, our counter to 100 wouldn’t have been as cool if it was a counter to 87.
  • Make a map of where you put each beacon, with detailed notes, or you will never find them again. We found most of our beacons, but it took a lot of hunting!

Things We’d Do Differently

Not everything went ok. Some things went horribly awry. Some things are cured by hindsight.

  • The native app on iOS started crashing once we began testing on-site. I fixed the crash and the app was approved in 24 hours… at 10pm the night before Mozfest began. I’m still recovering from the stress. I will NEVER EVER ship a native app without something like Microsoft’s CodePush for live-updates ever again. If you have other suggestions for tools like that, let me know!
  • Because so much time was lost investigating and fixing the crash and then submitting to app stores, I didn’t get the leaderboard up until late Saturday, and Sunday is far quieter at Mozfest, so we lost an opportunity to engage lots of passers-by. Once the board was up on the big screen, loads of people stopped to ask about it, and would immediately install the app.
  • We didn’t modulate the signal strength on the beacons, just used the default. Which meant that in open spaces, some beacons were detected 30 meters away. Ugh. Next time, I’ll turn them all way down, and only count something as an actual visit if someone is right next to the beacon, and for a given length of time. In fact, you can make things more useful by doing things like modifying the app to showcase the beacons that users spent the most time at, a sort of auto-bookmark.
  • Katie designed awesome flyers. The flyers arrived late. The publisher didn’t notify us. The Mozfest folks didn’t know where the box was. We ended up getting the flyers (along with six boxes of other projects’ printing jobs) an hour into the swag packing process. We got the flyers into about half of the 1800 swag bags.
  • In general, we needed more app installs. Having flyers in swag bags, even if they’d all made it, wasn’t enough. We should’ve waged a campaign on the #mozfest hashtag to get people to pre-install, building momentum prior to the event, and worked with the Mozfest organizers to get the word out.
  • Next time, I’ll use a link shortener with a programmatic API in order to automate short URL creation and management directly from the back-end.


The feedback we got from people at Mozfest was generally great. Most had never heard of beacons or the physical web.

  • Getting people to install an app is hard. Getting people to open a URL is easy. I’m looking forward to the day that the web can talk Bluetooth.
  • I ordered beacons with no plan. When you leave materials laying about and let people play with them, super fun and interesting things happen.
  • We overreached by far. We touched on beacons, event experiences, physical computing, gamification, multi-screen interactions, anonymizing user experience, and more… and learned a bunch of stuff about each.
  • Minimum-viable-gamification works for some people. We had users yelling out their beacon count at us when we’d walk by, and others coming back to check the leaderboard. All because we put a “n/100” counter in the app.
  • It’s important to make sure the content from the beacons brings real value to the users. Our pages were bare-bones, and needed more content. If they had excellent information, and photos of the exhibits, explanations, etc, could be shareable to social directly from the page, and be another outbound communication channel.


Katie put together the infographic below, summing up the statistics generated by our beacon logs. MozEx was nearly 50% of the beacon content, and was spread across all floors, so it dominates the results. But this gives you an idea of the type of learnings that ubiquitous beacon placement and ambient exposure tracking enables.


Thanks to Katie and Liz, awesome collaborators on this project. Thanks to Rabimba Karanjai for helping unbox and configure tons of beacons. Thanks to Mozfest and all it’s amazing organizers and volunteers. Thanks to all the peeps at Mozfest who installed the app and came by and talked to us.

And thank you for reading this far. If you’re doing experiments with beacons and the web, let me know, I’d love to hear about it!


Mozilla, Firefox, and the Web. Every spectator is a plotter.

Mozilla, Firefox, and the Web. Every spectator is a plotter.