# openScale BT-vågar — integrationsplan Bygga in [openScale](https://github.com/oliexdev/openScale):s Bluetooth- drivrutiner i FitnessDroid så att vägningar (vikt + %muskler/fett/vatten) kan hämtas direkt från en BT-våg in i appens kroppsmätningar. ## Beslut (2026-07-26) - **Licens: FitnessDroid relicensas till GPL-3.0.** openScale är GPL-3.0; att bädda in deras kod kräver att hela appen blir GPL-3.0. LICENSE byts, och källfilerna som kommer från openScale behåller sina copyright-headers. - **Alla drivrutiner portas** (hela `core/bluetooth`-paketet, ~55 handlers + adaptrar), inte bara en modell. `ScaleFactory` auto-detekterar vågen vid skanning precis som i openScale. - **Attribution:** en **About**-vy under Profil som anger att appen använder openScales drivrutiner, med länk till deras GitHub och GPL-3.0-licensen, plus en lista på öppen källkod som används (openScale, Blessed-Kotlin). ## Teknik (bekräftat från repot) - openScale använder **Blessed-Kotlin** (coroutine-BLE-wrapper) — läggs till som Gradle-beroende; vi portar drivrutinerna som ligger ovanpå, inte BLE-plumbingen. - `ScaleDeviceHandler.supportFor(device)` → `DeviceSupport` (displayName, linkMode, tuningProfile). `ScaleFactory` returnerar första matchande handler. - Tre kopplingslägen: `CONNECT_GATT`, `BROADCAST_ONLY`, `CLASSIC_SPP` med var sin adapter (Gatt/Broadcast/Spp). - `ScaleMeasurement` bär weight, fat, water, muscle, visceralFat, bone, lbm, bmr, protein, impedance m.m. → vi mappar weight + muscle/fat/water till vår `BodyMeasurement` (resten kan tas in senare). - minSdk 31 matchar vår app (BLE-permissions `BLUETOOTH_SCAN`/`_CONNECT`). ## Fallgrop: impedansvågar behöver användarprofil Vissa vågar skickar bara **rå impedans**; openScale räknar då själv ut fett/muskler/vatten med en formel som kräver **längd, ålder, kön** (ScaleUser). Vi måste därför: - Lägga till längd/födelseår/kön i profilen (se API-ändring nedan). - Porta openScales BIA-beräkning för de vågar som kräver den. Vågar som räknar ombord och skickar färdiga procent behöver inte detta. ## API-ändring: spara användarens längd (+ ålder/kön) Längden ska sparas **på servern** (gym-API:t) så att den är gemensam för app och webb, överlever ominstallation, och kan användas för mer korrekta beräkningar: - **BIA/kroppssammansättning:** openScales formler för impedansvågar kräver längd (+ ålder + kön) för att ge korrekta %fett/muskler/vatten. - **Energiförbrukning:** med längd (+ ålder + kön) kan kaloriberäkningen gå från ren MET × vikt × tid till en BMR-baserad uppskattning (Mifflin–St Jeor: `10·vikt + 6.25·längd − 5·ålder + könskonstant`), vilket ger rimligare siffror per pass. **Backend (brasse-pc.eu-v2, gym-api):** - Utöka `User` med `HeightCm` (double?), och för full BIA även `BirthDate` (eller `BirthYear`) och `Sex` (enum/sträng). Nullable + bakåtkompatibla. - Migration (körs automatiskt vid uppstart, samma mönster som `BodyMeasurement`). - Exponera i `myProfile`-query och en `updateProfile`-mutation (eller utöka `updateBodyWeight` → `updateProfile` med längd/ålder/kön). - Deploya om gym-api-prod + -test (serialiserat bygge, se [[pi5-ci-concurrency]]). **App:** profil-fält för längd (och ålder/kön) som läser/skriver mot API:t; cachas lokalt (som kroppsvikten) för offline och för BIA-beräkningen. **Webb (brasse-pc.eu-v2):** samma fält på profil-fliken via `updateProfile`. ## Milstolpar (byggbara steg) 1. **Grund + licens + About** — LICENSE → GPL-3.0; `blessed-kotlin`-beroende; BLE-permissions i manifestet; About-vy under Profil (attribution + länkar + openetlicens-text); körruntime-permission-flöde. *Ingen vågkod än — bara att allt kompilerar och About visas.* 2. **Porta bluetooth-paketet** — vendora `com.health.openscale.core.bluetooth` (ScaleCommunicator, ScaleFactory, scales/, adaptrar, data/, libs/) med copyright-headers kvar. Slimmad `ScaleMeasurement`/`ScaleUser`. Får det att kompilera mot Blessed. 3. **Skanna + koppla** — "Anslut våg" i inställningar: skanna BLE, kör `ScaleFactory` mot varje enhet, visa matchade vågar, spara vald MAC. 4. **Väg dig-flöde** — knapp som skannar/kopplar vald våg, tar emot en `ScaleMeasurement`, förhandsvisar och sparar via `addBodyMeasurement` (offline-kön tar resten). Live-status ("står på vågen…"). 5. **API: längd (+ ålder/kön)** — utöka gym-API:ts `User` med `HeightCm` (+ `BirthDate`/`Sex`), migration, `myProfile` + `updateProfile`, deploy. App + webb får profilfält. Se "API-ändring" ovan. 6. **Impedansvågar + bättre kalorier** — BIA-beräkning för vågar som skickar rå impedans (använder längd/ålder/kön), och BMR-baserad energiförbrukning. Verifieras mot din våg. 7. **Polering + docs** — felhantering, timeouts, ominställning av våg; uppdatera README/wiki + infra-Doc (GPL-relicens noterad). ## Öppna frågor / risker - **Vilken våg du har** avgör om milstolpe 5 (impedans-BIA) behövs eller om din våg skickar färdiga procent. Identifieras i milstolpe 3 via skanning. - Blessed-Kotlins exakta koordinater/version verifieras vid milstolpe 1. - APK växer (drivrutiner + BLE-lib) — troligen någon MB, oproblematiskt. - GPL-relicens är permanent för koden; medvetet val.