Add Zwift XML generation
This commit is contained in:
parent
cb8cb10a51
commit
5c34c7c167
|
|
@ -0,0 +1,71 @@
|
|||
import * as xml from "xml";
|
||||
import { Interval, Workout } from "./ast";
|
||||
|
||||
// Zwift Workout XML generator
|
||||
|
||||
const generateRangeInterval = (
|
||||
tagName: "Warmup" | "Cooldown",
|
||||
{ duration, intensity, cadence }: Interval
|
||||
): xml.XmlObject => {
|
||||
return {
|
||||
[tagName]: [
|
||||
{
|
||||
_attr: {
|
||||
Duration: duration,
|
||||
PowerLow: intensity.from,
|
||||
PowerHigh: intensity.from,
|
||||
...(cadence ? { Cadence: cadence } : {}),
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
const generateSteadyStateInterval = ({
|
||||
duration,
|
||||
intensity,
|
||||
cadence,
|
||||
}: Interval): xml.XmlObject => {
|
||||
return {
|
||||
SteadyState: [
|
||||
{
|
||||
_attr: {
|
||||
Duration: duration,
|
||||
Power: intensity.from,
|
||||
...(cadence ? { Cadence: cadence } : {}),
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
const generateInterval = (interval: Interval): xml.XmlObject => {
|
||||
const { intensity } = interval;
|
||||
if (intensity.from < intensity.to) {
|
||||
return generateRangeInterval("Warmup", interval);
|
||||
} else if (intensity.from > intensity.to) {
|
||||
return generateRangeInterval("Cooldown", interval);
|
||||
} else {
|
||||
return generateSteadyStateInterval(interval);
|
||||
}
|
||||
};
|
||||
|
||||
export const generateZwo = ({
|
||||
name,
|
||||
author,
|
||||
description,
|
||||
intervals,
|
||||
}: Workout): string => {
|
||||
return xml(
|
||||
{
|
||||
workout_file: [
|
||||
{ name: name },
|
||||
{ author: author },
|
||||
{ description: description },
|
||||
{ sportType: "bike" },
|
||||
...intervals.map(generateInterval),
|
||||
],
|
||||
},
|
||||
{ indent: " " }
|
||||
);
|
||||
};
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import * as fs from "fs";
|
||||
import { averageIntensity } from "./averageIntensity";
|
||||
import { generateZwo } from "./generateZwo";
|
||||
import { normalizedIntensity } from "./normalizedIntensity";
|
||||
import { parse } from "./parser";
|
||||
import { tokenize } from "./tokenizer";
|
||||
|
|
@ -13,7 +14,8 @@ console.log(`Parsing: ${filename}`);
|
|||
|
||||
const file = fs.readFileSync(filename, "utf8");
|
||||
|
||||
const { intervals } = parse(tokenize(file));
|
||||
const workout = parse(tokenize(file));
|
||||
const { intervals } = workout;
|
||||
|
||||
const duration = totalDuration(intervals);
|
||||
const avgIntensity = averageIntensity(intervals);
|
||||
|
|
@ -30,3 +32,5 @@ Normalized intensity: ${(normIntensity * 100).toFixed()}%
|
|||
TSS #1: ${tss(intervals).toFixed()}
|
||||
TSS #2: ${tss2(duration, normIntensity).toFixed()}
|
||||
`);
|
||||
|
||||
console.log(generateZwo(workout));
|
||||
|
|
|
|||
Loading…
Reference in New Issue