Auto-detect which Health metrics the instance actually knows and enable any that are known but disabled for the user, via GET/PUT configuration. Also makes the previously hardcoded 10s request timeout configurable via NC_TIMEOUT_SECONDS to accommodate slower instances.
Private Health
This project aims to create the necessary building blocks to collect, aggregate, and analyze one's personal health data while maintaining data sovereignty. Instead of closed-source apps and dubious clouds, it should use a FLOSS stack.
Architecture
- Start with what already works. Projects like Gadgetbridge or OpenScale have lively communities and cover a lot of ground. Lean on them whenever possible instead of reinventing the collector layer.
- When a FLOSS bridge is missing, accept a constrained compromise—HealthConnect or a similar on-device broker—so long as it keeps data encrypted locally and gives us clear levers for sync frequency, retention, and audit logs.
- Only build bespoke pieces (Nextcloud health app, dashboards, data science notebooks) where there is a genuine capability gap or user story that no existing FLOSS project covers.
The diagram below mirrors that hierarchy: green blocks are “ready to plug in,” orange blocks still need shaping or configuration, and red blocks mark the blank canvas where we design from scratch. In day-to-day terms, that means we can already sync scales or fitness trackers with minimal effort, but we must design a trustworthy Nextcloud app, decide how dashboards surface trends, and write glue that keeps everything coherent.
HealthConnect remains the pragmatic bridge for now. It lives on the user’s phone, encrypts data, and speaks schemas for dozens of vendors. That buys time for a gentle migration: you can keep your current wearable, pull data into a local store, and steadily replace proprietary parts as FLOSS collectors mature. We should still document a path away from HealthConnect by pairing it with community-built collectors or writing our own bridge once the ecosystem catches up. Any alternative proposal should show the same benefits—broad device coverage, schema richness, and user-controlled sync rules.
flowchart LR
scale(("bathroom<br>scale"))
A["openscale"]
B["openscale sync"]
hc["HealthConnect API<br>(or similar)"]
fitness_tracker(("fitness<br>tracker"))
gb["Gadgetbridge"]
gb_sync["(Gadgetbridge sync?)"]
nc[("Nextcloud")]
bpm(("blood<br>pressure<br> monitor"))
--> bpm_app["BPM app"]
--> hc
scale-->A
--> B
--> hc
fitness_tracker
--> gb
--> gb_sync
--> hc
hc --> ldc["Life Dashboard<br>Companion"]
--> bridge["Bridge / Adapter<br>(auth translation +<br>schema mapping)"]
--> health3["Nextcloud Health v3<br>(weight, steps, activity,<br>blood pressure)"]
health3 -.->|feature request| gap["muscle mass, body water<br>(not yet supported)"]
health3 --> nc
nc --> cA["Web UI<br>(Dashboard, statistics)"]
nc --> cB["mobile devices"]
nc --> cC["...other clients..."]
classDef green fill:#8fb935,stroke:#333;
classDef yellow fill:#e6e22e,stroke:#333;
classDef orange fill:#e09c3b,stroke:#333,stroke-width:4px;
classDef red fill:#e64747,stroke:#333,stroke-width:4px;
class A,B,gb,hc,ldc,health3 green;
class bpm_app,gb_sync,cA,nc,bridge,gap orange;