最近带着小朋友在运动,小朋友看到运动记录都在我的Garmin Connect活动在一起,还有点不开心,希望有自己的账号,只有他自己的运动记录。于是就有了下面忙活的内容。
现在博客跑步的内容是通过yihong0618大佬的running_page实现跑步记录自动生成博文,详细可以看《跑步记录自动生成Markdown发布博文》。
大致思路就是如下:
- 申请一个新的Garmin Connect账号;
- python脚本实现:做一个fit文件的缓存;根据指定的时间找到对应的fit文件;上次fit文件到新注册的Garmin Connect账号;
- 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账号和密码修改。
到这里基本上就可以达到小朋友的目的,从我的运动记录里上传一起跑的记录到小朋友的账号。