A smart scale that knows who stepped on it
hms-scale is a tiny 5 MB C++ service for an Etekcity BLE smart scale. It identifies which household member just weighed in with a 4-stage hybrid engine (deterministic rules + a Random Forest model), calculates full BIA body composition, and publishes every metric to Home Assistant over MQTT — with an Angular dashboard, habit analytics, and 108 unit tests behind it.

The Angular 21 dashboard — per-user weight, body fat, muscle and trend charts.
What it does
Knows who you are
A 4-stage identifier picks the right household member: exact weight match (±0.5 kg, 95% confidence), a Random Forest ML model (≥80%), a user-defined tolerance match (75%), then manual assignment as a fallback.
Full body composition
From weight and impedance it derives body fat (Kyle), muscle mass (Janssen), body water (Watson), BMR (Mifflin-St Jeor), bone mass (Hologic), plus visceral fat, BMI, protein and metabolic age.
Learns & advises
A background ML trainer (GridSearch, 5-fold CV) keeps identification sharp, while a habit analyzer tracks consistency, streaks, trends, and weight predictions with recommendations.
Get it running
1 · Build
Install the deps, then build the C++ backend and the Angular frontend. Add -DBUILD_WITH_BLE=ON to talk to the scale directly over BlueZ.
mkdir build && cd build
cmake -DBUILD_WITH_BLE=ON ..
make -j$(nproc)
./tests/run_tests
cd ../frontend
npm install
npx ng build --configuration production2 · Configure & run
Copy the sample config (or use env vars) for PostgreSQL and MQTT, then launch. The web UI lives on port 8889 and config is editable at /settings.
cp config.json.example ~/.hms-colada/config.json
# edit DB + MQTT credentials
./build/hms_coladaConnecting the scale
Two modes feed the same pipeline. Use direct BLE if your server has Bluetooth, or the ESP32-C3 gateway (hms-scale-esp) that POSTs measurements over HTTP for headless servers.
{
"ble": {
"enabled": true,
"scale_mac": "D0:4D:00:51:4F:8F"
}
}No Bluetooth on the host? Skip BLE and let the ESP32 hit POST /api/webhook/measurement instead — MQTT and analytics work the same.
Home Assistant & MQTT
hms-scale auto-discovers in Home Assistant, publishing 12 sensors per user. State is retained per metric, with an online/offline LWT on colada_scale/status.
giraffe_scale/measurement # in: {"weight_kg","impedance"}
colada_scale/user_selector/set # in: manual user pick from HA
colada_scale/{user}/weight # out: per-metric state (retained)
colada_scale/{user}/body_fat
colada_scale/{user}/muscle_mass
# ... bmi, bmr, body_water, bone_mass,
# visceral_fat, metabolic_age, protein, lean_mass
# HA discovery configs published to:
homeassistant/sensor/colada_scale_{user}/*/configWeigh in, privately
The full C++ service, ML engine, REST API, MQTT discovery and Angular dashboard are open source under the MIT license.