最近带着小朋友在运动,小朋友看到运动记录都在我的Garmin Connect活动在一起,还有点不开心,希望有自己的账号,只有他自己的运动记录。于是就有了下面忙活的内容。

现在博客跑步的内容是通过yihong0618大佬的running_page实现跑步记录自动生成博文,详细可以看《跑步记录自动生成Markdown发布博文》

大致思路就是如下:

  1. 申请一个新的Garmin Connect账号;
  2. python脚本实现:做一个fit文件的缓存;根据指定的时间找到对应的fit文件;上次fit文件到新注册的Garmin Connect账号;
  3. shell脚本实现:接收时间参数;获取Garmin Connect账号密钥;执行python脚本。

Garmin Connect账号注册

账号注册时需要注意,Garmin有国内账号和国际账号的区分,因此如果这方面需求的可以稍微注意一下。

国内账号地址:https://connect.garmin.cn/

国际账号地址:https://connectus.garmin.cn/

python同步脚本

下面的脚本放在run_page工程下的run_page目录下:

import argparse  
import asyncio  
import json  
import os  
from datetime import datetime  
  
import config  
from garmin_sync import Garmin  
from gpxtrackposter.track_loader import load_fit_file  
  
FIT_FOLDER = os.path.join(config.parent, "FIT_OUT")  
FIT_CACHE_FILE = os.path.join(config.parent, "fit_cache.json")  
  
def save_fit_cache_list(fit_cache_list):  
  with open(FIT_CACHE_FILE, "w") as f:  
    json.dump(fit_cache_list, f)  
  
  
def load_fit_cache_list():  
  if os.path.exists(FIT_CACHE_FILE):  
    with open(FIT_CACHE_FILE, "r") as f:  
      try:  
        return json.load(f)  
      except Exception as e:  
        print(f"json load {FIT_CACHE_FILE} \nerror {e}")  
        pass  
  
  return {}  
  
def upload_files_to_garmin(options):  
    print("Need to load all fit files maybe take some time")  
  
    fit_cache_list = load_fit_cache_list()  
  
    file_names = []  
  
    for file_name in os.listdir(FIT_FOLDER):  
        if file_name.endswith('.fit') and file_name not in fit_cache_list:  
            file_names.append(file_name)  
  
    for file_name in file_names:  
        track = load_fit_file(os.path.join(FIT_FOLDER, file_name))  
        if track.start_time_local:  
            fit_cache_list[file_name] = datetime.strftime(track.start_time_local, "%Y-%m-%d:%H:%M:%S")  
        save_fit_cache_list(fit_cache_list)  
  
    to_upload_files = []  
    if options.dt is not None:  
        dts = options.dt.split(",")  
        for dt in dts:  
            for file_name in fit_cache_list:  
                if fit_cache_list[file_name].startswith(dt):  
                    to_upload_files.append(os.path.join(FIT_FOLDER, file_name))  
                    break  
    print("Uploading files to Garmin...")  
    garmin_auth_domain = "CN" if options.is_cn else ""  
    garmin_client = Garmin(options.secret_string, garmin_auth_domain)  
    loop = asyncio.get_event_loop()  
    future = asyncio.ensure_future(  
        garmin_client.upload_activities_files(to_upload_files)  
    )  
    loop.run_until_complete(future)  
  
  
  
if __name__ == "__main__":  
    if not os.path.exists(FIT_FOLDER):  
        os.mkdir(FIT_FOLDER)  
    parser = argparse.ArgumentParser()  
    parser.add_argument(  
        "secret_string", nargs="?", help="secret_string fro get_garmin_secret.py"  
    )  
    parser.add_argument(  
        "--dt",  
        dest="dt",  
        help="if upload to strava all without check last time",  
    )  
    parser.add_argument(  
        "--is-cn",  
        dest="is_cn",  
        action="store_true",  
        help="if garmin account is cn",  
    )  
  
    upload_files_to_garmin(parser.parse_args())

使用方式,如上传2025-06-22:20,2025-06-22:21两个时间相关的运动记录到新账号。

special_to_garmin_sync.py garmin_secret --dt 2025-06-22:20,2025-06-22:21 --is-cn

Shell脚本

#!/bin/bash
# 检查是否提供了两个参数
if [ "$#" -ne 1 ]; then
    echo "用法: $0 <运动时间,多个时间英文逗号隔开> "
    echo "示例: $0 2025-06-22:20,2025-06-22:21"
    exit 1 # 如果参数数量不对,退出并返回错误码
fi
dt="$1"

workouts_page='/xxx/workouts_page'

cd $workouts_page
source venv/bin/activate

echo '获取garmin token'
garmin_cn_secret=$(python3 run_page/get_garmin_secret.py 账号 "密码" --is-cn)

echo '上传指定时间积累'
python3 run_page/special_to_garmin_sync.py $garmin_cn_secret --dt $dt --is-cn

echo "Done"
deactivate

需要将run_page工程地址进行修改,Garmin Connect账号和密码修改。

到这里基本上就可以达到小朋友的目的,从我的运动记录里上传一起跑的记录到小朋友的账号。