• Hallo Gast, wir suchen den Renner der Woche 🚴 - vielleicht hast du ein passendes Rennrad in deiner Garage? Alle Infos

MyWhoosh Aktivität nach Garmin Connect hochladen?

Sulemann

Neuer Benutzer
Registriert
15 August 2023
Beiträge
15
Reaktionspunkte
4
Hallo zusammen,

ich möchte gerne, dass meine MyWhoosh Aktivitäten (kostenlose Version) automatisch in der Garmin Connect App angezeigt werden. Leider klappt das irgendwie nicht 😳

Da in der MyWhoosh App, Garmin nicht hinterlegt werden kann, habe ich Strava eingestellt.

Die MyWhoosh Aktivitäten werden ohne Probleme in Strava hochgeladen.

In Strava (kostenlose Version) habe ich Garmin Connect hinterlegt, sodass die Aktivitäten von Strava nach Garmin hochgeladen werden müssten.

Das klappt aber nicht für MyWhoosh Aktivitäten?

Hat jemand nen Tipp?

Habe auch schon gegoogelt, alles getrennt und neu verbunden und auch bei den Apps abgemeldet und neu angemeldet.

Habt ihr ggf. Tipps?

Danke und Gruss
René
 

Anzeige

Re: MyWhoosh Aktivität nach Garmin Connect hochladen?
Hi!
Ich lade meine Aktivitäten zuerst von der MyWhoosh-Website als GPX herunter und importiere sie dann in Garmin connect Webversion. Ist am einfachsten so finde ich.

lg
 
Hi!
Ich lade meine Aktivitäten zuerst von der MyWhoosh-Website als GPX herunter und importiere sie dann in Garmin connect Webversion. Ist am einfachsten so finde ich.

lg
Ist GPX nicht nur die Strecke?
Wenn schon, das in Strava "Original runterladen" und das importieren, hätte ich gesagt.
Die Script-Lösung ist nat besser.
 
Ich mache das auch mit einem, von @Barst, angepassten Script .
Er hat es erweitert, sodass auch der Trainingseffekt in Garmin Connect berücksichtigt wird. 👍

Dank KI - ich bin nicht so der Programmierer - habe ich es dann auch nochmal ein wenig erweitert, damit das Script ein Auto-Login bei Garmin hat, ich die Daten nicht jedes mal eingeben muss und die hochgeladene FIT Datei aus dem Download Ordner gelöscht wird.
Die Namen der Aktivität in Strava und der FIT Datei sind unterschiedlich. An das Thema habe ich mich noch nicht gesetzt.

Somit ergibt sich
  1. FIT Datei von MW herunterladen
  2. Script laufen lassen
  3. Namen in Connect anpassen
 
Ich mache das auch mit einem, von @Barst, angepassten Script .
Er hat es erweitert, sodass auch der Trainingseffekt in Garmin Connect berücksichtigt wird. 👍

Dank KI - ich bin nicht so der Programmierer - habe ich es dann auch nochmal ein wenig erweitert, damit das Script ein Auto-Login bei Garmin hat, ich die Daten nicht jedes mal eingeben muss und die hochgeladene FIT Datei aus dem Download Ordner gelöscht wird.
Die Namen der Aktivität in Strava und der FIT Datei sind unterschiedlich. An das Thema habe ich mich noch nicht gesetzt.

Somit ergibt sich
  1. FIT Datei von MW herunterladen
  2. Script laufen lassen
  3. Namen in Connect anpassen
Hallo zusammen,
danke für die ganzen Infos hier. Ich bin komplett neu beim Thema Script etc. Wo kann ich denn das von @Barst angepasste Script finden?
Viele Grüße
 
Das Script habe ich hier. Man muss noch den Download-Path eintragen. Falls es nicht richtig startet, kopiere die Fehlermeldung in einen KI-Chat. Da wird dir der Rest erklärt.

Code:
#!/usr/bin/env python3
import os
import re
from pathlib import Path
from datetime import datetime
from getpass import getpass
import logging

import garth
from garth.exc import GarthException, GarthHTTPError
from fit_tool.fit_file import FitFile
from fit_tool.fit_file_builder import FitFileBuilder
from fit_tool.profile.messages.record_message import RecordMessage, RecordTemperatureField
from fit_tool.profile.messages.session_message import SessionMessage
from fit_tool.profile.messages.lap_message import LapMessage
from fit_tool.profile.messages.file_id_message import FileIdMessage

# === Logging ===
SCRIPT_DIR = Path(__file__).resolve().parent
log_file_path = SCRIPT_DIR / "myWhoosh2Garmin.log"
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
file_handler = logging.FileHandler(log_file_path)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)

