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.

C++BLEMachine learningHome AssistantMQTT

hms-scale Angular dashboard showing per-user weight and body-composition trends

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 production

2 · 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_colada

Connecting 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}/*/config

Weigh in, privately

The full C++ service, ML engine, REST API, MQTT discovery and Angular dashboard are open source under the MIT license.