Changelog
All notable changes to this project are documented here. Format based on Keep a Changelog.
v1.7.1 latest
2026-03-30
Fixed
- Update check: replaced strict 24-hour cooldown with calendar-day (UTC) comparison. Users who weigh in slightly earlier each day (e.g. 7:00 AM, then 6:55 AM) were being skipped
v1.7.0
2026-03-29
Added
- Update check with anonymous usage statistics (#87). After each successful measurement (max once per 24h), the app checks for newer versions. Only the app version, OS, and architecture are sent via the User-Agent header. Disable with
update_check: falsein config.yaml - Setup wizard shows an update notice before the first step if a newer version is available
- Public stats dashboard at stats.blescalesync.dev with aggregated anonymous data
v1.6.4
2026-03-27
Fixed
- BLE: use ATT Write Request instead of Reliable Write in node-ble handler, fixing "Operation is not supported" errors on Medisana BS430 and similar scales that do not support reliable writes (#85)
Improved
- BLE: GATT characteristic flags are now logged during discovery (
DEBUG=true) for easier troubleshooting
Thanks
v1.6.3
2026-03-04
Fixed
- Docker: removed cleanup workflow that was deleting multi-arch platform manifests, making all Docker images unpullable (#74, #76)
Thanks
- @marcelorodrigo for reporting the broken Docker images (#74)
- @mtcerio for the additional report (#76)
v1.6.2
2026-03-02
Changed
- CI: Docker
latesttag now only applies to GitHub releases, not every push to main (#70) - CI: Removed push-to-main Docker build trigger (#71)
- Docs: SEO meta keywords added to all documentation pages (#69)
- Docs: Alternatives page updated with Strava, file export, and ESP32 proxy sections (#68)
- Docs: ESP32 BLE proxy section added to getting started guide (#67)
v1.6.1
2026-03-01
Fixed
- BlueZ stale discovery recovery after Docker container restart. Adds kernel-level adapter reset via
btmgmtas Tier 4 fallback when D-Bus recovery fails, plus proactive adapter reset in Docker entrypoint (#39, #43)
Changed
- CI: Docker cleanup workflow removes PR images and untagged versions from GHCR (#58)
- Docs: Contributors section added to README
- Node.js: minimum version bumped to 20.19.0 (required by eslint 10.0.2)
- Deps: @stoprocent/noble 2.3.16, eslint 10.0.2, typescript-eslint 8.56.1, @types/node 25.3.3, @inquirer/prompts 8.3.0
v1.6.0
2026-02-28
Added
- ESP32 BLE proxy (experimental) for remote BLE scanning over MQTT. Use a cheap ESP32 board (~8€) as a wireless Bluetooth radio, enabling BLE Scale Sync on machines without local Bluetooth. Supports both broadcast and GATT scales
- ESP32 display board (Guition ESP32-S3-4848S040) with LVGL UI showing scan status, user matches, and export results
- Beep feedback on ESP32 boards with I2S buzzer (Atom Echo) when a known scale is detected
- Streaming BLE scan for ESP32-S3 boards with hardware radio coexistence
- Docker mqtt-proxy compose (
docker-compose.mqtt-proxy.yml) requiring no BlueZ, D-Bus, orNET_ADMIN - Setup wizard includes interactive mqtt-proxy configuration
BLE_HANDLER=mqtt-proxyenvironment variable as alternative to config.yaml- ESP32 proxy documentation page with architecture diagram, flashing guide, and MQTT topics reference
Changed
- Renpho broadcast parsing consolidated into QN scale adapter
- Landing page updated with ESP32 proxy and Setup Wizard feature cards
Thanks
v1.5.0
2026-02-24
Added
- File exporter (CSV/JSONL) for local measurement logging without external services. Auto-header CSV with proper escaping, JSONL one-object-per-line, per-user file paths, and directory writability healthcheck
- Strava exporter with OAuth2 token management. Updates athlete weight via PUT /api/v3/athlete. Automatic token refresh, restricted file permissions (0o600), and interactive setup script (
npm run setup-strava) - Strava API application setup guide in documentation with step-by-step instructions
v1.4.0
2026-02-24
Added
- BLE diagnostic tool (
npm run diagnose) for detailed device analysis: advertisement data, service UUIDs, RSSI, connectable flag, and step-by-step GATT connection testing - Broadcast mode for non-connectable QN-protocol scales (#34). Reads weight directly from BLE advertisement data without requiring a GATT connection
- Garmin 2FA/MFA support in
setup_garmin.py(#41 by @APIUM)
Fixed
- QN broadcast parser: corrected byte layout (LE uint16 at bytes 17-18, stability flag at byte 15)
- ES-CS20M: service UUID 0x1A10 fallback for unnamed Yunmai-protocol devices (#34)
- ES-CS20M: 0x11 STOP frame support as stability signal (#34)
Changed
- CI: Node.js 24 added to test matrix (required check)
- CI: PR-triggered Docker image builds with
pr-{id}tags (#44) - Deps: ESLint v10, typescript-eslint v8.56
v1.3.1
2026-02-22
Fixed
- ES-CS20M: support 0x11 STOP frame as stability signal for Yunmai-protocol variant (#34)
- ES-CS20M: add service UUID 0x1A10 fallback for unnamed devices (#34)
Added
- Docs: BLE handler switching guide in troubleshooting
- Docs: Pi Zero W (ARMv6) not supported notice (#42)
- Docs:
StartLimitIntervalSec=0in systemd service example
Changed
- CI: PR-triggered Docker image builds with
pr-{id}tags (#44) - CI: Node.js 24 added to test matrix
- Deps: ESLint v10, typescript-eslint v8.56
v1.3.0
2026-02-16
Added
- Garmin multi-user Docker authentication -
setup-garmin --user <name>and--all-userscommands setup_garmin.py --from-configmode reads users and credentials fromconfig.yaml--token-dirargument for per-user token directories (persisted via Docker volumes)pyyamldependency for config.yaml parsing in Python scripts- Docker multi-user volume examples in
docker-compose.example.ymland docs
Fixed
- Friendly error message when D-Bus socket is not accessible in Docker instead of raw
ENOENTcrash (#25)
Changed
- Wizard passes Garmin credentials via environment variables instead of CLI arguments (security)
v1.2.2
2026-02-14
Added
- Annotated
config.yaml.examplewith all sections and exporters CONTRIBUTING.mdwith development guide, project structure, and test coverageCHANGELOG.md- Documentation split into
docs/— exporters, multi-user, body composition, troubleshooting
Changed
- README rewritten (~220 lines, Docker-first quick start, simplified scales table)
- Dev content moved into
CONTRIBUTING.md
v1.2.1
2026-02-13
Added
- Docker support with multi-arch images (
linux/amd64,linux/arm64,linux/arm/v7) Dockerfile,docker-entrypoint.sh,docker-compose.example.yml- GitHub Actions workflow for automated GHCR builds on release
- Docker health check via heartbeat file
v1.2.0
2026-02-13
Added
- Interactive setup wizard (
npm run setup) — BLE discovery, user profiles, exporter configuration, connectivity tests - Edit mode — reconfigure any section without starting over
- Non-interactive mode (
--non-interactive) for CI/automation - Schema-driven exporter prompts — new exporters auto-appear in the wizard
v1.1.0
2026-02-13
Added
- Multi-user support — weight-based user matching (4-tier priority)
- Per-user exporters (override global for specific users)
config.yamlas primary configuration format (.envfallback preserved)- Automatic
last_known_weighttracking (debounced, atomic YAML writes) - Drift detection — warns when weight approaches range boundaries
unknown_userstrategy (nearest,log,ignore)- SIGHUP config reload (Linux/macOS)
- Exporter registry with self-describing schemas
- Multi-user context propagation to all 5 exporters
v1.0.1
2026-02-13
Changed
- Configuration is now
config.yaml-first with.envas legacy fallback
v1.0.0
2026-02-12
Added
- Initial release
- 23 BLE scale adapters (QN-Scale, Xiaomi, Yunmai, Beurer, Sanitas, Medisana, and more)
- 5 export targets: Garmin Connect, MQTT (Home Assistant), Webhook, InfluxDB, Ntfy
- BIA body composition calculation (10 metrics)
- Cross-platform BLE support (Linux, Windows, macOS)
- Continuous mode with auto-reconnect
- Auto-discovery (no MAC address required)
- Exporter healthchecks at startup
- 894 unit tests across 49 test files