Most fitness equipment that talks Bluetooth uses the standard FTMS (Fitness
Machine Service), which Home Assistant and apps like Zwift can read out of the box.
Older NordicTrack / ProForm / iFit treadmills do not. They advertise as I_TL
on a proprietary Nordic-Semiconductor service (00001533-…) and speak a custom
framing that nothing off-the-shelf understands. So we reverse-engineered it.
The hard part: it's host-polled
The first wall everyone hits: if you just connect and subscribe to notifications, you get nothing. The treadmill never pushes data on its own. The phone app is the clock — it writes a command roughly every 200 ms, and each write triggers a short burst of reply notifications. Miss that, and the belt looks dead over BLE.
Once we replayed that poll loop, the data started flowing.
Decoding the frame
Telemetry comes back on a page we call 0x29. After confirming against two
independent reverse-engineering efforts and our own packet capture, the decode is:
- Speed — bytes 10–11, little-endian, ÷100 → km/h
- Incline — bytes 12–13, little-endian, ÷100 → %
- Elapsed — byte 14, seconds
We validated it live against the console: 3 mph read back as 482 (4.82 km/h),
5 mph as 804, and 6% incline as 300. Exact.
From laptop script to a $5 device
We proved the protocol with a Python (bleak) script, then ported it to an
ESP32-S3: it scans for the treadmill, replays the init handshake, runs the
200 ms poll, decodes the page, and publishes everything to MQTT with Home
Assistant auto-discovery. Power it from any USB charger and it just sits there
connected — walk up, run, and your workout lands in Home Assistant with zero taps.
We even compute calories from your real body weight (pulled from a smart scale) using the ACSM metabolic equations — something the treadmill itself can't do, because it doesn't know who's running.
It's all open source
The firmware, the 3D-printed enclosure, the Home Assistant dashboard and the full protocol write-up are public. Want the bridge built and shipped to you instead of soldering it yourself? That's what we do.