Data-driven: pulling metrics my rower won't give me
Post 2 of the ergy.coach build-in-public series.
A coach with no data is a coach with its eyes shut. For my agent to help me chase a sub-8:00 2k, it needed fuel: my sessions, in numbers, one after another.
Small snag: my rower exposes nothing. No API, no webhook, no official door to read my meters, my power, or my stroke rate.
Strava? A dead end
My first instinct was Strava, where my sessions land. The Strava API terms now ban using the data in AI models and routing it through a third-party platform. That ruled Strava out for an AI coach. Better to learn it early and design around it.
The data was there all along, over Bluetooth
My rower hands out no API. It already broadcasts everything over Bluetooth so it can pair with apps. Most fitness machines speak an open standard, FTMS (Fitness Machine Service). For a rower it exposes a “Rower Data” characteristic: stroke rate, distance, pace, and power, live.
I confirmed it in two minutes with nRF Connect, a Bluetooth scanner app. My machine advertises the Fitness Machine service. The reading I thought was locked was sitting on a different channel.
The listener
I wrote a small app. It connects to the rower’s FTMS service, subscribes to the “Rower Data” notifications, and decodes the frames byte by byte. One header bit caught me out: its logic runs inverted. The app aggregates the session (distance, average and max watts, pace, stroke rate, heart rate) and pushes it into the database behind my Adonis API.
The agentic loop
The click came here: every time I save a session, my agent writes me a summary. It tells me what worked and what slipped, then gives one adjustment for next time. I don’t ask for it. I row, and the coach answers.
The lesson I’m keeping reaches past rowing. When an API shuts you out, drop down a layer toward the source. The reading you want often sits one channel away.
What’s next in this series
In Part 3, I go from numbers to stroke form — checking my technique on video with pose estimation and an agent that coaches from measured features, not hard-coded thresholds.