ble-scale-sync
Reads BLE smart scales (23 brands) via built-in Bluetooth, calculates body composition, and exports to Garmin Connect, MQTT/Home Assistant, InfluxDB, and more.
BLE Scale Sync
A cross-platform CLI tool that reads body composition data from 20+ BLE smart scales and exports to Garmin Connect, Strava, MQTT (Home Assistant), InfluxDB, Webhooks, Ntfy, and local files (CSV/JSONL). No phone app needed. Your data stays on your device.
Documentation · Getting Started · Supported Scales · Exporters · FAQ
Why This Exists
Most BLE smart scales measure weight and body impedance over Bluetooth, but their companion apps have no way to sync data to Garmin Connect. The only workflow was: open the phone app, wait for it to sync, then manually type the numbers into Garmin. Every single time.
I didn't want to depend on a phone app. So I built this tool. A Raspberry Pi Zero 2W sits next to the scale, always on, always listening. Step on the scale, wait a few seconds, and the reading appears in Garmin Connect - no phone needed, no app, no manual entry. It just works.
If you can't have a Pi next to your scale, a cheap ESP32 proxy can sit nearby and relay BLE data over WiFi to a Docker server anywhere on your network. See the ESP32 BLE proxy guide.
Quick Start
Docker (Linux)
# Configure
docker run --rm -it --network host --cap-add NET_ADMIN --cap-add NET_RAW \
--group-add 112 -v /var/run/dbus:/var/run/dbus:ro \
-v ./config.yaml:/app/config.yaml \
-v ./garmin-tokens:/app/garmin-tokens \
ghcr.io/kristianp26/ble-scale-sync:latest setup
# Run (continuous mode, auto-restart)
docker run -d --restart unless-stopped --network host \
--cap-add NET_ADMIN --cap-add NET_RAW \
--group-add 112 -v /var/run/dbus:/var/run/dbus:ro \
-v ./config.yaml:/app/config.yaml:ro \
-v ./garmin-tokens:/app/garmin-tokens:ro \
-e CONTINUOUS_MODE=true \
ghcr.io/kristianp26/ble-scale-sync:latest
Ideal for Raspberry Pi, NAS, and headless servers. Works alongside any Home Assistant install (Container, Core, OS) via MQTT auto-discovery.
Home Assistant Add-on
If you run Home Assistant OS or Supervised, one click is all it takes:
The badge opens your Home Assistant instance, confirms the repository, and shows BLE Scale Sync in the Add-on Store ready to install.
Prefer manual steps?
- Settings > Add-ons > Add-on Store > three-dot menu > Repositories
- Add
https://github.com/KristianP26/ble-scale-syncand install BLE Scale Sync
The add-on handles config through the UI, auto-detects the Mosquitto broker for Home Assistant auto-discovery, and bootstraps Garmin tokens on first start. See the Home Assistant Add-on guide for the full option reference, MFA workaround, and custom config mode.
Note: Add-ons are not available on HA Container or HA Core installs (no Supervisor). Use the Docker method above instead — sensors still appear in HA via MQTT auto-discovery.
Standalone (Node.js — Linux, macOS, Windows)
Runs natively on all major desktop and server operating systems. No containers required.
git clone https://github.com/KristianP26/ble-scale-sync.git
cd ble-scale-sync && npm install
npm run setup # interactive wizard
CONTINUOUS_MODE=true npm start # always-on
Requires Node.js v20.19+ and a BLE adapter. See the full install guide for prerequisites and systemd service setup.
Features
- 20+ scale brands — Xiaomi, Renpho (Elis 1, FITINDEX, Sencor, QN-Scale), Eufy, Yunmai, Beurer, Sanitas, Medisana, and more
- 7 export targets — Garmin Connect, Strava, MQTT (Home Assistant), InfluxDB, Webhook, Ntfy, File (CSV/JSONL)
- 10 body metrics — BIA-based body composition from weight + impedance
- Multi-user — automatic weight-based identification with per-user exporters
- Interactive setup wizard — scale discovery, exporter config, connectivity tests
- BLE diagnostic tool —
npm run diagnosefor detailed BLE troubleshooting - Home Assistant Add-on — one-click install via My Home Assistant badge, MQTT auto-discovery, UI-driven config, Garmin token bootstrap, and MFA workaround
- ESP32 BLE proxy — use a remote ESP32 as a BLE radio over MQTT, with a built-in embedded broker for zero-config setup, simplified Docker deployment, and optional display
- ESPHome Bluetooth proxy — reuse an existing ESPHome BT proxy mesh (Home Assistant) as a BLE radio via Native API (experimental, broadcast-only in phase 1)
- BLE adapter selection —
ble.adapter: hci1for multi-adapter setups (Linux) - Broadcast mode — supports non-connectable scales that only advertise weight via BLE advertisements
- Update check — optional, anonymous version check after each measurement (opt-out via
update_check: false); see the auto update guide for Watchtower, systemd timer, and HA add-on recipes - Cross-platform — Linux (Docker + native), macOS, Windows
- Private — your data stays on your device, no vendor cloud
Credits
- Scale protocols - many adapters ported from openScale (oliexdev and contributors); Eufy P2 / P2 Pro ported from bdr99/eufylife-ble-client; QN-Scale / FITINDEX and a few others reverse-engineered in this project
- Garmin upload - powered by garminconnect by cyberjunky
- BLE - node-ble (Linux), @abandonware/noble (Windows), @stoprocent/noble (macOS)
- ESP32 proxy - mqtt_as by peterhinch, aioble
Contributors
KristianP26 |
APIUM |
marcelorodrigo |
fromport |
Contributing
See CONTRIBUTING.md for development setup, project structure, and how to add new scale adapters or exporters.
License
GPL-3.0. See LICENSE for details.