# === Pfade ===
MYWHOOSH_PATH = Path("Download-Path")
BACKUP_PATH = MYWHOOSH_PATH / "backup"
BACKUP_PATH.mkdir(exist_ok=True)

# === Garmin Auth ===
TOKENS_PATH = SCRIPT_DIR / '.garth'

def authenticate_to_garmin():
    try:
        if TOKENS_PATH.exists():
            garth.resume(TOKENS_PATH)
        else:
            username = input("Garmin Benutzername: ")
            password = getpass("Garmin Passwort: ")
            garth.login(username, password)
            garth.save(TOKENS_PATH)
        logger.info(f"Authenticated as: {garth.client.username}")
    except GarthException as e:
        logger.error(f"Garmin Auth Fehler: {e}")
        exit(1)

# === Hilfsfunktionen ===
def calculate_avg(values):
    return round(sum(values)/len(values),1) if values else 0

def append_value(values, message, field_name):
    val = getattr(message, field_name, None)
    if val is not None:
        values.append(val)

def reset_values():
    return [], [], []

def get_most_recent_fit_file(folder: Path) -> Path:
    fit_files = list(folder.glob("*.fit"))
    if not fit_files:
        return None
    return max(fit_files, key=os.path.getctime)

def generate_new_filename(fit_file: Path) -> Path:
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    return BACKUP_PATH / f"{fit_file.stem}_{timestamp}.fit"

# === Hauptlogik ===
def cleanup_fit_file(fit_file_path: Path, new_file_path: Path):
    builder = FitFileBuilder()
    fit_file = FitFile.from_file(str(fit_file_path))
    cadence_values, power_values, hr_values = reset_values()

    for record in fit_file.records:
        msg = record.message
        if isinstance(msg, FileIdMessage):
            # Override manufacturer/product but keep other fields
            msg.manufacturer = 1
            msg.product = 1836
        if isinstance(msg, LapMessage):
            continue
        if isinstance(msg, RecordMessage):
            msg.remove_field(RecordTemperatureField.ID)
            append_value(cadence_values, msg, "cadence")
            append_value(power_values, msg, "power")
            append_value(hr_values, msg, "heart_rate")
        if isinstance(msg, SessionMessage):
            if not msg.avg_cadence:
                msg.avg_cadence = calculate_avg(cadence_values)
            if not msg.avg_power:
                msg.avg_power = calculate_avg(power_values)
            if not msg.avg_heart_rate:
                msg.avg_heart_rate = calculate_avg(hr_values)
            cadence_values, power_values, hr_values = reset_values()
        builder.add(msg)
            
    # Datei bauen und speichern
    builder.build().to_file(str(new_file_path))
    logger.info(f"Bereinigte Datei gespeichert: {new_file_path}")

# === Main ===
def main():
    authenticate_to_garmin()

    latest_fit = get_most_recent_fit_file(MYWHOOSH_PATH)
    if not latest_fit:
        logger.error(f"Keine FIT-Dateien in {MYWHOOSH_PATH} gefunden.")
        exit(1)

    logger.info(f"Neueste Datei: {latest_fit}")
    new_file = generate_new_filename(latest_fit)

    try:
        cleanup_fit_file(latest_fit, new_file)
    except Exception as e:
        logger.error(f"Fehler beim Bereinigen: {e}")
        exit(1)

    # Upload zu Garmin
    try:
        with open(new_file, "rb") as f:
            garth.client.upload(f)
        logger.info(f"Erfolgreich hochgeladen: {new_file}")
    except GarthHTTPError:
        logger.info("Aktivität möglicherweise schon bei Garmin Connect vorhanden.")

if __name__ == "__main__":
    main()
 
Das Script habe ich hier. Man muss noch den Download-Path eintragen. Falls es nicht richtig startet, kopiere die Fehlermeldung in einen KI-Chat. Da wird dir der Rest erklärt.

Code:
#!/usr/bin/env python3
import os
import re
from pathlib import Path
from datetime import datetime
from getpass import getpass
import logging

import garth
from garth.exc import GarthException, GarthHTTPError
from fit_tool.fit_file import FitFile
from fit_tool.fit_file_builder import FitFileBuilder
from fit_tool.profile.messages.record_message import RecordMessage, RecordTemperatureField
from fit_tool.profile.messages.session_message import SessionMessage
from fit_tool.profile.messages.lap_message import LapMessage
from fit_tool.profile.messages.file_id_message import FileIdMessage

# === Logging ===
SCRIPT_DIR = Path(__file__).resolve().parent
log_file_path = SCRIPT_DIR / "myWhoosh2Garmin.log"
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
file_handler = logging.FileHandler(log_file_path)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)

# === Pfade ===
MYWHOOSH_PATH = Path("Download-Path")
BACKUP_PATH = MYWHOOSH_PATH / "backup"
BACKUP_PATH.mkdir(exist_ok=True)

