Garmin Integration auf meiner Webseite

Jonas Mosimann
26. Juni 2020

Unter Triathlon könnt ihr eine kleine Übersicht über mein Training in den letzten 7 Tagen sehen:

00h00

Total

-

Höhenmeter

00h00

Swim

00h00

Bike

00h00

Run

Diese Daten werden direkt von meinem Garmin-Account geladen und hier angezeigt.

Da diese Trainingsdaten aber nicht sehr häufig ändern und die Statistik auch nicht immer auf die Sekunde genau muss sein, werden die Daten jeweils nur beim Aufruf der Webseite aktualisiert und falls der letzte Aufruf nicht älter als 1h ist. Rufe ich also z.B. die Seite Triathlon auf, werden die neusten Daten von meinem Garmin-Account geladen und angezeigt. Ruft nun jemand (oder auch ich) dieselbe Seite nochmals innerhalb der nächsten Stunde auf, so werden die Daten aus dem Cache angezeigt und nicht noch einmal von meinem Garmin-Account abgerufen. Dies macht meine Seite viel schneller und reduziert entsprechend die Aufrufe auf die Garmin-Webseite.

Dazu verwende ich garmin-connect mit welchem ich die Trainings der letzten Woche abrufe und diese nach Aktivitätstyp filtere und dann gecached zurückgebe.

pages/api/garmin.ts
const { GarminConnect } = require('garmin-connect');

const garmin = async (req, res) => {
    const GCClient = new GarminConnect();
    await GCClient.login(
        process.env.GARMIN_USER,
        process.env.GARMIN_PASSWORD
    );

    const activities = await GCClient.getActivities(0, 20);

    // ... Aktivitäten filtern und nur die letzte Woche anzeigen

    res.setHeader(
        'Cache-Control',
        's-maxage=3600, stale-while-revalidate'
    );
    return res.status(200).json({
        activities
    });
};

export default garmin;

Diese Schnittstelle kann ich nun verwenden um die Daten auf meiner Webseite anzuzeigen:

/components/GarminStats.tsx
import React from 'react';
import StatisticItem from 'components/base/StatisticItem';
import {SecondsToHourMinutes} from 'services/DateFormatter';
import useSWR from 'swr';

const fetcher = async function<JSON = any>(
    input: RequestInfo,
    init?: RequestInit
): Promise<JSON> {
    const res = await fetch(input, init)
    return res.json()
}

const GarminStats = () => {
    const { data } = useSWR('/api/garmin', fetcher);
    const summary = data?.summary;

    const totalDuration = SecondsToHourMinutes(summary?.duration ?? 0);
    const elevation = SecondsToHourMinutes(summary?.elevation ?? 0);
    const swimDuration = SecondsToHourMinutes(summary?.swimDuration ?? 0);
    const bikeDuration = SecondsToHourMinutes(summary?.bikeDuration ?? 0);
    const runDuration = SecondsToHourMinutes(summary?.runDuration ?? 0);

    return (
        <>
            <div>
                <StatisticItem label={"Total"} value={totalDuration}/>
                <StatisticItem label={"Höhenmeter"} value={elevation}/>
            </div>
            <div>
                <StatisticItem label={"Swim"} value={swimDuration/>
                <StatisticItem label={"Bike"} value={SbikeDuration}/>
                <StatisticItem label={"Run"} value={runDuration}/>
            </div>
        </>
    )
};

export default GarminStats;

Newsletter abonnieren

Erhalte E-Mails von mir über Triathlon und Web Development.