Skip to content

Conversation

@DXCanas
Copy link

@DXCanas DXCanas commented Jan 26, 2026

For those of us who do not have a tiny screen to attach to our Pi's, and want to preserve the battery of our smartphones!

Sets the stage for more themes, in case someone ever sets up… idk, MIP? E-Ink? 🤷

Currently depends on #170, though can be refactored to remove that dependency.

Using CSS themes, tucking setting away under Experimental until it's a little more battle-tested.

Opted for borders over full background for maximum power savings.

True Black Dashboard True Black Toggle)

Testing TBD

…onent

Extracted toolbar functionality from PerformanceDashboard into new DashboardToolbar component.
Removed 'actions' from default dashboard metrics.
 Updated layout to use flexbox with separate toolbar and metrics grid sections.
@DXCanas DXCanas changed the base branch from main to 0.9.7-(under-construction) January 26, 2026 22:46
@JaapvanEkris
Copy link
Owner

Testing challenge accepted :)

@DXCanas
Copy link
Author

DXCanas commented Jan 27, 2026

During live testing, I think I ran into something completely unrelated regarind fit file writing in the 0.9.7 branch — I know it's in active dev, but I have no means to DM and put it on your radar in case you don't know about it @JaapvanEkris:

Jan 26 18:25:38 rowingmonitor npm[855]: Activating split settings for split 2
Jan 26 18:25:38 rowingmonitor npm[855]: Raw data-file has been saved as data/recordings/2026/01/2026-01-27_02-19-59_raw.csv.gz
Jan 26 18:25:38 rowingmonitor npm[855]: RowingData-file has been saved as data/recordings/2026/01/2026-01-27_02-19-59_rowingData.csv
Jan 26 18:25:38 rowingmonitor npm[855]: Uncaught Exception: TypeError: Cannot read properties of undefined (reading 'num')
Jan 26 18:25:38 rowingmonitor npm[855]:     at /opt/openrowingmonitor/node_modules/@markw65/fit-file-writer/build/src/fit-encode.js:1:3947>
Jan 26 18:25:38 rowingmonitor npm[855]:     at Array.sort (<anonymous>)
Jan 26 18:25:38 rowingmonitor npm[855]:     at S.writeMessage (/opt/openrowingmonitor/node_modules/@markw65/fit-file-writer/build/src/fit->
Jan 26 18:25:38 rowingmonitor npm[855]:     at createActiveSplit (file:///opt/openrowingmonitor/app/recorders/fitRecorder.js:672:14)
Jan 26 18:25:38 rowingmonitor npm[855]:     at writeSplits (file:///opt/openrowingmonitor/app/recorders/fitRecorder.js:612:15)
Jan 26 18:25:38 rowingmonitor npm[855]:     at workoutToFit (file:///opt/openrowingmonitor/app/recorders/fitRecorder.js:457:11)
Jan 26 18:25:38 rowingmonitor npm[855]:     at async Object.fileContent (file:///opt/openrowingmonitor/app/recorders/fitRecorder.js:354:21)
Jan 26 18:25:38 rowingmonitor npm[855]:     at async Object.writeFile (file:///opt/openrowingmonitor/app/recorders/fileWriter.js:34:25)
Jan 26 18:25:38 rowingmonitor npm[855]:     at async writeRecordings (file:///opt/openrowingmonitor/app/recorders/recordingManager.js:172:>
Jan 26 18:25:38 rowingmonitor npm[864]: 2026-01-26 18:25:38 sigHandler: Unhandled signal 15, terminating
Jan 26 18:25:38 rowingmonitor npm[855]: OpenRowingMonitor shutdown at 18:25, at 335.28646 seconds,distance 1064.2m
Jan 26 18:25:38 rowingmonitor npm[855]: Raw data-file has been saved as data/recordings/2026/01/2026-01-27_02-19-59_raw.csv.gz
Jan 26 18:25:38 rowingmonitor npm[855]: RowingData-file has been saved as data/recordings/2026/01/2026-01-27_02-19-59_rowingData.csv
Jan 26 18:25:38 rowingmonitor npm[855]: /opt/openrowingmonitor/node_modules/@markw65/fit-file-writer/build/src/fit-encode.js:1
Jan 26 18:25:38 rowingmonitor npm[855]: "use strict";var x=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var R=Object.getOwn>
Jan 26 18:25:38 rowingmonitor npm[855]: _hour:5,degreesCelsius:6,degrees_celsius:6,degreesFarenheit:7,degrees_farenheit:7,zone:8,gear:9,rp>
Jan 26 18:25:38 rowingmonitor npm[855]: 33,plank_with_leg_lift:133,reversePlankWithLegPull:134,reverse_plank_with_leg_pull:134,_min:0,_max>
Jan 26 18:25:38 rowingmonitor npm[855]: igh_value:{num:1,name:"high_value",type:"uint16",array:"false",scale:1,offset:0,units:"watts",bits>
Jan 26 18:25:38 rowingmonitor npm[855]: ce_position:{num:108,name:"avg_cadence_position",type:"uint8",array:"true",scale:1,offset:0,units:>
Jan 26 18:25:38 rowingmonitor npm[855]: ts:!1,subFields:[]},distance:{num:4,name:"distance",type:"uint32",array:"false",scale:100,offset:0>
Jan 26 18:25:38 rowingmonitor npm[855]: t:0,units:"rpm",bits:[],components:[],isAccumulated:!1,hasComponents:!1,subFields:[]},manufacturer>
Jan 26 18:25:38 rowingmonitor npm[855]: ource_type:{num:19,name:"heart_rate_source_type",type:"source_type",array:"false",scale:1,offset:0>
Jan 26 18:25:38 rowingmonitor npm[855]: ld ${e.key}`)}else if(typeof a=="number")l=a;else if(d?.mask){let _=a;l=_.value,_.options?.forEach>
Jan 26 18:25:38 rowingmonitor npm[855]:                                                                                                   >
Jan 26 18:25:38 rowingmonitor npm[855]: TypeError: Cannot read properties of undefined (reading 'num')
Jan 26 18:25:38 rowingmonitor npm[855]:     at /opt/openrowingmonitor/node_modules/@markw65/fit-file-writer/build/src/fit-encode.js:1:3947>
Jan 26 18:25:38 rowingmonitor npm[855]:     at Array.sort (<anonymous>)
Jan 26 18:25:38 rowingmonitor npm[855]:     at S.writeMessage (/opt/openrowingmonitor/node_modules/@markw65/fit-file-writer/build/src/fit->
Jan 26 18:25:38 rowingmonitor npm[855]:     at createActiveSplit (file:///opt/openrowingmonitor/app/recorders/fitRecorder.js:672:14)
Jan 26 18:25:38 rowingmonitor npm[855]:     at writeSplits (file:///opt/openrowingmonitor/app/recorders/fitRecorder.js:612:15)
Jan 26 18:25:38 rowingmonitor npm[855]:     at workoutToFit (file:///opt/openrowingmonitor/app/recorders/fitRecorder.js:457:11)
Jan 26 18:25:38 rowingmonitor npm[855]:     at async Object.fileContent (file:///opt/openrowingmonitor/app/recorders/fitRecorder.js:354:21)
Jan 26 18:25:38 rowingmonitor npm[855]:     at async Object.writeFile (file:///opt/openrowingmonitor/app/recorders/fileWriter.js:34:25)
Jan 26 18:25:38 rowingmonitor npm[855]:     at async writeRecordings (file:///opt/openrowingmonitor/app/recorders/recordingManager.js:172:>
Jan 26 18:25:38 rowingmonitor npm[855]:     at async Object.handleCommand (file:///opt/openrowingmonitor/app/recorders/recordingManager.js>
Jan 26 18:25:38 rowingmonitor npm[855]: Node.js v22.21.0
Jan 26 18:25:38 rowingmonitor systemd[1]: openrowingmonitor.service: Main process exited, code=exited, status=1/FAILURE

@JaapvanEkris
Copy link
Owner

JaapvanEkris commented Jan 27, 2026

During live testing, I think I ran into something completely unrelated regarind fit file writing in the 0.9.7 branch — I know it's in active dev, but I have no means to DM and put it on your radar in case you don't know about it @JaapvanEkris:

Thanks, will pick it up this weekend. As this hasn't changed, I assume it is also in the production branch.

@JaapvanEkris
Copy link
Owner

Jan 26 18:25:38 rowingmonitor npm[855]: Activating split settings for split 2
Jan 26 18:25:38 rowingmonitor npm[855]: Raw data-file has been saved as data/recordings/2026/01/2026-01-27_02-19-59_raw.csv.gz

Why does this happen? I think there should be a stop-command in between? What kind of session did you use?

@DXCanas
Copy link
Author

DXCanas commented Jan 27, 2026

Jan 26 18:25:38 rowingmonitor npm[855]: Activating split settings for split 2
Jan 26 18:25:38 rowingmonitor npm[855]: Raw data-file has been saved as data/recordings/2026/01/2026-01-27_02-19-59_raw.csv.gz

Why does this happen? I think there should be a stop-command in between? What kind of session did you use?

As far as I know, I was just picking up the handle and yanking 🤷. Really, this came up while I was calibrating things for the the thread over in #140

If I recall, the order went:

  1. Rowing, with watch connected via ANT+
  2. Unsatisfied with numbers. Go to laptop, update config (I think it was flyWheelInertia), restart ORM
  3. Resume watch, start rowing.
  4. Unsatisfied still. Go to laptop, check logs, see the fitfile error but no "Goodness" grep matches.
  5. Realize that I have RowingEngine under logLevel with a lowercase r. Update, and disable fitFiles while I'm at it. Restart ORM
  6. Start logs, grep for "Goodness".
  7. Start rowing, see "Goodness"

So it was a secondary thing I caught while testing the new UI and calibrating.

… in localStorage.

Remove deprecated DashboardActions component and migrate saved metrics

Deleted DashboardActions.js component as functionality has been moved to DashboardToolbar.
Replaced dynamic inline style injection with CSS class-based approach for grid row configuration.

Changed metrics container from div to semantic section element.

Updated grid layout to use explicit grid-template-rows and added .rows-3 modifier class for 12-tile configuration.
…vements

Reorganized CSS properties for better readability and consistency.
Simplified button styles by removing redundant properties and using flex instead of inline-flex.
Changed fullscreen/windowed icon containers from div with IDs to span with classes.
Consolidated media query icon display rules into single-line declarations.
Added explicit grid-template-areas to PerformanceDashboard for clearer layout structure.
Added min-height: 0 to metrics-grid and metric-tile to prevent grid blowout issues.
@JaapvanEkris JaapvanEkris added this to the 0.9.7 milestone Jan 27, 2026
…rt legend.

More reliable - Avoids Chart.js legend bugs on iOS and autoscaling issues
Better for responsive design - HTML text naturally inherits the fluid typography
Added host flex container styles and title styling at 80% font size with center alignment.
…thod for better performance and to follow Lit best practices.
…y for more efficient change detection with array values
Including new border definition, for division in true-black mode.
Theme preference is persisted to localStorage and applied via data-theme attribute on document root element.
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.

3 participants