The Open Open-Gangway Gang
Last week, the MTA expanded its rollout of the new open-gangway train, known as the R211T, to the G line. (There are only three of these experimental trains in service; until last week there were two, exclusively running on the C line.) If you’re a railfan or just want to experience a fancy new train, you could spend an hour waiting on the platform in the hopes that one of these rare trains might roll in. Or, as of today, you can visit traintrack.now and see exactly where they are in real-time.

traintrack.now uses a mix of real-time data sources to track three R211Ts: MTA’s real-time GTFS feed, goodservice.io‘s adjusted live schedule API, and a Nordic nRF51822 iBeacon running a flashed version of OpenHaystack. It’s reliant on a fairly janky homebrew setup, so by the time you read these words the site may or may not be functioning. We’ll see!
OK, let’s back up a step. What is the R211T, and why should anyone care?
The R211T is an open-gangway train: like the articulated buses rolling around town with an accordion in the middle, this basically means that passengers can walk between each of the cars without having to open a door and step outside into the tunnel. (Great news for my friend Jon, who got locked between two cars of a Q train about ten years ago as it was heading over the Manhattan Bridge, and had to break a window to climb back in while other straphangers just ignored him!)

I’ve been eager to see an R211T in the wild since at least December 2017, when the MTA stuck a full-size mock-up inside the Hudson Yards 7 train station for a few days!

I also crossed paths with the first shiny new R211T cars in the fall of 2022, when I was visiting my physical therapist nearby and happened to notice a bunch of cars being staged at the MTA’s yard in Industry City, where trains arrive by flatbed truck and enter the system.

So when the first R211Ts began testing in 2023 and entered revenue service on the C in 2024, I couldn’t wait to check them out. (I have a long history of catching the first and/or last ride into / out of old and/or new stations, as I did with South Ferry in 2009, Hudson Yards in 2015, the 2nd Avenue Subway in 2017, and Grand Central Madison in 2023.) But somehow I never managed to catch the elusive R211T.
Meanwhile, this winter my similarly infrastructure-obsessed friend Reed was visiting New York for the first time in nearly a decade, so we decided to spend a day touring ten years’ worth of big new infrastructure projects, including places like Hudson Yards, Moynihan Station, Little Island, Gansevoort Peninsula, Domino Park, and all the big stations I mentioned above.
And of course we wanted to experience the R211T. So we spent an hour on the A/C platform at Fulton St waiting. It never came. We did some rough calculations looking at timetables and pondering the length of the line, and determined that within an hour we’d seen just about every train actively running on the line. Perhaps the R211T was sitting in a maintenance yard, or perhaps it was never active on Sundays. Who knew?
This seemed like a solvable problem. Surely the trove of available subway data would include timetables for specific cars.
Nope! It turns out that the MTA doesn’t include this information in its GTFS data feed. It offers a trip ID, but that’s generated and/or assigned to a specific train when it leaves a terminal and starts a route. There’s no connection between that ID and which car is running. Perhaps that’s simply because our hundred-year-old 24/7 subway system is too chaotic to reliably support this. Cars get added to and removed from trains all the time, trains get delayed and rerouted or removed from service, and in general the realtime data feed is a hodgepodge of scheduled and impromptu trips. (Honestly, it’s remarkable that it works as well as it does!)

We thought: okay, well, surely there’s some camera we could tap into. Nope. The MTA doesn’t release its camera feeds to the public, and while the city and state operate many public feeds that could offer sightlines to certain above-ground subway lines (even though that’s not their purpose), the C train runs below-ground for its entire route.
By this time, my friend had left the city, bitterly disappointed at having missed the open-gangway train. But I kept turning it over in my head.
I thought: a GPS beacon would be a really compelling option. Something that could phone home and share the train’s location as it moved up and down the line. But no: since the C is below-ground, satellites wouldn’t do the trick.
That got me thinking about AirTags. I wondered if I could just stick an AirTag on an R211T and get updates on its real-time location. Maybe? But Apple’s Find My ecosystem is – of course – closed-source, so I had no idea if I’d be able to tap into this data in any useful way. (By this point I’d moved on from my own short-term goal to the larger mission of making this data public: after all, if I found a train and could put an AirTag on it, I would have already experienced the train!)
I shared this idea with my brother, since he’d been working on his own bus data visualization project around this time. And incredibly, like manna from heaven, he offered this back:

And indeed, r/selfhosted is a special and untamable place. Jordan sent me to a post that solved exactly my problem, outlining a procedure in which one could flash BLE beacons with firmware called OpenHaystack to piggyback off of the Find My network using custom hardware, gather location data, and incorporate that into custom code without relying directly on Apple hardware.
So for the price of a few $2 beacons on aliexpress, we could harness the coverage of the Find My ecosystem and get reliable, real-time, below-ground readings on the R211T. Incredible!
I got to work.

The process here was reasonably simple: use OpenHaystack to generate custom firmware for the beacon, then use open-ocd, telnet and an ST-LINK v2 programmer to flash the hardware. I did have to temporarily solder four (3.3v, gnd, SWDIO, SWCLK) to some tiny test pads on the PCB to do this, but fortunately my soldering skills have leveled up in the past couple of years.

And then, like magic, a little beacon phoning home! After that, it was just a matter of popping it onto a physical train and then figuring out the best way to visualize the incoming data.

search-party-token
to connect to Apple’s servers and retrieve location dataThe deus ex machina of the reddit post my brother shared was an incredible moment, but collaborating with him over the past couple of weeks has been the bigger gift.

Jordan and I have a lot of overlapping interests, and civic tech, code and data visualizations just scratch the surface. We’ve been looking for something to pair on for a while, but many of my recent projects have been weird nostalgic retro computing things that aren’t always his jam. This was such a perfect opportunity!
We’re both vibe coders, but while I struggle to think of myself as anything more than a dilettante who can kludge things together with spit and sealing wax, I admire his ability to deeply understand technical problems and build with efficient modern frameworks. Aside from my recent dabbling in LLM-paired coding, I’ve been coding the same basic way for decades, which means I had a ton to learn from his approach. (Put simply, I’m more comfortable working directly in prod via BBedit and uploading via FTP than setting up development environments, deploying to github and using serverless frameworks.)

Many of Jordan’s recent projects have existed within the Next.js / React / Vercel cinematic universe, so he situated our work there. If I had my druthers, I would have done something dumb in Python and Flask and called it a day. And I’ll admit it took me a while to even get into the habit of cloning the repo, rigging my own functioning local dev environment, and pushing changes to prod. For longer than I care to admit, I sent him random python files via Signal and asked him to wire it all up. Eep.
The actual traintrack.now site that resulted from our work is pretty straightforward. Because I’m uncomortable constantly pinging the beacons (since it uses private Find My APIs and I feel confident my burner Apple IDs will get banned before too long), we have some back-end logic that attempts to map the beacon’s lat/long to a known trip_id represented in the MTA’s GTFS data (which we access using the lovely nyct-gtfs wrapper). Right now, we basically find the timestamp of the most recent ping from a terminus, and then attept to map that to the departure timestamp of a trip that’s currently underway. The front-end is basically next.js and Tailwind CSS running on Vercel, with a custom MapBox base overlaid with MTA geojson. The back-end is a serverless Python functions that runs on a cron and performs the beacon-to-GTFS mapping, storing the results in a Neon serverless postgres database that the front-end pings as a REST API via Prisma.
That whole stack is thanks to Jordan. It allowed us to do something remarkably slick without a ton of overhead. I’m really proud of the outcome.
Jordan also encouraged us to play with Mapbox Studio based on his experiences building Bustle. Oh god it was so much fun to basically rebuild the famous Tauranac subway map we’ve all come to know and love in Mapbox. I had no idea it was possible to customize Mapbox so much — the last time I rolled my sleeves up with it, it was just to use those amazing Stamen Labs watercolor map tiles. I went overboard here, matching land, park, water and airport colors, as well as the various weights and kerning of Helvetica and Times New Roman, while trying to keep the information density low enough that the extraneous text wouldn’t compete for attention with the subway line overlays. I absolutely love how it turned out; you can play with it here.

And that’s that! Something I shouldn’t leave unsaid is how impressive it is that these beacons have been rolling on three R211Ts for almost two weeks now. I’m sure sooner or later they’ll be found and discarded or the batteries will wear out. I also should spend a minute talking about privacy. The beacons record only the location of a train as it moves up and down a fixed and known track. Apple’s page on Find My & Privacy is worth reading, especially the line “The Find My network uses end-to-end encryption so that Apple cannot see the location of any offline device or reporting device“ (emphasis added). With the help of a useful discussion on hacker news, I’ve discovered that you can opt out of participating in this mesh network by disabling the toggle at Settings > [Your name] > Find My > Find My iPhone > Find My network
. Android users aren’t unwittingly helping us find fun open-gangway trains, though their Find My Device network works similarly.
You can check out our github repo here. For once, thanks to Jordan, I don’t even have to apologize too much for it.
See you on the rails!


