245 Commits
Author SHA1 Message Date
Ken Blizzard-CaronandJosé Rebelo fd1ffa28da Add Ollee Watch One support
Ollee Watch One is a Nordic-UART (nRF) analog smartwatch. This adds a new
all-Kotlin `ollee` device family providing:

  - time + location sync
  - a single alarm (weekday repetition; one-shot mapped to its next-fire
    weekday, as the watch has no true single-fire mode)
  - world time (one zone, with the world-time face enable and offset register)
  - notification count badge
  - battery voltage
  - activity step sync (on-watch record drain -> activity samples)

The device family follows the existing all-Kotlin coordinator/support
pattern: OlleeDeviceCoordinator (capabilities + discovery), a thin
OlleeDeviceSupport, and per-feature pure-logic files (frame codec, alarm
record builder, weekday/world-time register composer, faces table, activity
records codec), each covered by JVM unit tests.

The wire protocol was worked out clean-room from HCI snoop logs and BLE
probes of my own watch and companion watch faces; nothing here derives from
decompiled or proprietary sources.

Hardware-verified on an Ollee Watch One (firmware 01.05.0000.01.10):
connect/init, battery voltage, firmware version, time+location sync,
activity step sync, world time, and the alarm (set, acknowledged by the
watch, shown on the Alarm face, and physically ringing at the set time).
2026-07-24 22:29:00 +02:00
José Rebelo 93afedce2f Fix crash when opening map view 2026-07-19 14:13:52 +01:00
Arjan Schrijver b1adb29b96 Workouts: Add function to set header photo 2026-07-13 09:03:47 +02:00
Dany MestasandJosé Rebelo fec57bcf83 Xiaomi: parse daily-summary validity bitmap 2026-07-12 16:34:26 +02:00
Vladimir TasicandJosé Rebelo 88e63fcc9b Initial support for AK102 (TopStep / FitCloud) - All features ported and tested 2026-07-12 15:17:52 +02:00
José Rebelo d0199154a9 Merge pull request 'Health Connect: Stabilise sleep session identity to fix dropped nights' (#6301)
Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/6301
2026-07-12 00:35:02 +02:00
Gideon Zenz 7b8093bd72 Health Connect: Replace sleep cursor state-machine with plain forward cursor
The frozen-clientRecordId registry already makes HC upserts idempotent, so
the cursor machinery built to avoid re-processing is redundant. Drop the
persisted finalized flag, the sessionStart-1s cursor-hold, the completed-only
cursor derivation, and the prune-horizon coupling.

Sleep now advances a plain forward cursor (max end synced in slice) like every
other data type. A backward-re-segmenting night re-enters the existing 24h
look-back, overlap-matches its frozen id, and upserts onto the same record, so
advancing the cursor cannot orphan it. Skip the HC write when a re-detected
night's span is unchanged.

Add the missing HealthConnectSleepSession cleanup in
AbstractDeviceCoordinator#deleteDevice.

planSleepSessions: 5 params/two loops -> 3 params/one loop. SleepSessionRow
drops finalized. Schema stays 134 (table new in this PR, no migration).
2026-07-11 22:58:36 +02:00
José Rebelo 6c5455373a GBDaoGenerator: add @Nullable / @NonNull annotations to generated Dao code
Also fixes a crash when uploading a workout without name to Endurain.
2026-07-11 00:09:29 +01:00
Gideon Zenz 473715e45d Health Connect: Stabilise sleep session identity to fix dropped nights
A sleep session's start moves earlier across syncs because SleepAnalysis is
stateless and re-segments as samples arrive. Both the sync cursor and the
clientRecordId were derived from that unstable start, so a night could be
dropped entirely from Health Connect while the device chart still showed it.

Concretely, from issue #6297 (Xiaomi Smart Band 9 Pro, times UTC): one pass
saw only a single-sample fragment at 01:02 and advanced the cursor to
01:01:59. Seconds later the real night re-segmented to 23:08 -> 07:25, whose
start now sat before the cursor, so the slice-ownership rule skipped it -
permanently, since every later slice starts even later. The 7h28m night never
reached HC; only the bogus 1-minute fragment did, stuck under its own id.

Decouple session identity from the start: persist a per-device registry
(HealthConnectSleepSession) of clientRecordId + grown span + finalized flag.
Match each freshly detected session to a stored row by temporal overlap and
reuse its frozen id, so the single HC record grows in place instead of
spawning a new one. This makes HC's upsert idempotent and lets the
slice-ownership rule be removed. Derive the cursor only from completed
sessions (end older than the 6h in-progress threshold), never from an open
one, so a still-growing night is never orphaned by the forward-only cursor.

The registry is short-lived, not a history log: rows are pruned once their end
predates the next scan window (cursor - 24h look-back) and can no longer be
re-detected, which also reclaims open rows stranded by deleted samples. It is
persisted atomically (delete + re-insert in one transaction) so a failed write
cannot wipe the registry and cause id re-minting and duplicate HC records.

In the #6297 case the night's samples stay within the 24h look-back window,
so the dropped session is recovered automatically on the next sync.

Schema 131 -> 132 (new table, created by createAllTables, no migration).
2026-07-05 12:15:06 +02:00
Dany MestasandJosé Rebelo 2cf22b01df Xiaomi: workout details parser 2026-06-29 22:44:20 +02:00
José Rebelo 71b08c90a2 Reduce logging verbosity during code generation
Respect gradle logging levels, and move the per-file logging to INFO
2026-06-28 16:29:51 +01:00
Thomas Kuehne c6102f1af4 reduce DAO related merge conflicts for new devices
- add GenericBodyEnergySample
- add GenericRespiratoryRateSample and AbstractSleepScoreSample
- and GenericSleepScoreSample
- add AbstractMetricSample
- add SleepStageSample and AbstractSleepStageSample
- add additional entries to MetricSample.Metric
2026-06-14 20:13:22 +00:00
Thomas KuehneandJosé Rebelo 6ad6638605 fix device independent typos 2026-06-10 17:43:46 +02:00
José Rebelo 7a986ee5e7 Merge pull request 'MetricsSamples: add experimental UI visualisation paths for TrainingAcuteLoad, TrainingChronicLoad and RestingMetabolicRate' (#6076)
Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/6076
2026-06-01 00:42:44 +02:00
Thomas Kuehne 35d5774c2a Yawell: switch to automatically generated sample providers 2026-05-29 20:33:03 +00:00
Thomas Kuehne a3c7beaf10 Xiaomi: switch to automatically generated sample providers 2026-05-29 20:33:00 +00:00
Thomas Kuehne b1ba12923c Wena3: switch to automatically generated sample providers 2026-05-29 20:32:58 +00:00
Thomas Kuehne 2a9966e203 Ultrahuman: switch to automatically generated sample providers 2026-05-29 20:32:55 +00:00
Thomas Kuehne 577a1fe918 QHybrid: switch to automatically generated sample provider 2026-05-29 20:32:50 +00:00
Thomas Kuehne ae125f1763 Moyoung: switch to automatically generated sample providers 2026-05-29 20:32:48 +00:00
Thomas Kuehne 481477e5a8 MiScale: switch to automatically generated sample provider 2026-05-29 20:32:46 +00:00
Thomas Kuehne 08732d3013 Mijia Lywsd: switch to automatically generated sample provider 2026-05-29 20:32:44 +00:00
Thomas Kuehne 6f51e3a764 Huawei: switch to automatically generated sample providers 2026-05-29 20:32:42 +00:00
Thomas Kuehne 3bab9b8620 Huami: switch to automatically generated sample providers 2026-05-29 20:32:40 +00:00
Thomas Kuehne 129ecb0c8c Glory Fit: switch to automatically generated sample provider 2026-05-29 20:32:37 +00:00
Thomas Kuehne caad9b0af4 Garmin: switch to automatically generated sample providers 2026-05-29 20:32:35 +00:00
Thomas Kuehne 43c92e0317 Cycling Sensor: switch to automatically generated sample provider 2026-05-29 20:32:33 +00:00
Thomas Kuehne 54fa5f3b01 CMF Watch Pro: switch to automatically generated sample providers 2026-05-29 20:32:30 +00:00
Thomas Kuehne 55d3511105 Blood Pressure: switch to automatically generated sample provider 2026-05-29 20:32:24 +00:00
LiJu09andJosé Rebelo 637ca0069c add support for keephealth devices (#5634)
Add support for devices using Keephealth app [https://play.google.com/store/apps/details?id=com.keephealthpro.android&hl=en-US](https://play.google.com/store/apps/details?id=com.keephealthpro.android&hl=en-US)
Currently tested with this "LIGE" smartband [https://www.aliexpress.com/item/1005005057986140.html](https://www.aliexpress.com/item/1005005057986140.html)

Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/5634
2026-05-29 21:49:26 +02:00
Thomas Kuehne 23cf885c13 MetricsSamples: database infrastructure
- fix: use milliseconds instead of seconds to align with most other samples
- DB upgrade copies existing data from GARMIN_RESTING_METABOLIC_RATE_SAMPLE, GENERIC_TRAINING_LOAD_ACUTE_SAMPLE and GENERIC_TRAINING_LOAD_CHRONIC_SAMPLE to GENERIC_METRIC_SAMPLE
- new data is saved to both the specific table as well as GENERIC_METRIC_SAMPLE
- add GenericMetricSampleProvider with service functions
- add GENERIC_MAXIMUM_OXYGEN_UPTAKE parsing for Garmin
2026-05-29 19:28:26 +00:00
Thomas Kuehne 2f2bb33ddf add missing @Override annotations 2026-05-25 17:24:58 +00:00
Steffen WinterandJosé Rebelo 252779596a Gradle: Migrate GBDaoGenerator build file to Kotlin DSL 2026-05-16 09:52:52 +02:00
Steffen WinterandJosé Rebelo d33ada370f Gradle: Migrate to version catalog 2026-05-15 22:02:12 +02:00
Yusuf Cihan 997d338d52 Don't localize DB entity names on generation 2026-04-23 14:59:23 +03:00
Thomas Kuehne f9d9ecce09 Garmin: extract and store metrics (#5708, #5709, #5710)
This extracts the following metrics and stores them in a new GenericMetricSample / GENERIC_METRIC_SAMPLE table:
- endurance score
- functional threshold power
- hill endurance
- hill score
- hill strength
- MET max VO2
- running lactate threshold power
- training readiness

Visualisation and charts aren't part of this PR.
2026-04-12 17:13:10 +00:00
José Rebelo 32d5bbc1c6 Huawei: Add ActivityTrackProvider 2026-03-21 21:55:04 +00:00
José Rebelo 58d6d670f7 Introduce ActivityTrackProvider 2026-03-21 21:55:03 +00:00
Erwin Scheuch-HeiligandJosé Rebelo 9d918bdb3b Initial support for laxasfit devices (#5774)
# laxasfit support

With reference to issue #5640 here comes the initial implementation of the first supported laxasfit device:
- Q11 smartwatch

The used protocol is a derivate of the FitPro protocol, using
- different UUIDs
- different message ID's
- additional CRC

Protocol details are documented in the related issue #5640

Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/5774
Co-authored-by: Erwin Scheuch-Heilig <fr3ts0n@gmx.at>
Co-committed-by: Erwin Scheuch-Heilig <fr3ts0n@gmx.at>
2026-02-14 23:53:04 +01:00
José Rebelo 9dd91c4349 Garmin: Display sleep restless moments 2026-01-23 21:14:55 +00:00
José Rebelo e2c375eaf3 GBDaoGenerator: Generate sample providers
Most "basic" sample providers are the same, this reduces the boilerplate
code necessary to add a new sample to the database.
2026-01-20 23:03:57 +00:00
José Rebelo 5cb2425643 SBM67: Extract blood pressure profile 2026-01-20 13:15:04 +00:00
Daniele GobbettiandJosé Rebelo 1257f9d3f3 add support for SBM67 Blood Pressure device 2026-01-20 13:15:04 +00:00
José Rebelo 489bff52e2 Garmin: Allow firewalled app internet access 2026-01-18 16:21:34 +00:00
José Rebelo ad7ed39a2a HeartRateProfile: Parse and persist RR intervals 2026-01-17 17:39:34 +00:00
Wa-dotandJosé Rebelo 52c5f34b27 Fix error path in GBDaoGenerator 2026-01-17 17:32:13 +01:00
José Rebelo 4ec30d1e52 OneTouch: Initial support 2026-01-06 20:57:32 +00:00
Arjan Schrijver 19147e1e36 Pebble: Check for watchapp updates if internet is available 2025-12-28 16:59:37 +01:00
Arjan SchrijverandArjan Schrijver d431d73dc3 Remove obsolete custom URL Filter code 2025-12-25 14:45:08 +01:00
Arjan SchrijverandArjan Schrijver ba0e8c3d86 Add preferences screen and URL allowlist functionality 2025-12-25 14:45:08 +01:00