A C11 library for integrating with HackMotion wrist sensors over Bluetooth Low Energy, with Python bindings for driving one from Python.
The library implements the sensor's protocol: framing and decode, session sequencing, calibration, the device→host clock fit, and full-rate retrieval of the sensor's on-board history buffer.
It is sans-I/O — it owns no radio, thread, timer or clock. Your code supplies bytes and timestamps; the library returns commands, samples and events. That lets it sit alongside a BLE stack you already use, and lets it be tested without a radio or a sensor.
A C11 compiler and CMake ≥ 3.16. No dependencies.
cmake -S . -B build/dev -DCMAKE_BUILD_TYPE=Debug
cmake --build build/dev -j4
ctest --test-dir build/dev --output-on-failurePresets dev, san, cov, rel and release wrap the usual configurations.
The last two are both optimised and differ only in debug info: rel is
RelWithDebInfo, for symbolising a fault in an optimised build, and release is
-O3 with none, for shipping — 110 KB against 342 KB.
The library is meant to be embedded, so adding it to your project changes nothing about your project — not its build type, not its test registry, not its install manifest. Drop it in and link:
add_subdirectory(libwrist) # or FetchContent_MakeAvailable(wrist)
target_link_libraries(your_app PRIVATE wrist)#include <wrist/wrist.h> then resolves through the link — the include
directory is PUBLIC on the target.
If instead you install it and consume it as a package, both of the usual mechanisms are there and give you the same target:
find_package(wrist CONFIG REQUIRED)
target_link_libraries(your_app PRIVATE wrist::wrist)pkg-config --cflags --libs wristwrist::wrist is also defined by add_subdirectory, so a consumer can spell it
the one way whichever route the library arrived by. The version file is
SameMinorVersion: before 1.0 the minor is the compatibility number.
You get the library and nothing else. The tests, the command line tools, the FFI
shared object, -Werror and the install rules all default to ON when this is the
top-level project and OFF when it is not, so there is no list of options to switch
off first. Each is still an ordinary option if you want it: WR_BUILD_TESTS,
WR_BUILD_TOOLS, WR_BUILD_FFI, WR_WERROR, WR_INSTALL.
WR_BUILD_RECORD is the exception and defaults ON either way — wrist_record
is a library target rather than developer tooling, and linking the .wrwire
container is an ordinary thing for a consumer to want. It needs the core's internal
symbols, so it is available in a static build only.
Static or shared is BUILD_SHARED_LIBS as usual.
The build also produces libwrist_ffi, which the binding loads. There is
nothing further to install:
PYTHONPATH=python python3 -c "import wrist; print(wrist.VERSION)"An optional bleak transport drives a real
sensor on Linux, macOS and Windows. tools/wr_bench.py is a complete session
written against it — connect, stream, retrieve, record — and is meant to be
copied:
pip install bleak
./tools/wr_bench.py --out bench.wrwire --duration 90bleak is required only for that transport; import wrist neither imports
nor needs it. See python/README.md.
⛔ Do not sweep or fuzz the device's command space. Command f0 reboots the
sensor into firmware-update mode, and it reaches that mode through the ordinary
data characteristic — avoiding the OTA service is not sufficient on its own.
The bytes this library can emit are a short allowlist in src/wr_command.c,
enforced by a single gate. There is no sendRaw() and there will not be one.
Fuzzing the decoder is a different activity and is encouraged.
docs/design.md— how the library works, and why.docs/specification.md— the wire protocol itself.
This project is an independent, unofficial work. It is not affiliated with, authorised, endorsed, sponsored or supported by HackMotion or any of its subsidiaries or affiliates.
This library communicates with the HackMotion sensor hardware over Bluetooth Low Energy, and nothing else. To be explicit about what it does not do:
- It does not interoperate with, extend, modify, replace, emulate or interfere with the HackMotion mobile application in any way.
- It does not connect to, authenticate against, query, scrape or otherwise interact with HackMotion's cloud services, servers, APIs or online accounts.
- It does not access, transmit, retrieve or store any HackMotion account, subscription, licence or user data.
- It does not contain, reproduce or redistribute any HackMotion firmware, application code, or other proprietary or confidential material. This library is an independent implementation of the protocol as observed.
- It does not unlock, bypass or circumvent any paid feature, subscription tier or access control.
Its sole purpose is to allow independent software to read sensor data from a device the user already owns, so that the data can be used in an application of their own choosing. No part of HackMotion's software ecosystem is a target, a dependency, or a point of contact.
The protocol was determined independently, on hardware owned by the author, for the sole purpose of achieving interoperability between the sensor and independent software.
Almost all of it was established by observing the Bluetooth Low Energy
traffic between the sensor and its host, decoding those recordings
offline against known motion, and then reproducing each behaviour from a
Linux machine with the vendor's application closed. Every behavioural
claim in docs/specification.md rests on a
measurement that can be repeated that way.
The set of commands the sensor accepts was additionally established by examining the vendor's own application. That was a safety decision: the only safe way to learn that a particular command reboots the sensor into firmware-update mode is to read it rather than to send it, which is why this library ships a fixed allowlist and refuses every other value by construction. Examining a program to obtain the information necessary for interoperability is expressly permitted by Article 6 of EU Directive 2009/24/EC, with comparable allowances elsewhere. No HackMotion code was copied, translated or included in this project.
"HackMotion" and any associated logos or product names are trademarks of their respective owners. They are used here solely to identify the hardware with which this software is designed to interoperate, as permitted by nominative fair use. Their use does not imply any association, sponsorship or endorsement.
This software is provided "as is", without warranty of any kind. It may stop working at any time — for example following a firmware update — and use is entirely at your own risk. The author accepts no liability for any damage to hardware, loss of data, or effect on any warranty or terms of service applicable to your device.
Please do not contact HackMotion for support with this library. Issues should be raised in this repository.
MIT — full text in LICENSE, and every source file carries an
SPDX-License-Identifier: MIT line.
MIT is the licence that actually matches how this library is meant to be used. It is embedded, and on some platforms it can only be embedded one way: an iOS app is statically linked and code-signed, so a user cannot relink it against a modified library. A copyleft library licence that requires exactly that relinking is unusable there, whatever the application's own licence. MIT asks only that the copyright notice travels with the code.