Captive - RFID Demonstration (2018)
Captive tasked me with doing some research and development with some RFID hardware.
The immediate goal was to roll out a demonstration at a conference in town:
- Patrons would have an RFID sticker applied to their name tag
- The patron's contact information would be entered into a computer and the tag scanned to associate it
- When the patron entered various conference sessions, they could scan their name tag at a podium as they entered
- The slides and other materials from the presentation would be emailed to them immediately
The end goal of the system would be to implement it at events to reduce the friction for patrons to provide their contact information to various exhibitors in order to enter contests, sign up for mailing lists, etc.
I got in touch with a Canadian-based supplier of high quality German RFID hardware. A bit of quizzing of the sales manager and dodging of sales calls, and I managed to get the detail I needed to be reasonably certain that we could integrate their hardware with most of our experiences and systems—a 190 page system integrators manual detailing the format of protocol data units, available commands, and the format of arguments and responses.
The sales manager assured me we'd want to use the SDK rather than talking to the hardware in terms of raw data over the USB connection, which was my hope too, but the manual ensured that we'd be able to integrate regardless.
When we got the hardware, it was pretty much as I expected—Windows DLLs and Java SDKs. In order to develop freestanding kiosks and podiums that contained these readers, we planned on using Raspberry Pis and similar hardware running Linux. The manufacturer's drivers weren't going to do the trick. Looking around the internet, all that I could find was wrappers around the Windows DLLs for languages besides Java.
I went looking for some bindings for libusb and found the PyUSB project. Over the course of the next day, I learned some Python and developed a fairly basic driver for the RFID hardware.
An initial version of the driver without any of the other supporting code or services was published to GitHub.
Conceptually, the idea was to have each scanning station generate "events" which were then processed and correlated in a backend service in order to determine what actions to be taken (e.g., send an email) and then actually accomplish that.
The processing pipeline was designed and implemented in about two days.
For a variety of reasons, storing the patron's contact information directly on the RFID tags and having individual scanning points attempting to send them emails or otherwise perform interaction actions directly was not my preferred way to tackle this project:
- Privacy — Handing someone a tag that allows anyone to wirelessly read their personally identifiable information is not great from a privacy standpoint.
- Change Management — Having each scanning point performing actions directly means each device needs to know what actions to perform. That means someone needs to keep track of that and ensure the devices are correctly configured for each event.
- Security — Allowing the scanning points to perform actions like sending emails means each scanning point needs access to send emails on our behalf. I'm always wary of putting any credentials out in the wild.
- Scalability — While the Raspberry Pi device are pretty powerful, they could potentially turn into a bottleneck.
- Etc — I could probably come up with ten more reasons, but those should be enough points in the 'cons' column to kill this idea.
Instead, the plan was to use each tags serial number and simply generate events for a backend to process and correlate in order to take the correct actions.
Finding the Right AWS Services
Based on a high level understanding of a variety of AWS's products, I developed a plan for using them to tackle this problem:
- Internet of Things — A product specifically designed for receiving events and measurements from embedded devices. As events are generated by the devices, they are received and pushed into...
- Simple Queue Service — Put all the events in a queue for processing. A job queue is an easy way to implement parallelism and reliability into a system like this. Once events are queued, trigger...
- Lambda — Rather than manually manage our processing infrastructure and scaling, delegate that to AWS and simply write the code to solve our problem. Process events from the queue and lookup the desired response actions and update records in...
- DynamoDB — I generally think using document storage systems for structured data (i.e., almost all data) is lazy, but DynamoDB is the only cheap option for having Amazon handle the database for us. Store tag registration information and event actions in here—all the information the processing step generates and needs.
You may remember from the "RFID Hardware" section that that was my first time really using Python. Implementing this project with Lambda was my second.
Changes in Implementation
While each scanning point was individually registered and contained its own credentials for publishing events, the registration system for entering the names and emails used Amazon Cognito in order to gain access to IoT Core.
There is no ability to trigger a Lambda function based on any sort of SQS queue events, so the function instead had to be set to simply run periodically. This was my biggest disappointment with how the project turned out and the first thing on my list to refactor.
How it Worked
It's pretty cool to tap a RFID tag and feel your pocket buzz a moment later with an email.
It's really cool when you know all the steps involved to make something so complicated seem so simple.