You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.5 KiB
119 lines
3.5 KiB
import * as fs from "fs/promises";
|
|
import { parseString } from "xml2js";
|
|
|
|
export function generateTrimlogInput(filename, name = "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: "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": []
|
|
}
|
|
|
|
*/
|