Building Smart City Kiosks with Web App Practices

Making cities smarter requires smart engineering habits 🏗️

Tuesday, February 12, 2019

Click here to go to all posts. Also published on the Intersection blog

Building human-centered digital experiences is always a challenge. That challenge increases dramatically when trying to bridge the divide between the built environment, physical product, and digital experience. That’s one of the tasks our engineering team is aiming to achieve at Intersection.

A Chicago CTA Interactive Kiosk

After recently launching our interactive kiosks, otherwise known as IxNTouch kiosks, with the Chicago Transit Authority, it seems like the perfect time to discuss the tech stack we used to get there. After all, these rider-centric devices are the product of years of iteration, in terms of not only user experience and design, but also engineering lessons learned.

While this post focuses on our engineering work, you can check out Kohzy Koh’s post,Two-way Communications in Transit: Lessons Learned From Designing Public Interactive Kiosks, to learn more from a product and UX perspective.

Let’s take a look at a few of the important elements of our technology stack! I’ll be focusing on the kiosk software experience of IxNTouch.

Foundation of Chromium

For both the interactive kiosks and local development, we rely on Chromium to power our experience. In the case of the kiosks, we depend on a Chromium-based player that uses the Chromium Embedded Framework to show frames with web content. Historically, we depended on some of the player-specific features to power our kiosk experiences, but we have since committed to Chromium as the generic foundation.

This is a huge engineering win, because instead of writing architecture-specific software, we can build rapidly using the latest web standards. I will touch on our web app approach in the next section, but Chromium itself is a separate win for us.

The IxNTouch web app with Chrome Dev Tools open

Since Chromium is our foundation, we can safely depend on Chromium Developer Tools built into the browser, as well as add-ons specific to our framework and dependency selections. When something isn’t working as expected, we can debug locally or on kiosks using remote debugger, via developer tools, and drill down as needed. Exploring the DOM, stepping into functions, testing offline state, and watching data usage are made significantly easier by choosing Chromium.

Velocity Using Web Tech

When it comes to the user-facing kiosk experience, we use web technology to power everything. At our core, we’re using JavaScript (ES6+), HTML, and CSS, with React as the framework. That’s right; just like you might build a web app for desktop or mobile users, we’ve chosen a modern framework that gives us simple control over data flow, componentization, and code reuse.

Unlike alternative paths, this has a number of critical benefits, including:

  • We’re able to build and test using the tools we’re already familiar with

  • Our talented engineers don’t have to deal with the intricacies of a proprietary stack

  • Our kiosk web app can be tested and reviewed on a variety of devices, including tablets, touchscreen laptops, and phones 💻 🖥📱

  • We can focus on differentiating the experience and use tools like styled-components, Redux, and Workbox to help us get there

  • We can use best practices for mobile development around areas such as offline state, as they overlap greatly with our kiosk experience

  • We use awesome tools like React Storybook to drill into our components and develop them with clean reuse in mind

Jack, one of our engineers, debugging on a test kiosk (without applying rotation! 😆)

Additionally, since we’re using Chromium, we get to take advantage of tools like React Developer Tools and Redux DevTools as we’re building, to create quick feedback loops. Debugging and digging into the running app is essential for our development process.

Connected, But Not Always

Similar to the mobile world, our kiosks need to work 24/7. In some cases, kiosks are connected exclusively via LTE (cellular connection), which not only limits our bandwidth and data usage, but also causes latency and occasional network drops.

To account for this, our web app has to work in a variety of offline states. Again, by virtue of being a regular web app in a Chromium-based environment, we take advantage of a Service Worker to handle transparently caching data and detecting offline state.

Animated GIF showing the offline/online state switch

In particular, while we use both pre-caching and runtime caching, we also detect when requests are failing and use that to determine if we’ve entered an offline state. At that point, we can determine how to handle the offline state on a per-component or per-data basis. For instance, in the image above, you can see arrivals disappear after around three minutes of being offline, as this data is rapidly considered stale. On the other hand, we can continue to show alerts or video content for longer, as those are not immediately considered stale.

In both cases, the Service Worker is transparently caching the data and alerting commuters about the online/offline state, while leaving the business-oriented decision of “what content to expire and when” to the app layer.

What’s Next?

As we continue to build out our kiosks and other smart city experiences, we are excited to share more about the technology we’re using. This includes deep dives into the above topics, including management of off-line state, web-stack dependencies, and our development pipeline. We’ll also cover our use of Storybook, lessons learned from previous kiosk development, and some of the challenges we’ve run into (including a Chromium bug!).

In many ways, building smart city experiences is very much the same as building for mobile or the web: our goal is to keep the user front and center and to provide them with the best possible experience. As engineers, we bring that experience to life with the right tools and techniques.