import * as fs from "fs/promises"; import { parseString } from "xml2js"; export function generateTrimlogInput(filename, name = "Walk", type = "walk") { return new Promise(async(resolve, reject) => { parseString(await fs.readFile(filename, "utf-8"), (err, res) => { if (err != null) { reject(err); } const data = res.TrainingCenterDatabase.Activities[0].Activity[0]; const map = {}; const date = new Date(res.TrainingCenterDatabase.Activities[0].Activity[0].Id[0]); const dateStr = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` let totalCalories = 0; let minAltitude = null; let maxAltitude = null; for (const lap of data.Lap) { totalCalories += parseFloat(lap.Calories[0]) || 0; for (const tp of lap.Track[0].Trackpoint) { const point = { time: tp.Time[0], longitude: parseFloat(tp.Position?.[0]?.LongitudeDegrees[0]), latitude: parseFloat(tp.Position?.[0]?.LatitudeDegrees[0]), altitude: parseFloat(tp.AltitudeMeters[0]), distance: parseFloat(tp.DistanceMeters[0]), heartrate: parseFloat(tp.HeartRateBpm?.[0].Value?.[0]), }; if (minAltitude == null || point.altitude < minAltitude) { minAltitude = point.altitude; } if (maxAltitude == null || point.altitude > maxAltitude) { maxAltitude = point.altitude; } map[tp.Time[0]] = point; } } const out = { date: dateStr, contents: [{rawActivity: { kind: type === "cycling" ? "Biking" : "Walking", sets: [], effortScale: 1, weight: 0, measurements: Object.keys(map).sort().map(k => map[k]).map(p => ({ seconds: Math.round((new Date(p.time) - date) / 1000), meters: p.distance, pulse: p.heartrate, })) }}], description: name, tags: [ { key: "tcx:Time", value: res.TrainingCenterDatabase.Activities[0].Activity[0].Id[0] }, { key: "tcx:TotalCalories", value: totalCalories.toFixed(1) }, { key: "tcx:MaximumAltitude", value: maxAltitude.toFixed(1) }, { key: "tcx:MinimumAltitude", value: minAltitude.toFixed(1) }, ] } resolve(out); }); }) } export function today() { const date = new Date(); return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`; } function pad(n) {return n > 9 ? n.toString() : `0${n}`} /* { "date": "2023-12-31", "contents": [ { "rawActivity": { "kind": "Walking", "sets": [], "measurements": [ { "seconds": 1234, "calories": 4321, "meters": 432553 }, { "seconds": 2468, "calories": 42342, "meters": 3424 }, { "seconds": 3702, "calories": 23423, "meters": 2342 }, { "seconds": 4936, "calories": 23423, "meters": 2342 } ], "effortScale": 1, "weight": 0 } } ], "description": "asdfasdfasdf", "tags": [] } */