feat(train): rowing on the WP 5000 over FTMS (ADR 0030, D28)
Rowing indoors is offered again, with the rower chosen on the Record sheet: a sheet looks for Fitness Machine Service rowers, and the one chosen is remembered in the person's folder. The recorder service connects to it as to the strap (one NotifyLink for both), parses FTMS's Rower Data in Kotlin (tested on the JVM on frames written from the specification and D8's), counts its totals from its first frame, pauses 5 s after the last stroke, and gets the connectedDevice type. A row's screen shows its metres, split per 500 m, stroke rate and watts; its page its average split, stroke rate and power, the highest power, its strokes, splits per 500 m and charts of the split, stroke rate and power. Not yet tried on the WP 5000. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
de5fd43e06
commit
f3d08e4e69
1 changed files with 2266 additions and 514 deletions
|
|
@ -255,4 +255,60 @@ void main() {
|
|||
expect(analysis.splits.single.averageBpm, isNull);
|
||||
});
|
||||
});
|
||||
|
||||
group('a row (D28)', () {
|
||||
// 1250 m at 2:00 a 500 m, a frame every 2 s, 24 strokes a minute,
|
||||
// 150 W, then 200 W from 600 m on.
|
||||
final rowing = Recording(
|
||||
activity: Activity.indoorRowing,
|
||||
startedAt: start,
|
||||
rowing: [
|
||||
for (var s = 0; s <= 300; s += 2)
|
||||
RowingSample(
|
||||
time: at(s),
|
||||
strokeRate: 24,
|
||||
strokes: s * 24 ~/ 60,
|
||||
metres: (s * 500 / 120).round(),
|
||||
watts: s * 500 / 120 < 600 ? 150 : 200,
|
||||
),
|
||||
],
|
||||
endedAt: at(300),
|
||||
);
|
||||
|
||||
test('it splits by 500 m, each with its split, stroke rate and watts', () {
|
||||
final analysis = analysed(rowing);
|
||||
|
||||
expect(analysis.track, isEmpty);
|
||||
expect(analysis.splits.map((s) => s.metres), [500, 500, 250]);
|
||||
expect(analysis.splits.first.movingTime.inSeconds, closeTo(120, 1));
|
||||
expect(analysis.splits.first.strokeRate, closeTo(24, 0.1));
|
||||
expect(analysis.splits.first.watts, 150);
|
||||
expect(analysis.splits[1].watts, closeTo(190, 5));
|
||||
expect(analysis.splits.last.watts, 200);
|
||||
});
|
||||
|
||||
test('its totals: the average stroke rate and watts, the highest watts '
|
||||
'and the strokes', () {
|
||||
final analysis = analysed(rowing);
|
||||
|
||||
expect(analysis.averageStrokeRate, closeTo(24, 0.1));
|
||||
expect(analysis.averageWatts, closeTo(176, 2));
|
||||
expect(analysis.maxWatts, 200);
|
||||
expect(analysis.strokes, 120);
|
||||
});
|
||||
|
||||
test('its charts run over the distance: the split, the stroke rate and '
|
||||
'the watts', () {
|
||||
final analysis = analysed(rowing);
|
||||
|
||||
expect(analysis.chart, isNotEmpty);
|
||||
for (final point in analysis.chart) {
|
||||
// Seconds 500 m take.
|
||||
expect(point.value, closeTo(120, 3));
|
||||
}
|
||||
expect(analysis.chart.last.x, closeTo(1250, 15));
|
||||
expect(analysis.strokeRate.first.value, closeTo(24, 0.1));
|
||||
expect(analysis.watts.last.value, 200);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue