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
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.
# 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:latestIdeal for Raspberry Pi, NAS, and headless servers. Works alongside any Home Assistant install (Container, Core, OS) via MQTT auto-discovery.
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.
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-onRequires Node.js v20.19+ and a BLE adapter. See the full install guide for prerequisites and systemd service setup.
- 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
- 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
See CONTRIBUTING.md for development setup, project structure, and how to add new scale adapters or exporters.
GPL-3.0. See LICENSE for details.