Commit Graph
100 Commits
Author SHA1 Message Date
Thomas Kuehne e01599a9e3 Garmin: enhance activity summaries
- add fallback sources for HR_AVG, TOTAL_ASCENT, TOTAL_DESCENT, AVG_POWER, BODY_ENERGY_AT_START and BODY_ENERGY_AT_END
- fallback to lap average speed if the lap enhanced average speed isn't available
- ensure that paces/speeds are only rounded by WorkoutValueFormatter and not also by GarminWorkoutParser
- add diving lap summary for apnea
- add scuba tank summary
- fix diving summary gaps when CNS, N2 load or O2 toxicity values are 0
2026-04-25 00:16:16 +00:00
Thomas Kuehne 0372f855c9 Garmin: code cleanup in FitImporter / GarminWorkoutParser 2026-04-24 20:54:30 +00:00
Thomas Kuehne 748e388bdd Garmin: extend AntGadget support for dual ANT+ / Bluetooth devices 2026-04-24 20:54:19 +00:00
Thomas Kuehne 0e010c0ce0 Garmin: decode more FIT messages and fields 2026-04-24 20:53:53 +00:00
Thomas Kuehne f0c5748eaa Garmin: add more sport / subsport codes 2026-04-24 20:50:55 +00:00
Thomas Kuehne fc36a2e073 Garmin: fix UINT64Z BaseType from 0x8F (UINT64) to 0x90 2026-04-24 20:49:38 +00:00
Thomas KuehneandJosé Rebelo 9b9e6dd34a Garmin: add more ANT+ IDs and fallback to formatted ANT ID before serial number 2026-04-19 14:19:52 +02:00
Thomas Kuehne cd09de5ebb Garmin: use more human friendly names for ANT+ gear in activity summaries 2026-04-16 10:19:41 +00:00
Thomas Kuehne 426a88f020 Garmin: enhance activity summaries
- prioritise names: workout name > session sports profile > sport name
- gracefully fallback from Enhanced Respiration to plain Respiration
- gracefully fallback from Enhanced Speed to plain Speed
- add gear info showing last battery reading of connected devices
- add altitude min/max/avg
- add user heart rate (min/max/resting)
- add workout feel (0 - 100%)
- add device battery state (initial / final)
- add ebike battery state (initial / final)
- add more recovery, work, energy statistics
- diving: add SAC (Surface Air Consumption)
- diving: add water density with fallback to water type
- diving: ignore disabled gases
2026-04-14 05:00:58 +00:00
Thomas Kuehne 1b8c103610 Garmin: streamline adding data to activity summary
ActivitySummaryData already checks if the value is `null`.
Unless forcing a display or performing calculations, there is no need to also check for `null` values in GarminWorkoutParser.
2026-04-13 19:25:42 +00:00
Thomas Kuehne 35d2d31093 Garmin: map more Session, Lap, Monitoring, Record and EcgSummary fit fields 2026-04-13 19:24:59 +00:00
Thomas Kuehne 45318a3c84 fix: ActivityPoint.getN2Load 2026-04-13 19:24:18 +00: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
Thomas KuehneandJosé Rebelo bde914fad2 Garmin: extend support for non-GPS activities
- chart elevation even if the activity has no GPS recording (e.g. treadmill and floor climbing)
- added distance chart
- added stride chart
- added step length chart
- added body energy chart - 24/7 energy level
- added stamina chart - activity specific endurance capacity
- added N2 load (Nitrogen) chart for diving
- added CNS toxicity (Central Nervous System) chart for diving
- added oxygen toxicity summary for diving
- added surface interval summary for diving
- adjusted dive summary layout
2026-04-11 01:43:45 +02:00
Thomas KuehneandJosé Rebelo 5b2f982509 Garmin: fix identification of relevant FitDiveSummary session record
The logic depended on the sequence of records and not their actual content.
2026-04-11 01:43:45 +02:00
Thomas KuehneandJosé Rebelo 4da08f7968 Garmin: ignore Null Island for ActivitySummaryData.setHasGps
Some indoor tracks, like Edge1030's Cycling / Virtual Activity, record all points with fake Null Island (0°N 0°E) position.
2026-04-11 01:43:45 +02:00
Thomas KuehneandJosé Rebelo 9344940260 extend support for non-GPS activities
This enhances the general GB code _without_ the device specific adjustments required to actually display values:
- chart elevation even if the activity has no GPS recording (e.g. treadmill and floor climbing)
- added distance chart
- added stride chart
- added step length chart
- added body energy chart - 24/7 energy level
- added stamina chart - activity specific endurance capacity
- added N2 load (Nitrogen) chart for diving
- added CNS toxicity (Central Nervous System) chart for diving
- added oxygen toxicity summary for diving
- added surface interval summary for diving
2026-04-11 01:43:45 +02:00
Thomas KuehneandJosé Rebelo 536ad17c4d Garmin HRM 600: Initial support
Based on feedback in #5633
2026-04-11 00:03:36 +02:00
Thomas Kuehne 9edeec2a57 Garmin: fix start time handling for stopwatch (#4507) and prepare for multi sessions in one file (#5862. #5860)
Prioritise the session specific start time over the file creation time.
2026-04-10 17:33:39 +00:00
Thomas KuehneandJosé Rebelo fc6dcc793b Garmin: export FIT laps as GPX track segments 2026-04-07 00:14:44 +02:00
Thomas KuehneandJosé Rebelo 68aa74bc39 GPX: fix redirecting URLs in xsi:schemaLocation
Some XML parsers don't support HTTP redirection for schemaLocation so encode the actual URLs.
2026-04-07 00:14:06 +02:00
Thomas Kuehne d65b1fd853 DeviceCoordinator.findInstallHandler: add Bundle parameter
EventHandler.onInstallApp already has a Bundle parameter for passing options to install handlers.
This prepares the infrastructure for PR #5923.
2026-04-03 20:57:30 +00:00
Thomas KuehneandJosé Rebelo 05b229c833 Gpx: export track name
Some Garmin devices only read gpx/trk/name and ignore gpx/metadata/name.
Export the same name to both.
2026-04-03 18:53:54 +02:00
Thomas Kuehne de1c74f223 fix: always use GPSCoordinate.hasAltitude to check if altitude value is valid
Altitude is a floating point value that supports NaN so it is too easy to use the wrong comparison operation.
2026-04-03 16:40:55 +00:00
Thomas Kuehne 3cd5ae847b Garmin: add support for installing .FIT location and segment files
The uploaded location file creates new waypoints on the device by updating the LCTNS.FIT / Location.fit file.
2026-03-30 01:26:02 +02:00
Thomas KuehneandJosé Rebelo 6fcb07ea98 GPX: add support for importing older GPX version 1.0 files
Also takes care of slightly quirky GPX 1.1 files that contain extra spaces, XML comments or use floats instead of integers for cadence and heart rate.
2026-03-25 23:17:42 +01:00
076a85d762 Garmin: fix CobsCoDec.encode
Co-authored-by: José Rebelo <joserebelo@outlook.com>
2026-03-21 00:16:35 +01:00
Thomas KuehneandJosé Rebelo 165cd803a0 Garmin: fuzzy test for CobsCoDec 2026-03-21 00:16:35 +01:00
Thomas KuehneandJosé Rebelo fde8563b4a backport upstream BouncyCastle fixes
aligned with bcgit/bc-java@7b094ad188
2026-03-17 00:00:31 +01:00
Thomas KuehneandJosé Rebelo e6bdac82d4 Garmin: GpxRouteFileConverter add depth, temperature, speed and tests 2026-03-16 23:31:39 +01:00
Thomas Kuehne d985e0ab7e strings: clean-up British vs US spellings and GPS 2026-03-14 19:39:59 +01:00
Thomas Kuehne 4ebb31f255 add missing @Override annotations 2026-03-14 11:02:58 +01:00
Thomas KuehneandJosé Rebelo cb5634dcfe Garmin: add Recovery Heart Rate and Rate of Perceived Exertion to activity summary
RPE / rate of perceived exertion
https://support.garmin.com/en-US/?faq=8nISJXqSZVAI3Td4IWRqsA

recovery heart rate
https://support.garmin.com/en-US/?faq=3HTTUrSoRF51m8vGUtMhY9
2026-03-11 22:13:16 +01:00
Thomas KuehneandJosé Rebelo 07b1e593b3 nQuant: backport Gadgetbridge fixups 2026-03-09 22:28:03 +01:00
Thomas KuehneandJosé Rebelo c8da8b4717 nQuant: refresh to mcychan/nQuant.android@12822f15c9 2026-03-09 22:28:03 +01:00
Thomas KuehneandJosé Rebelo 26cf09d700 Garmin: move test FIT data into files 2026-03-09 22:15:35 +01:00
Thomas Kuehne 98fe5caaa4 Garmin: FIT file type 57 is SPORTS_BACKUP 2026-03-08 08:30:55 +01:00
Thomas KuehneandJosé Rebelo 7dc6044138 BleNamesResolver: add more standard services and characteristics 2026-03-07 21:28:35 +01:00
Thomas KuehneandJosé Rebelo bacc85bcb8 Garmin: add sleep disruption FIT fields 2026-02-28 18:36:59 +01:00
Thomas Kuehne 9a9ba5b30c Garmin: add more FIT sport types
example FIT files for testing:

STREET_RUN (sport:1, subsport:2)
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2025/Activity_20250410_Running_Nike_1794463148babf53fb33b260a19a91fe.fit

VIRTUAL_CYCLING (sport:2, subsport:58)
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2026/Activity_20260110_Cycling_Mywhoosh_cbefa61fcd6d7c0f9916e07d119fbceb.fit

INDOOR_ROWING (sport:4, subsport:14)
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2017/Activity_20170518_FitnessEquipment_VivoActiveHr_94dbffeb8be296bb39027edc041a2963.fit

STOPWATCH (sport:52, subsport:0)
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2023/Activity_20221129_52_Fenix5Plus_43621059f6fc664f8f3b577e2f1d8695.fit

CCR_DIVING (sport:53, subsport:63)
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2017/Activity_20230816_Diving_Descent_d602dcb95b6701d1921e9d6a26594ebe.fit
2026-02-28 17:39:51 +01:00
Thomas Kuehne 17a4338984 Garmin: add more FILETYPEs 2026-02-21 12:55:02 +01:00
Thomas KuehneandJosé Rebelo 84dab742b1 GPXExporter: fix generated XML and export depth and ambient temperature 2025-11-22 19:54:21 +01:00
Thomas Kuehne a62eed5cae WriteAction: use more compact logging format 2025-10-25 20:23:06 +02:00
Thomas KuehneandJosé Rebelo b09ed96de6 GxpParser: add support for version 2 of Garmin's TrackPointExtension 2025-10-24 21:36:06 +02:00
Thomas KuehneandJosé Rebelo 4d9afdbfb8 GxpParser: forward description, depth and temperature to ActivityPoint 2025-10-24 21:34:23 +02:00
Thomas KuehneandJosé Rebelo 01ff179071 ble: adjust TransactionBuilder's MTU logging 2025-10-14 23:27:36 +02:00
Thomas Kuehne 4355236799 ble: prepare evenrealities for online chunking PR
Adjust G1DeviceSupport and G1SideManager to limit the impact of #5218
2025-10-14 21:09:13 +02:00
Thomas KuehneandJosé Rebelo c8f6b8cfaf GxpParser: extraction more waypoint and trackpoint data (#5465) 2025-10-12 23:50:37 +02:00
Thomas KuehneandJosé Rebelo 3fd826cd79 fix: unescaped' and " as well as white space sequences in string.xml
https://developer.android.com/guide/topics/resources/string-resource#FormattingAndStyling
Escape single quotes (') and double quote (").
Unescaped characters are removed by the Android tool chain.

A string contained completely in quotes
   <string>"a b   c"</string>
triggers special white space preserving handling (a b   c) instead of the normal white space collapse (a b c).
2025-10-11 23:41:55 +02:00
Thomas KuehneandJosé Rebelo a28ed02534 Garmin: extend FIT file parsing 14 - COURSE_POINT 32 / type 4
based on https://github.com/muktihari/fit
2025-10-10 01:01:44 +02:00
Thomas KuehneandJosé Rebelo 89485c76ad GpxTrackPoint: fix NullpointerException in toString 2025-10-10 00:54:50 +02:00
Thomas Kuehne f01f7f7537 GpxParser: improve GPX file detection
Add support for byte order marks (BOM) and UTF-16 big endian / little endian.
2025-10-04 02:24:49 +02:00
Thomas KuehneandJosé Rebelo c265c0892d Garmin: extend FIT file parsing 13 - test Location encoding 2025-10-03 19:42:17 +02:00
Thomas KuehneandJosé Rebelo 36f5c8a31e Garmin: extend FIT file parsing 12 - LOCATION 29 / symbol 3 2025-10-02 20:40:13 +02:00
Thomas KuehneandJosé Rebelo a7d9088cc6 Bluetooth: log bond loss on API 36.1 / Android 16 QPR2 2025-10-01 21:31:26 +02:00
Thomas Kuehne 933ba53a65 Garmin: extend FIT file parsing 11 - DEVICE_STATUS 104 / battery_level 2
Persist the gadget's battery level encoded in FitDeviceStatus.getBatteryLevel.
ACTIVITY FIT files seem to frequently use this.
2025-09-30 19:42:48 +02:00
Thomas Kuehne 94279f388a Garmin: extend FIT file parsing 10 2025-09-29 16:15:40 +02:00
Thomas Kuehne bed17b4a17 Garmin: extend FIT file parsing 9 2025-09-28 19:16:00 +02:00
Thomas Kuehne 4e915647d1 Garmin: extend FIT file parsing 8 - sports 2025-09-27 17:57:29 +02:00
Thomas KuehneandJosé Rebelo f03ac358fa ble: standardize server actions (#5157) 2025-09-26 22:39:53 +02:00
Thomas KuehneandJosé Rebelo 643fc0c7ef Garmin: extend FIT file parsing 7 2025-09-24 00:19:57 +02:00
Thomas Kuehne 76d16b6829 Garmin: extend FIT file parsing 6 2025-09-23 14:39:49 +02:00
Thomas KuehneandJosé Rebelo faa00faafb Garmin: extend FIT file parsing 5 2025-09-22 20:22:54 +02:00
Thomas Kuehne d61292b831 Gradle: housekeeping update to improve build performance 2025-09-22 19:06:35 +02:00
Thomas Kuehne ca081c062f Garmin: extend FIT file parsing 4 2025-09-21 15:24:05 +02:00
Thomas KuehneandJosé Rebelo 0e5c493cea Garmin: add debug support to fetch the DEVICE_XML
`Debug / Fetch device Debug Logs` now fetches the FILETYPE.DEVICE_XML instead of triggering a normal fetch.
On some devices this file is readily available via USB on others this is the only way to retrieve it.

Note:
The features listed in DEVICE_XML and device.fit sometimes differ substantially and don't necessarily reflect the supported features.
So far there is no known way to retrieve device.fit via Bluetooth.
2025-09-20 22:34:06 +02:00
Thomas Kuehne ddf008327c Garmin: prepare for more complex FIT upload scenarios 2025-09-19 22:28:31 +02:00
Thomas KuehneandJosé Rebelo 7f5a6e7f93 Garmin: extend FIT file parsing 3
The encoding of some BIKE_PROFILE fields has changed over the years (UINT8 vs ENUM). Use the modern encoding.
2025-09-19 21:47:25 +02:00
Thomas Kuehne ba70067aad Garmin: update FILETYPE comments and names
SLP_DISR is present on various devices (folder SlpDisr) and seems to stand for sleep disruptions.
2025-09-19 19:18:55 +02:00
Thomas KuehneandJosé Rebelo b1323b6fd1 Garmin: extend FIT file parsing 2 2025-09-18 21:13:36 +02:00
Thomas KuehneandJosé Rebelo 24fbbe854c Garmin: more targeted log for unknown message type
old log output:
n.f.g.s.d.g.m.GFDIMessage - Unknown message type 5023, message [12, 0, -97, 19, 50, -7, -1, -1, -1, -1, 50, 64]
n.f.g.s.d.g.m.GFDIMessage - Leftover bytes when parsing message type 5023. Bytes: 32F9FFFFFFFF, complete message: 0C009F1332F9FFFFFFFF3240

new log output:
n.f.g.s.d.g.m.GFDIMessage - Unknown message type 5023. Bytes: 32F9FFFFFFFF
2025-09-16 21:06:02 +02:00
Thomas Kuehne 47e7ef7e33 Garmin: update our ConfigurationMessage payload 2025-09-16 20:59:07 +02:00
Thomas KuehneandJosé Rebelo 62d458255b Garmin: add the "Unit ID" (device serial number) to the device details 2025-09-16 20:44:20 +02:00
Thomas KuehneandJosé Rebelo b12fd1027f Garmin: add FILETYPE 8/255 (device XML) 2025-09-16 20:44:09 +02:00
Thomas KuehneandJosé Rebelo 80aeaead1a garmin: extend FIT file parsing (#5339)
This updates the parser to interpret more FIT information and display it in the FIT file viewer.
Actually using the available information isn't part of this PR.
2025-09-16 20:12:52 +02:00
Thomas Kuehne 1becb9f6b3 btle+btbr: remove deprecated methods
DeviceSupports in master already use the modern methods.
DeviceSupports outside of the master branch either already use the modern methods or have know fix-ups (#5318).
2025-09-14 18:04:06 +02:00
Thomas Kuehne 1507553247 Garmin: HRM-Pro Plus - native support (#5353) 2025-09-14 16:49:15 +02:00
Thomas KuehneandJosé Rebelo 71116173f8 strings: Bluetooth is a proper name 2025-09-14 14:00:31 +02:00
Thomas KuehneandJosé Rebelo d414ae17b1 fix: NullPointerException in DeviceSpecificSettingsFragment.setChangeListener
Add a "CMF Watch Pro 2" test device manually and then open device specific settings results in following exception because supportedLanguages is null:

Uncaught exception in mainjava.lang.NullPointerException: Attempt to get length of null array
at nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsFragment.setChangeListener(DeviceSpecificSettingsFragment.java:419)
at nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsFragment.onCreatePreferences(DeviceSpecificSettingsFragment.java:244)
at androidx.preference.PreferenceFragmentCompat.onCreate(PreferenceFragmentCompat.java:161)
at nodomain.freeyourgadget.gadgetbridge.activities.AbstractPreferenceFragment.onCreate(AbstractPreferenceFragment.java:81)
2025-09-11 20:16:35 +02:00
Thomas Kuehne fc03ac11aa Garmin: fix NullPointerException in getActivityKind 2025-09-07 17:54:00 +02:00
Thomas KuehneandJosé Rebelo f5eb4a5feb garmin: add experimental support for In Reach Mini 2 2025-09-07 14:53:42 +02:00
Thomas Kuehne 06925b2384 garmin: add missing DAOs to getAllDeviceDao 2025-09-07 10:58:12 +02:00
Thomas Kuehne eba83f93ad change daily sleep goal from hours to minutes (#1312) 2025-08-31 10:27:24 +02:00
Thomas KuehneandJosé Rebelo e112a51c1e garmin: add FitDebug to improve logging of unsupported global field numbers 2025-08-27 19:44:46 +02:00
Thomas Kuehne 0500a6ee41 zip backup: add zip archive comment to ease human identification
example comment:
data export from Android application nodomain.freeyourgadget.gadgetbridge version 0.86.1 from 2025-08-26T23:59:45Z
2025-08-26 22:47:13 +02:00
Thomas KuehneandJosé Rebelo 0f54f2c6e0 zip backup: sort the external files by name to improve comparability 2025-08-26 22:02:07 +02:00
Thomas KuehneandJosé Rebelo 42033aad18 ultrahuman: redesign device support 2025-08-26 21:38:51 +02:00
Thomas KuehneandJosé Rebelo f5e015ff57 ui: optionally disable fetching new data from connected devices when swiping down
1) add new preference Settings / User interface / refresh on swipe
2) adjusted ControlCenterv2, AbstractChartsActivity and WorkoutListActivity
2025-08-26 21:17:04 +02:00
Thomas KuehneandJosé Rebelo 805bc35299 ui: use app:useSimpleSummaryProvider="true" instead of android:summary="%s"
fixes ListPreference's logcat warning:
`Setting a summary with a String formatting marker is no longer supported. You should use a SummaryProvider instead.`

https://developer.android.com/develop/ui/views/components/settings/customize-your-settings#summaries
2025-08-25 22:03:45 +02:00
Thomas KuehneandJosé Rebelo deef1c9d12 device settings: use icons / use more specific icons 2025-08-18 11:31:30 +02:00
Thomas KuehneandJosé Rebelo 5b1a4b237b WeightScale: add btle profile and generic device coordinator / device support (#5225)
Adds support for receiving weights from standard Bluetooth Weight scales:
0000181d-0000-1000-8000-00805f9b34fb - org.bluetooth.service.weight_scale
00002a9d-0000-1000-8000-00805f9b34fb - org.bluetooth.characteristic.weight_measurement
https://www.bluetooth.com/specifications/specs/weight-scale-service-1-0-1/
2025-08-18 11:23:52 +02:00
Thomas Kuehne be12a9d794 ble: add new Bluetooth standard mapping to BleNamesResolver 2025-08-17 19:21:45 +02:00
Thomas KuehneandJosé Rebelo 78b78de8e6 delete export files when deleting a device (#5216) 2025-08-14 23:08:14 +02:00
Thomas Kuehne 3b5ea9bf7f weather: try to reduce risk of TransactionTooLargeException 2025-08-14 09:49:32 +02:00
Thomas Kuehne 21a272cd74 weather: add compressed WeatherGz support to ACTION_GENERIC_WEATHER (#5239)
When receiving the broad cast action `nodomain.freeyourgadget.gadgetbridge.ACTION_GENERIC_WEATHER`

Try to decode bundle extra `WeatherGz` (ByteArray containing GZiped UTF-8 encoded JSON array of weather specifications) first.
If not present fall back to bundle extras `WeatherJson`  (String containing one JSON weather specification) and optional `WeatherSecondaryJson` (String containing JSON array of weather specifications).
2025-08-14 08:35:03 +02:00
Thomas Kuehne 32204ce606 debug: enable sharing an existing log file even if file logging is currently disabled (#4659) 2025-08-12 21:12:36 +02:00
Thomas Kuehne 00d3e9b23d implement getAllDeviceDao to enable device specific database exports (#5230) 2025-08-12 11:43:07 +02:00
Thomas KuehneandJosé Rebelo 111b705963 add missing @Override annotations 2025-08-11 21:41:25 +02:00
Thomas Kuehne bb710bae92 fix: BatteryInfoProfile complaining about unexpected characteristics 2025-08-10 18:16:58 +02:00
Thomas Kuehne 6966f80f3d ble: use UUID version of TransactionBuilder.read/write/notify (#5222)
Using the UUID version instead of BluetoothGattCharacteristic version ensures that, if a characteristic is missing on the gadget GB actually logs what characteristic is missing.
2025-08-09 18:05:22 +02:00