Transport-independent Bluetooth Fitness Machine Service protocol libraries.
Replace handwritten FTMS packet parsing with typed values, explicit diagnostics, and bidirectional codecs. Decode telemetry, inspect capability evidence, and encode protocol messages—without replacing your Bluetooth stack.
For application developers, firmware authors, and protocol tooling maintainers. Created and maintained by Dean Cochran; contributions are welcome.
Why use a protocol library? FTMS explained: from bytes to a workout walks through flags, little-endian values, measurement scaling and control messages with runnable examples—and shows which code your application no longer needs to own.
| Language | Start here | Distribution |
|---|---|---|
| C | Installed-library quickstart | C99 source archive; CMake installation and C++ consumers |
| C# | C# guide | NuGet: DeanCochran.Ftms; .NET |
| Dart | Dart guide | pub.dev: deancochran_ftms; Dart and Flutter |
| Go | Go guide | Go module github.com/deancochran/ftms/packages/go |
| Kotlin/JVM | Kotlin guide | Maven Central: io.github.deancochran:ftms; Kotlin and Java |
| Python | Python guide | PyPI: deancochran-ftms |
| Rust | Rust guide | crates.io: ftms |
| Swift | Swift guide | SwiftPM revision-pinned Git dependency |
| TypeScript | Five-minute quickstart | npm: @deancochran/ftms; JavaScript and TypeScript |
The canonical release matrix records verified versions, publication identity, prerelease status, installation requirements and evidence limits. For a guided entry point, choose a language. See releasing for independent package tags and release steps. The role-based support profiles distinguish client and equipment wire directions from optional package modules.
Rust is an independent, allocation-free no_std implementation with raw codecs,
static capability evidence, normalized views, and bounded record planning/assembly;
it does not own BLE, execution authority, or device lifecycle. See its
coverage and evidence.
With Node.js 20+ in a new directory:
npm init -y
npm install @deancochran/ftmsRetain the saved dependency and lockfile. The repository quickstart separately pins the verified artifact for reproducible tests. See all-port installation guidance.
Save as reading.mjs, then run node reading.mjs:
import { parseFtmsIndoorBikeMeasurement } from "@deancochran/ftms";
const bytes = Uint8Array.of(0x44, 0x00, 0x10, 0x0e, 0xb4, 0x00, 0xfa, 0x00);
const reading = parseFtmsIndoorBikeMeasurement(bytes);
console.log(reading.metrics.speedMps); // 10
console.log(reading.metrics.cadenceRpm); // 90
console.log(reading.metrics.powerWatts); // 250
console.log(reading.diagnostics.truncated); // falseThese are illustrative bytes, not a device capture. The runnable quickstart asserts these values and checks a deliberately truncated input. No Bluetooth hardware is needed.
- All six FTMS measurement families: treadmill, cross trainer, step climber, stair climber, rower and indoor bike.
- Features, supported ranges, training/machine statuses and Control Point codecs.
- TypeScript normalized metrics and raw APIs; C fixed-point values and diagnostics.
- Static capability interpretation that preserves missing and contradictory evidence.
- Shared, versioned regression fixtures and verified package-consumer boundaries.
See coverage for exact scope. Protocol coverage is not universal equipment compatibility. A limited passive KICKR CORE pilot is evidence for that recorded setup only, not control safety or qualification.
Bluetooth discovery, permissions, connections, subscriptions, timing, reconnection, control ownership, procedure serialization and physical safety. Encoding a valid command or observing a supported feature does not authorize sending it. This is not a complete trainer controller or a Bluetooth-qualified product. The consumer adapter seam defines the project-wide split between protocol packages and application integration.
- Documentation website
- Documentation and recommended reading order
- Static documentation site: local preview and deployment
- Integration cookbook
- Web Bluetooth, React Native and C byte-boundary recipes
- Consumer adapter seam and ownership table
- Public API selection and reference
- Troubleshooting
- TypeScript package details · C installation
See CONTRIBUTING.md, roadmap and non-goals, MIT license, and security reporting.
From a source checkout with Node.js 20+ and pnpm 10.33.0:
pnpm install --frozen-lockfile
pnpm verify
pnpm docs:build
make -C packages/c testpnpm checks validate TypeScript and documentation, not native code or devices. Native tests need their own host compilers and dependencies; see the contributor guide. No command above operates equipment or publishes a release.
Repository boundaries and package ownership are documented in architecture. Protocol contracts and fixtures live under shared/; language-owned sources and tools live under packages/. Detailed historical verification remains available through the documentation index, separate from the getting-started path.