Ride summary: descent and total kJ in the ride footer (OBRF v5) - #2148
Merged
Merged
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
timohueser
force-pushed
the
claude/effort-kj-summary-2138
branch
from
September 23, 2026 18:44
0912009 to
5aa4977
Compare
The ride footer grows from 144 to 150 bytes and goes to version 5. v4 is gone. - Bytes 24..26 hold the ride's descent in metres, next to the climb. The recorder takes it from the same dead band as the climb. - Bytes 38..42 hold the ride's energy from power in whole kJ, next to the power summary. 0xFFFF_FFFF means the ride has no power data, so 0 kJ stays a real value. The device ride detail does not change: its redesign reads these fields in a follow-up. RideSummary carries the energy for that redesign. The descent stays out of the resident ride list; the detail can read it from the opened ride, as the route detail reads a route's descent. TripRef keeps its key as NonZeroU64, so Option<TripRef> loses its tag and a board RideEntry stays at 112 B, now pinned. TripRef::new already refused key 0, so no behaviour changes. The phone decodes both fields and keeps them in summary.json. A ride edit recomputes the descent and estimates the energy from the stored points, with each interval capped at 2 s as on the device. The ride detail shows an Energy row. The web builder decodes v5. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
timohueser
force-pushed
the
claude/effort-kj-summary-2138
branch
from
September 23, 2026 19:27
2a28849 to
829db74
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2138. This is part 2 of 2: the ride summary data (section 5). #2139 added the live effort display and the recorder's energy total. The device ride detail is redesigned in a follow-up PR (three manual pages). That PR reads these fields. This PR adds the data and the iOS row only.
What changed
Ride footer v5. The footer grows from 144 to 150 bytes. v4 is gone, with no migration.
0xFFFF_FFFF= no power data (new)Descent. The recorder already keeps a dead band for the climb. That dead band also counts the descent, and the ride-resume data already carries it. The footer takes
climb.descent(), with the same smoothing and hysteresis as the climb.Energy. The footer takes
RecorderMachine::kj(). The energy crosses a reset. A ride without power data writes the absent value, so 0 kJ is a real value.Spec and vectors.
specs/obc-ble-interface-spec.md§7.2 has the new table and notes for climb and descent and for energy.ride-v4.binis nowride-v5.bin(95 m descent, 756 kJ). The manifest and the vector README are updated.Decoders.
obc-formats,obc-route(RideStats,RideInfo), host and link tests,obc-web-convert, the web builderobjects.ts, and iOSRideObjectCodecall use v5.iOS.
RideSummaryhasdescentMetersandenergyKJ. Both are kept insummary.jsonand filled in on ride sync. A ride edit counts the descent again with the 3 m dead band. The energy after an edit is an estimate from the stored points: watts × min(dt, 2 s). The ride detail shows an "Energy · 756 kJ" row after max power, only with power data. iOS shows no descent row, because the tracked ride detail shows its climb only in the one stats line.Device. The ride detail is unchanged.
RideSummarycarriesenergy_kjfor the follow-up. The descent is not in the resident ride list. The follow-up can read it from the opened ride, as the route detail reads a route's descent.Web builder test. A corruption test flipped the last byte of a stream record. With a 250-byte payload, that byte is alignment padding, so the test now flips a byte in the middle of the payload.
RAM and the trip key
RideEntryis 112 B (RideSummary104 B + 8 B id). A new const assert pins this. Without the change below,energy_kjwould make it 120 B (+256 B for the 32 resident entries).TripRefnow holds its key asNonZeroU64, soOption<TripRef>has no tag. A const assert pins this too.TripRef::newis the only constructor. It returnedNonefor key 0 before this change too.rejects_zero_key)Trip.newKey(): returns1...UInt64.maxTripObjectCodec: rejects key 0manage.ts: falls back to|| 1nTripRef::new(0, 0, 1) == Noneresource_baseline.jsondid not change.Checks
obc test -ppassed: obc-formats (55), obc-route (252), obc-vectors (12), obc-link (99), obc-host-core (130), obc-web-convert (14), obc-app (1154), obc-sim (74).cargo clippy -D warningson the touched crates and on the board crate, andcargo fmt --all --check, are clean.obc shot --check: all 370 frames matchdevelop. No digest changed.swift testpassed (450 tests, including a newwithStatstest).obc check frontend(1003 vitest tests),firmware/tools/tests(101),obc suites check,obc prose --checkandpython3 docs/build_docs.py --check-links.web.builder-browser(Playwright is not installed on this machine), OBCRoutingswift test(it needsobc companion-core) andios.xcuitest. CI covers them.Out of scope: the device ride-detail display (follow-up PR), GPX and FIT export of energy, calories, and live in-ride fields.
Docs
The public docs changed.
docs/content/software/formats.mdnow says the footer is 150 bytes. That change is its owndocs:commit.Requirements: none
🤖 Generated with Claude Code