Skip to content

Introduction of the Calories workout type, various improvements#158

Open
JaapvanEkris wants to merge 263 commits intomainfrom
0.9.7-(under-construction)
Open

Introduction of the Calories workout type, various improvements#158
JaapvanEkris wants to merge 263 commits intomainfrom
0.9.7-(under-construction)

Conversation

@JaapvanEkris
Copy link
Owner

@JaapvanEkris JaapvanEkris commented Dec 16, 2025

New functionality in 0.9.7

  • Addition of the 'Calories' workout type. You can now program Intervals and splits based on calories to be burned
  • GUI Improvements. The GUI now has dark (OLED) mode, its layout is more efficient and it has new tiles for Peak Force and Ratio
  • Introduction of splits in the fit-file. The fit-file now also has splits, which makes the fit-file closer to a native Garmin recording of the same session

Bugfixes and robustness improvements in 0.9.7

  • Fix of the Garmin bluetooth issues which affected the 'Cycling Power' and 'Cycling Speed and Cadence' Bluetooth profiles (see issue 125, issue 169 and the known issues in 0.9.6).
  • Brought the Bluetooth FTMS interface further into specification: several bugfixes in the communication to prevent miscommunication between OpenRowingMonitor and the client
  • Upgrade of the flywheel systematic error filter, which now can handle systematic errors of magnet positioning on the flywheel. This is more effective at reducing structural measurement noise and allows a reduction of the code complexity in Flyhweel.js as all dependent algorithms can use the same datastream. It reduces noise on the reference system from 1.5% (version 0.9.6) to 0.3% (version 0.9.7).
  • Improvement of the Moving Least Squares regressor:
    • Code refactoring to isolate this function from Flywheel.js, allowing a more thorough testing of this function's behaviour
    • Introduced the 'Local Goodness of Fit' function to improve the robustness against noise. This reduces the effect of outliers on stroke detection, the Force curve, Power curve and Handle speed curve
    • Introduction of a 'Gaussian Weight' filter to reduce the effects of flanks on the regression in a specific datapoint
    • Added documentation about the mathematical foundations of the algorithms used
  • Fixed a bug in the initialisation of the Flywheel.js
  • Improved logging in the Strava uploader for better troubleshooting (see issue 145)
  • Fixed a bug where VO2Max calculation missed heartrate data (see this discussion)
  • Increased the test coverage of key algorithms
  • As usual, all packages are updated to the newest versions

JaapvanEkris and others added 30 commits February 18, 2026 11:19
Corrected several minor typos (e.g., "alrrady", "recieve", "recomended") to improve overall readability.
* fix: correct FTMS Control Point error codes per Bluetooth spec

The FTMS Control Point characteristic returned wrong result codes in
several cases:

- reset/startOrResume/stopOrPause without prior requestControl returned
  opCodeNotSupported (0x02) instead of controlNotPermitted (0x05)
- stopOrPause with invalid parameter (not 1 or 2) returned
  opCodeNotSupported instead of invalidParameter (0x03)
- stopOrPause with a truncated 1-byte buffer caused a RangeError crash
  (buffer underflow) that prevented indicate+callback from being called,
  hanging the BLE stack

Also removes dead fallthrough code — all handled cases now return
explicitly, so only the default case produces opCodeNotSupported.

Adds 11 uvu tests covering all control point code paths.

* refactor: use guard clauses in FTMS control point handler
* fix: correct FTMS Control Point error codes per Bluetooth spec

The FTMS Control Point characteristic returned wrong result codes in
several cases:

- reset/startOrResume/stopOrPause without prior requestControl returned
  opCodeNotSupported (0x02) instead of controlNotPermitted (0x05)
- stopOrPause with invalid parameter (not 1 or 2) returned
  opCodeNotSupported instead of invalidParameter (0x03)
- stopOrPause with a truncated 1-byte buffer caused a RangeError crash
  (buffer underflow) that prevented indicate+callback from being called,
  hanging the BLE stack

Also removes dead fallthrough code — all handled cases now return
explicitly, so only the default case produces opCodeNotSupported.

Adds 11 uvu tests covering all control point code paths.

* refactor: use guard clauses in FTMS control point handler

* feat: add software debounce filter for GPIO magnetic sensor

Hardware bounce from magnetic flywheel sensors can send phantom ticks
(~0.5ms apart) that corrupt stroke data. This middleware layer filters
bounces by validating delta-times against a rolling median buffer.

- Rejects deltas below 1ms (absolute minimum)
- Rejects deltas below 40% of median (physically impossible acceleration)
- Uses fixed-size circular buffer for performance (no allocations in hot path)

* refactor: remove GPIO debounce filter based on maintainer feedback, retain FTMS fixes

* fix: restore maintenance comments in GpioTimerService.js

Comments were unintentionally removed when stripping the debounce
filter changes. File now matches the base branch with no modifications.
* Patching DashboardForceCurve behaviour so that it's not just a large black box.

* Add division lines plugin to Force Curve chart with click-to-toggle functionality

- Implement custom Chart.js plugin to draw vertical dashed division lines at configurable positions
- Add click handler to cycle through division modes (0, 2, or 3 divisions)
- Move Chart.register call outside constructor to include new divisionLinesPlugin
- Add `_divisionMode` state property to track current division setting
- Implement `_updateDivisionLines()` to calculate line positions based on data length and division mode

* Refactor Force Curve division mode to use app state instead of component state

* Have GUI config state merge to preserve existing (non-edited) configuration values

Changed updateState call in settings-update handler to spread existing guiConfigs before applying new values, preventing unintended deletion of other GUI configuration properties when updating individual settings.

* Simplifying markup.
Removing inline styles and wrapper div.
Thickening line a bit, for visibility.

* Fix `trueBlackTheme`` being undone on gui setting change

Now we merge the new settings into the existing guiConfigs and pass the resulting trueBlackTheme value to applyTheme, ensuring the theme state is preserved.

* Add robust localStorage validation for dashboardMetrics

    Replaced the hardcoded 'actions' metric migration with a dynamic validation check against the authoritative DASHBOARD_METRICS object keys.
    This ensures that any non-existent or deprecated tiles are gracefully ignored and removed from saved state, preventing rendering issues if metrics are removed in future updates.

AI-Assisted-By: Gemini 3.1
* Merach NovaRow R50 Air Resistance Rower Profile
See discussion #140 .
Specifically:
- #140 (reply in thread)
- #140 (reply in thread)

* Update Merach R50 profile

Adjusted timing parameters:
- Loosened stroke tolerances just a bit
- Updated comments to clarify air resistance; magnet was a hallucination.

* Adding Merach R50 Recording
510.36m, 49 strokes, 176w avg, 23spm avg. 2:05/500m avg pace.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants