# BLE Scale Sync       BLE Scale Sync reads weight and body composition from Bluetooth Low Energy smart scales and sends every reading to Garmin Connect, Home Assistant, InfluxDB and other services. It runs on a Raspberry Pi, a Linux server, macOS, Windows or as a Home Assistant add-on, so you do not need the scale's phone app. [Documentation](https://blescalesync.dev) | [Getting Started](https://blescalesync.dev/guide/getting-started) | [Supported Scales](https://blescalesync.dev/guide/supported-scales) | [Exporters](https://blescalesync.dev/exporters) | [Troubleshooting](https://blescalesync.dev/troubleshooting) | [FAQ](https://blescalesync.dev/faq) ## Install ### Docker (Linux) Run the setup wizard in the container to write `config.yaml`, then start the container with host networking and the D-Bus socket mounted. Docker needs a Linux host with BlueZ, such as a Raspberry Pi. The commands and a Compose file are in [Getting Started: Docker](https://blescalesync.dev/guide/getting-started#docker). ### Home Assistant Add-on [](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2FKristianP26%2Fble-scale-sync) The add-on needs Home Assistant OS or Supervised. On HA Container or Core, use Docker; the sensors still appear through MQTT discovery. The [add-on guide](https://blescalesync.dev/guide/home-assistant-addon) covers options, Garmin sign-in and MFA. ### Node.js (Linux, macOS, Windows) ```bash npx ble-scale-sync setup # wizard, writes ./config.yaml CONTINUOUS_MODE=true npx ble-scale-sync # always on ``` Requires Node.js 22.23.4+, 24.22.1+ or 26.12.1+ and a BLE adapter. [Getting Started: Standalone](https://blescalesync.dev/guide/getting-started#standalone) has the prerequisites, a systemd service and the install from a clone. ## Features - Reads scales from Xiaomi, Renpho, Eufy, Yunmai, Beurer, Sanitas, Medisana and other brands, over a GATT connection or from their advertisements ([Supported Scales](https://blescalesync.dev/guide/supported-scales)). - Sends each reading to [13 export targets](https://blescalesync.dev/exporters), among them Garmin Connect, Strava, MQTT with Home Assistant discovery, InfluxDB, webhooks and CSV or JSONL files. - Computes [body composition](https://blescalesync.dev/body-composition) from weight and impedance, with a BMI-based estimate for scales that report no impedance. - Tells household members apart by weight and gives each person their own exporters ([Multi-User](https://blescalesync.dev/multi-user)). - Imports measurements stored in the scale's memory with their original time, for exporters that can record a past measurement ([historical readings](https://blescalesync.dev/exporters#historical-readings)). - Uses the computer's own Bluetooth adapter, an [ESP32 BLE proxy](https://blescalesync.dev/guide/esp32-proxy), an [ESPHome Bluetooth proxy](https://blescalesync.dev/guide/esphome-proxy) or [Home Assistant Bluetooth](https://blescalesync.dev/guide/ha-bluetooth) as the radio ([Bluetooth Transports](https://blescalesync.dev/guide/transports)). - Sets up through an interactive [setup wizard](https://blescalesync.dev/guide/configuration#setup-wizard-recommended), with `scan`, `validate` and `diagnose` commands for checking the result. - Recovers BlueZ on Linux when discovery stops after hours of uptime ([BlueZ stuck state](https://blescalesync.dev/troubleshooting#ble-discovery-stops-working-after-hours-bluez-stuck-state)). - Logs a notice when a new version is out; [Auto Updates](https://blescalesync.dev/guide/auto-update) has recipes for Watchtower, a systemd timer and the add-on. ## Privacy No scale vendor app or account is involved. Readings go only to the exporters you configure. The one other request is a version check, at most once a day, that sends the app version, OS and CPU architecture; those also feed the public [usage stats](https://stats.blescalesync.dev). Set `update_check: false` to turn it off ([what the update check sends](https://blescalesync.dev/faq#what-does-the-update-check-send)). ## Help If your scale is not found or its values look wrong, follow [Troubleshooting](https://blescalesync.dev/troubleshooting). For a scale that is not listed, collect a log with [debug mode](https://blescalesync.dev/troubleshooting#debug-mode) and open an [issue](https://github.com/KristianP26/ble-scale-sync/issues) with the log and the scale model. ## Credits - Scale protocols: many adapters are ported from [openScale](https://github.com/oliexdev/openScale) by oliexdev and contributors. - Eufy P2, P2 Pro, C20 and P3: [bdr99/eufylife-ble-client](https://github.com/bdr99/eufylife-ble-client). - Etekcity Fit 8S: [etekcity_esf551_ble](https://github.com/ronnnnnnnnnnnnn/etekcity_esf551_ble), support contributed by Flautz. - OKOK and Chipsea broadcast: public captures, checked against openScale and [ble_monitor](https://github.com/custom-components/ble_monitor). - PICOOC Mini Lite: openScale (dnsfdv) and the advertisement log in oliexdev/openScale#1512. - A&D UC-352BLE: the capture in oliexdev/openScale#1505 (mrblowntobits) and the GATT dump in [HEADS-project/ThingML-BLE](https://github.com/HEADS-project/ThingML-BLE). - QN-Scale, FITINDEX and a few others: reverse-engineered in this project. - Garmin upload: [garminconnect](https://github.com/cyberjunky/python-garminconnect) by cyberjunky. - BLE: [node-ble](https://github.com/chrvadala/node-ble) (Linux), [@abandonware/noble](https://github.com/abandonware/noble) (Windows), [@stoprocent/noble](https://github.com/stoprocent/noble) (macOS). - ESP32 proxy: [mqtt_as](https://github.com/peterhinch/micropython-mqtt) by peterhinch, [aioble](https://github.com/micropython/micropython-lib/tree/master/micropython/bluetooth/aioble). ## Contributors
KristianP26 1,282 commits |
APIUM 34 commits |
alasano 8 commits |
marcelorodrigo 7 commits |
alexw23 3 commits |
bondesen 3 commits |
albert-canfield 3 commits |
ibrokemypie 3 commits |
fromport 2 commits |
O-Palda 2 commits |
chrisauer 2 commits |
gvarph 2 commits |
vargamihaly 2 commits |
FridoE 2 commits |
boildead 1 commit |
junaidk 1 commit |
hedoric 1 commit |
Bretos 1 commit |
JamieSBenson 1 commit |
totalitarian 1 commit |
ocurero 1 commit |
rolandgeider 1 commit |
sanglt 1 commit |
rjekelmans 1 commit |
intrak 1 commit |