# === Garmin Auth ===
TOKENS_PATH = SCRIPT_DIR / '.garth'

def authenticate_to_garmin():
    try:
        if TOKENS_PATH.exists():
            garth.resume(TOKENS_PATH)
        else:
            username = input("Garmin Benutzername: ")
            password = getpass("Garmin Passwort: ")
            garth.login(username, password)
            garth.save(TOKENS_PATH)
        logger.info(f"Authenticated as: {garth.client.username}")
    except GarthException as e:
        logger.error(f"Garmin Auth Fehler: {e}")
        exit(1)

# === Hilfsfunktionen ===
def calculate_avg(values):
    return round(sum(values)/len(values),1) if values else 0

def append_value(values, message, field_name):
    val = getattr(message, field_name, None)
    if val is not None:
        values.append(val)

def reset_values():
    return [], [], []

def get_most_recent_fit_file(folder: Path) -> Path:
    fit_files = list(folder.glob("*.fit"))
    if not fit_files:
        return None
    return max(fit_files, key=os.path.getctime)

def generate_new_filename(fit_file: Path) -> Path:
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    return BACKUP_PATH / f"{fit_file.stem}_{timestamp}.fit"

# === Hauptlogik ===
def cleanup_fit_file(fit_file_path: Path, new_file_path: Path):
    builder = FitFileBuilder()
    fit_file = FitFile.from_file(str(fit_file_path))
    cadence_values, power_values, hr_values = reset_values()

    for record in fit_file.records:
        msg = record.message
        if isinstance(msg, FileIdMessage):
            # Override manufacturer/product but keep other fields
            msg.manufacturer = 1
            msg.product = 1836
        if isinstance(msg, LapMessage):
            continue
        if isinstance(msg, RecordMessage):
            msg.remove_field(RecordTemperatureField.ID)
            append_value(cadence_values, msg, "cadence")
            append_value(power_values, msg, "power")
            append_value(hr_values, msg, "heart_rate")
        if isinstance(msg, SessionMessage):
            if not msg.avg_cadence:
                msg.avg_cadence = calculate_avg(cadence_values)
            if not msg.avg_power:
                msg.avg_power = calculate_avg(power_values)
            if not msg.avg_heart_rate:
                msg.avg_heart_rate = calculate_avg(hr_values)
            cadence_values, power_values, hr_values = reset_values()
        builder.add(msg)
           
    # Datei bauen und speichern
    builder.build().to_file(str(new_file_path))
    logger.info(f"Bereinigte Datei gespeichert: {new_file_path}")

# === Main ===
def main():
    authenticate_to_garmin()

    latest_fit = get_most_recent_fit_file(MYWHOOSH_PATH)
    if not latest_fit:
        logger.error(f"Keine FIT-Dateien in {MYWHOOSH_PATH} gefunden.")
        exit(1)

    logger.info(f"Neueste Datei: {latest_fit}")
    new_file = generate_new_filename(latest_fit)

    try:
        cleanup_fit_file(latest_fit, new_file)
    except Exception as e:
        logger.error(f"Fehler beim Bereinigen: {e}")
        exit(1)

    # Upload zu Garmin
    try:
        with open(new_file, "rb") as f:
            garth.client.upload(f)
        logger.info(f"Erfolgreich hochgeladen: {new_file}")
    except GarthHTTPError:
        logger.info("Aktivität möglicherweise schon bei Garmin Connect vorhanden.")

if __name__ == "__main__":
    main()

Ich möchte noch ergänzen, dass dazu natürlich Python installiert sein/werden muss. Das hatte ich nicht, aber mit Hilfe der KI ging auch diese Installation relativ rasch.
 
Hi zusammmen, das klingt doch alles nach guten Ansätzen.
Hat jemand eine Idee wie man das ggf auf dem iPad umsetzen kann? Einen Computer besitze ich nicht mehr..
 
Ich kenne mich da nicht so aus, aber gibt es nicht auch Python auf IOS? Frage doch mal eine KI, was du dafür tun musst.
Danke dir. Ich habe da versucht, schlau draus zu werden - ohne Erfolg. Mir fehlt da wohl ein bisschen technischer Background. Aber im Grunde sagt Microsofts Copilot mir, dass ich nur die Datei von Whoosh downloaden und dann bei Garmin hochladen kann. Naja, schade
 
Du kannst das doch Schritt für Schritt durchgehen. Kopiere das Script in den Chat mit der KI und frage, wie man das auf dem IPad nutzen kann. Das Script lädt dann die neuste Fit-Datei, die du vorher heruntergeladen hast, in einer angepassten Version auf Garmin hoch. Im Script muss wohl nur der Ordner eingegeben werden, wo deine Downloads liegen.
 
Zurück