Open Vensent opened 5 months ago
@Vensent @yihong0618 第五点和我的工作流相似,不过我是华为运动健康 -> Keep -> Strava。
我也是昨天才开始用running page,根据自己的想法修改了一些,完成了上面的工作流,但是还不算完善(在读博,确实没有太多时间搞)。
我是在@ben的基础上做的(因为他支持更多的运动类型)。
华为运动健康 -> Keep是可以APP自动绑定的,这点和OPPO一致。
只考虑 Keep 保存GPX,然后自动上传到strava即可。
目前支持的是 running, walking,cycling,因为现在我自己平时也就这些,后续可能根据需要添加远足,登山,爬楼。
为了快速实现,我是直接把keep_sync.py复制出了keep_sync_running.py,keep_sync_walking.py,keep_sync_cycling.py,分别对应上面的运动类型(ugly code)。
然后分别将里面对应的接口改为
# in keep_sync_running.py
RUN_DATA_API = "https://api.gotokeep.com/pd/v3/stats/detail?dateUnit=all&type=running&lastDate={last_date}"
RUN_LOG_API = "https://api.gotokeep.com/pd/v3/runninglog/{run_id}"
RUN_DATA_API = "https://api.gotokeep.com/pd/v3/stats/detail?dateUnit=all&type=hiking&lastDate={last_date}" RUN_LOG_API = "https://api.gotokeep.com/pd/v3/hikinglog/{run_id}"
RUN_DATA_API = "https://api.gotokeep.com/pd/v3/stats/detail?dateUnit=all&type=cycling&lastDate={last_date}" RUN_LOG_API = "https://api.gotokeep.com/pd/v3/cyclinglog/{run_id}"
3. 然后里面对应的数据类型分别修改为
```python
run_data["dataType"] == "outdoorRunning"
run_data["dataType"] == "outdoorCycling"
run_data["dataType"] == "outdoorWalking"
d = {
"id": int(keep_id),
"name": "cycling from keep",
# future to support others workout now only for run
"type": "Ride", # Run, Walk, Hike ...
...
在每个keep_sync_xxx.py中利用parse_points_to_gpx()写入gpx时,增加对应strava运动类型的type,保证上传gpx到strava时能提取到对应的类型。对应的GPX类型分别为:
gpx_track.type = "Run"
gpx_track.type = "Ride"
gpx_track.type = "Walk"
在 https://github.com/yihong0618/running_page/blob/eae7de259c430121c16b983b28c0fd68553025d7/run_page/utils.py#L95 位置添加一个运动类型的识别。
with open(file_name, "rb") as f:
x = gpxpy.parse(f)
try:
if x.tracks[0].type is not None:
r = client.upload_activity(
activity_file=f, data_type=data_type, activity_type=x.tracks[0].type
)
elif force_to_run:
r = client.upload_activity(
activity_file=f, data_type=data_type, activity_type="run"
)
...
- name: Run sync Keep script
if: env.RUN_TYPE == 'strava'
run: |
python run_page/keep_sync_walking.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx
python run_page/keep_sync_cycling.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx
python run_page/keep_sync_running.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx
python run_page/gpx_to_strava_sync.py ${{ secrets.STRAVA_CLIENT_ID }} ${{ secrets.STRAVA_CLIENT_SECRET }} ${{ secrets.STRAVA_CLIENT_REFRESH_TOKEN }}
- name: Run clean GPX
if: env.RUN_TYPE == 'strava'
run: |
touch GPX_OUT/tmp.txt
rm GPX_OUT/*
当然上面的都是可以合并到一起的,但是为了清爽一点,选择了拆开。
不过我这还有一些问题
if x.tracks[0].type is not None:
r = client.upload_activity(
activity_file=f, data_type=data_type, activity_type=x.tracks[0].type
))
print(x.tracks[0].type)
print(r)
output:
Walk
<stravalib.client.ActivityUploader object at 0x00000223B14241C0>
Uploading gpx file: D:\Toys\running_page\GPX_OUT\9223370324642451807.gpx to strava, upload_id: 11920271611.
但是,打开strava查看,发现没有任何更新。
我以为是我新生成的gpx有问题,然后我在网页端手动上传相应的gpx,是可以成功识别运动类型并且上传成功的(说明添加了type的gpx没有问题),但是手动上传一天最多30条。
所以验证过后就是
上面三次的运动记录都是相同的,唯一的区别就是,该数据使用未经过5,6步修改的上传脚本上传过后,我手动在strava中删掉了这条记录。后面使用新脚本生成了新gpx上传提示成功,不过strava没有任何记录,但是手动上传该gpx是可以的。 所以我猜测 ”如果在strava中删除了一条由脚本上传的运动记录,该运动记录将无法再次通过脚本上传,必须转成手动上传。但是我无法验证这一条了,因为我这两天没有户外运动。“ 不清楚我的猜测对不对,或许有人可以试一下我修改后的脚本,上传全新从未上传过的运动数据。
@Vensent @yihong0618 第五点和我的工作流相似,不过我是华为运动健康 -> Keep -> Strava。
我也是昨天才开始用running page,根据自己的想法修改了一些,完成了上面的工作流,但是还不算完善(在读博,确实没有太多时间搞)。
我是在@ben的基础上做的(因为他支持更多的运动类型)。
华为运动健康 -> Keep是可以APP自动绑定的,这点和OPPO一致。
只考虑 Keep 保存GPX,然后自动上传到strava即可。
目前支持的是 running, walking,cycling,因为现在我自己平时也就这些,后续可能根据需要添加远足,登山,爬楼。
- 为了快速实现,我是直接把keep_sync.py复制出了keep_sync_running.py,keep_sync_walking.py,keep_sync_cycling.py,分别对应上面的运动类型(ugly code)。
- 然后分别将里面对应的接口改为
# in keep_sync_running.py RUN_DATA_API = "https://api.gotokeep.com/pd/v3/stats/detail?dateUnit=all&type=running&lastDate={last_date}" RUN_LOG_API = "https://api.gotokeep.com/pd/v3/runninglog/{run_id}" # in keep_sync_walking.py RUN_DATA_API = "https://api.gotokeep.com/pd/v3/stats/detail?dateUnit=all&type=hiking&lastDate={last_date}" RUN_LOG_API = "https://api.gotokeep.com/pd/v3/hikinglog/{run_id}" # in keep_sync_cycling.py RUN_DATA_API = "https://api.gotokeep.com/pd/v3/stats/detail?dateUnit=all&type=cycling&lastDate={last_date}" RUN_LOG_API = "https://api.gotokeep.com/pd/v3/cyclinglog/{run_id}"
- 然后里面对应的数据类型分别修改为
run_data["dataType"] == "outdoorRunning" run_data["dataType"] == "outdoorCycling" run_data["dataType"] == "outdoorWalking"
- 当然相应的也要修改
d = { "id": int(keep_id), "name": "cycling from keep", # future to support others workout now only for run "type": "Ride", # Run, Walk, Hike ... ...
- 在每个keep_sync_xxx.py中利用parse_points_to_gpx()写入gpx时,增加对应strava运动类型的type,保证上传gpx到strava时能提取到对应的类型。对应的GPX类型分别为:
gpx_track.type = "Run" gpx_track.type = "Ride" gpx_track.type = "Walk"
- 在 https://github.com/yihong0618/running_page/blob/eae7de259c430121c16b983b28c0fd68553025d7/run_page/utils.py#L95 位置添加一个运动类型的识别。
with open(file_name, "rb") as f: x = gpxpy.parse(f) try: if x.tracks[0].type is not None: r = client.upload_activity( activity_file=f, data_type=data_type, activity_type=x.tracks[0].type ) elif force_to_run: r = client.upload_activity( activity_file=f, data_type=data_type, activity_type="run" ) ...
- .github/workflows/run_data_sync.yml 中修改了一下, RUN_TYPE: strava,以及keep位置动了一下
- name: Run sync Keep script if: env.RUN_TYPE == 'strava' run: | python run_page/keep_sync_walking.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/keep_sync_cycling.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/keep_sync_running.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/gpx_to_strava_sync.py ${{ secrets.STRAVA_CLIENT_ID }} ${{ secrets.STRAVA_CLIENT_SECRET }} ${{ secrets.STRAVA_CLIENT_REFRESH_TOKEN }}
- 额外加了一个,让仓库干净一点。
- name: Run clean GPX if: env.RUN_TYPE == 'strava' run: | touch GPX_OUT/tmp.txt rm GPX_OUT/*
当然上面的都是可以合并到一起的,但是为了清爽一点,选择了拆开。
不过我这还有一些问题
- strava好像上传有限制?我遇到了奇怪的问题。我第一次上传keep导出的gpx时候没有添加类型的区分(也就是5,6步),导致上传到strava后都是”跑步“(还是锻炼啥的,我也忘记了,反正不是实际对应的运动类型),然后又懒得一个个改,就在strava中全给删掉了,在第5步添加运动类型到gpx以后以及第6步添加了上传时类型识别之后,重新运行脚本上传,也提示上传成功,
if x.tracks[0].type is not None: r = client.upload_activity( activity_file=f, data_type=data_type, activity_type=x.tracks[0].type )) print(x.tracks[0].type) print(r)
output:
Walk <stravalib.client.ActivityUploader object at 0x00000223B14241C0> Uploading gpx file: D:\Toys\running_page\GPX_OUT\9223370324642451807.gpx to strava, upload_id: 11920271611.
但是,打开strava查看,发现没有任何更新。
我以为是我新生成的gpx有问题,然后我在网页端手动上传相应的gpx,是可以成功识别运动类型并且上传成功的(说明添加了type的gpx没有问题),但是手动上传一天最多30条。
所以验证过后就是
- keep -> 无type的gpx(原版代码) ->strava (run_page/gpx_to_strava_sync.py未添加type), 成功
- keep -> 有type的gpx -> strava (run_page/gpx_to_strava_sync.py 添加了type),输出成功,但是网页端没有更新。
- keep -> 有type的gpx -> strava (网页手动),成功
上面三次的运动记录都是相同的,唯一的区别就是,该数据使用未经过5,6步修改的上传脚本上传过后,我手动在strava中删掉了这条记录。后面使用新脚本生成了新gpx上传提示成功,不过strava没有任何记录,但是手动上传该gpx是可以的。 所以我猜测 ”如果在strava中删除了一条由脚本上传的运动记录,该运动记录将无法再次通过脚本上传,必须转成手动上传。但是我无法验证这一条了,因为我这两天没有户外运动。“ 不清楚我的猜测对不对,或许有人可以试一下我修改后的脚本,上传全新从未上传过的运动数据。
- 第二个问题,那就是keep保存了gpx时(会写入data.db和activity.json)并上传到strava之后,然后运行strava_sync,该记录会被重复写入到activity.json,导致展示页面出现重复数据。 比如这是我的https://songj.xyz/, 可以发现里面有重复数据
谢谢分享。
FYI, 我自己用的是 nike_to_strava 因为自己有需求。 https://github.com/yihong0618/run
@Vensent @yihong0618 第五点和我的工作流相似,不过我是华为运动健康 -> Keep -> Strava。
我也是昨天才开始用running page,根据自己的想法修改了一些,完成了上面的工作流,但是还不算完善(在读博,确实没有太多时间搞)。
我是在@ben的基础上做的(因为他支持更多的运动类型)。
华为运动健康 -> Keep是可以APP自动绑定的,这点和OPPO一致。
只考虑 Keep 保存GPX,然后自动上传到strava即可。
目前支持的是 running, walking,cycling,因为现在我自己平时也就这些,后续可能根据需要添加远足,登山,爬楼。
- 为了快速实现,我是直接把keep_sync.py复制出了keep_sync_running.py,keep_sync_walking.py,keep_sync_cycling.py,分别对应上面的运动类型(ugly code)。
- 然后分别将里面对应的接口改为
# in keep_sync_running.py RUN_DATA_API = "https://api.gotokeep.com/pd/v3/stats/detail?dateUnit=all&type=running&lastDate={last_date}" RUN_LOG_API = "https://api.gotokeep.com/pd/v3/runninglog/{run_id}" # in keep_sync_walking.py RUN_DATA_API = "https://api.gotokeep.com/pd/v3/stats/detail?dateUnit=all&type=hiking&lastDate={last_date}" RUN_LOG_API = "https://api.gotokeep.com/pd/v3/hikinglog/{run_id}" # in keep_sync_cycling.py RUN_DATA_API = "https://api.gotokeep.com/pd/v3/stats/detail?dateUnit=all&type=cycling&lastDate={last_date}" RUN_LOG_API = "https://api.gotokeep.com/pd/v3/cyclinglog/{run_id}"
- 然后里面对应的数据类型分别修改为
run_data["dataType"] == "outdoorRunning" run_data["dataType"] == "outdoorCycling" run_data["dataType"] == "outdoorWalking"
- 当然相应的也要修改
d = { "id": int(keep_id), "name": "cycling from keep", # future to support others workout now only for run "type": "Ride", # Run, Walk, Hike ... ...
- 在每个keep_sync_xxx.py中利用parse_points_to_gpx()写入gpx时,增加对应strava运动类型的type,保证上传gpx到strava时能提取到对应的类型。对应的GPX类型分别为:
gpx_track.type = "Run" gpx_track.type = "Ride" gpx_track.type = "Walk"
- 在 https://github.com/yihong0618/running_page/blob/eae7de259c430121c16b983b28c0fd68553025d7/run_page/utils.py#L95 位置添加一个运动类型的识别。
with open(file_name, "rb") as f: x = gpxpy.parse(f) try: if x.tracks[0].type is not None: r = client.upload_activity( activity_file=f, data_type=data_type, activity_type=x.tracks[0].type ) elif force_to_run: r = client.upload_activity( activity_file=f, data_type=data_type, activity_type="run" ) ...
- .github/workflows/run_data_sync.yml 中修改了一下, RUN_TYPE: strava,以及keep位置动了一下
- name: Run sync Keep script if: env.RUN_TYPE == 'strava' run: | python run_page/keep_sync_walking.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/keep_sync_cycling.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/keep_sync_running.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/gpx_to_strava_sync.py ${{ secrets.STRAVA_CLIENT_ID }} ${{ secrets.STRAVA_CLIENT_SECRET }} ${{ secrets.STRAVA_CLIENT_REFRESH_TOKEN }}
- 额外加了一个,让仓库干净一点。
- name: Run clean GPX if: env.RUN_TYPE == 'strava' run: | touch GPX_OUT/tmp.txt rm GPX_OUT/*
当然上面的都是可以合并到一起的,但是为了清爽一点,选择了拆开。
不过我这还有一些问题
- strava好像上传有限制?我遇到了奇怪的问题。我第一次上传keep导出的gpx时候没有添加类型的区分(也就是5,6步),导致上传到strava后都是”跑步“(还是锻炼啥的,我也忘记了,反正不是实际对应的运动类型),然后又懒得一个个改,就在strava中全给删掉了,在第5步添加运动类型到gpx以后以及第6步添加了上传时类型识别之后,重新运行脚本上传,也提示上传成功,
if x.tracks[0].type is not None: r = client.upload_activity( activity_file=f, data_type=data_type, activity_type=x.tracks[0].type )) print(x.tracks[0].type) print(r)
output:
Walk <stravalib.client.ActivityUploader object at 0x00000223B14241C0> Uploading gpx file: D:\Toys\running_page\GPX_OUT\9223370324642451807.gpx to strava, upload_id: 11920271611.
但是,打开strava查看,发现没有任何更新。
我以为是我新生成的gpx有问题,然后我在网页端手动上传相应的gpx,是可以成功识别运动类型并且上传成功的(说明添加了type的gpx没有问题),但是手动上传一天最多30条。
所以验证过后就是
- keep -> 无type的gpx(原版代码) ->strava (run_page/gpx_to_strava_sync.py未添加type), 成功
- keep -> 有type的gpx -> strava (run_page/gpx_to_strava_sync.py 添加了type),输出成功,但是网页端没有更新。
- keep -> 有type的gpx -> strava (网页手动),成功
上面三次的运动记录都是相同的,唯一的区别就是,该数据使用未经过5,6步修改的上传脚本上传过后,我手动在strava中删掉了这条记录。后面使用新脚本生成了新gpx上传提示成功,不过strava没有任何记录,但是手动上传该gpx是可以的。 所以我猜测 ”如果在strava中删除了一条由脚本上传的运动记录,该运动记录将无法再次通过脚本上传,必须转成手动上传。但是我无法验证这一条了,因为我这两天没有户外运动。“ 不清楚我的猜测对不对,或许有人可以试一下我修改后的脚本,上传全新从未上传过的运动数据。
- 第二个问题,那就是keep保存了gpx时(会写入data.db和activity.json)并上传到strava之后,然后运行strava_sync,该记录会被重复写入到activity.json,导致展示页面出现重复数据。 比如这是我的https://songj.xyz/, 可以发现里面有重复数据
新思路不错
@SongJgit 感觉你说的重复的问题,可以通过切分支或者新拉个仓来解决。就是不同的工作流使用不同的分支或者仓来做,互不影响。
看了你发的我感觉直接用Keep不是什么好办法,太复杂了。因为我在OPPO上班,我准备联系看看接入一下我们公司的开放平台来捞数据,越过keep这一步。
要是这条路打通了可以发个PR么? @yihong0618
@SongJgit 感觉你说的重复的问题,可以通过切分支或者新拉个仓来解决。就是不同的工作流使用不同的分支或者仓来做,互不影响。
看了你发的我感觉直接用Keep不是什么好办法,太复杂了。因为我在OPPO上班,我准备联系看看接入一下我们公司的开放平台来捞数据,越过keep这一步。
要是这条路打通了可以发个PR么? @yihong0618
当然可以,不过 OPPO 有这么开放么😂
@SongJgit 感觉你说的重复的问题,可以通过切分支或者新拉个仓来解决。就是不同的工作流使用不同的分支或者仓来做,互不影响。 看了你发的我感觉直接用Keep不是什么好办法,太复杂了。因为我在OPPO上班,我准备联系看看接入一下我们公司的开放平台来捞数据,越过keep这一步。 要是这条路打通了可以发个PR么? @yihong0618
当然可以,不过 OPPO 有这么开放么😂
我联系我们公司的同事帮我开了个健康开放平台的id和token了,有点像Strava的那种认证方式,我先试试看能不能打通。
2. 第二个问题,那就是keep保存了gpx时(会写入data.db和activity.json)并上传到strava之后,然后运行strava_sync,该记录会被重复写入到activity.json,导致展示页面出现重复数据。 比如这是我的https://songj.xyz/, 可以发现里面有重复数据
@SongJgit 造成重复的原因在这:
13. .github/workflows/run_data_sync.yml 中修改了一下, RUN_TYPE: strava,以及keep位置动了一下
- name: Run sync Keep script if: env.RUN_TYPE == 'strava' run: | python run_page/keep_sync_walking.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/keep_sync_cycling.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/keep_sync_running.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/gpx_to_strava_sync.py ${{ secrets.STRAVA_CLIENT_ID }} ${{ secrets.STRAVA_CLIENT_SECRET }} ${{ secrets.STRAVA_CLIENT_REFRESH_TOKEN }}
1.keep_sync*
同步了 keep 的 gpx 记录
2.gpx_to_strava_sync
上传 gpx 的同时,也同步了 strava 新上传的记录
而这两个被当成了不同的记录
要想解决重复的问题也很简单,有以下三个方案:
run_id
字段, 看能否用同一个keep_sync*
注释掉保存 data.db 部分,只做 gpx 下载gpx_to_strava_sync
注释掉同步 strava 部分,只做 gpx 上传@SongJgit 感觉你说的重复的问题,可以通过切分支或者新拉个仓来解决。就是不同的工作流使用不同的分支或者仓来做,互不影响。
看了你发的我感觉直接用Keep不是什么好办法,太复杂了。因为我在OPPO上班,我准备联系看看接入一下我们公司的开放平台来捞数据,越过keep这一步。
要是这条路打通了可以发个PR么? @yihong0618
其实keep这条路还算不错,复杂是因为我说的比较详细,基本都是在描述数据的获取,以及不同app之间的运动类型对齐。比如,keep叫outdoorRunning,但是strava就叫Run,其他的app也都有各自的命名与区分,即使是oppo导出也还是需要和运动类型对齐才能同步上去。
至于oppo直连strava应该是不可能的(好像是因为隐私数据不准出境,比如rq,zepp,华为这些非国内账号本身都可以直连strava,但是国内账号却都不行,甚至之前health sync国内也可以直连,现在好像都不行了,连gps都获取不到了。当然,如果个人做的话可能没这种限制?),我觉得华为,oppo之类的能做到直出gpx就很棒了,或者能直连国内佳明(这样就可以自动同步到国际然后strava了)。
- 第二个问题,那就是keep保存了gpx时(会写入data.db和activity.json)并上传到strava之后,然后运行strava_sync,该记录会被重复写入到activity.json,导致展示页面出现重复数据。 比如这是我的https://songj.xyz/, 可以发现里面有重复数据
@SongJgit 造成重复的原因在这:
- .github/workflows/run_data_sync.yml 中修改了一下, RUN_TYPE: strava,以及keep位置动了一下
- name: Run sync Keep script if: env.RUN_TYPE == 'strava' run: | python run_page/keep_sync_walking.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/keep_sync_cycling.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/keep_sync_running.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/gpx_to_strava_sync.py ${{ secrets.STRAVA_CLIENT_ID }} ${{ secrets.STRAVA_CLIENT_SECRET }} ${{ secrets.STRAVA_CLIENT_REFRESH_TOKEN }}
1.
keep_sync*
同步了 keep 的 gpx 记录 2.gpx_to_strava_sync
上传 gpx 的同时,也同步了 strava 新上传的记录 而这两个被当成了不同的记录要想解决重复的问题也很简单,有以下三个方案:
- 检查 keep gpx 和 strava 的
run_id
字段, 看能否用同一个keep_sync*
注释掉保存 data.db 部分,只做 gpx 下载gpx_to_strava_sync
注释掉同步 strava 部分,只做 gpx 上传
嗯,昨天下午看了一下你的代码之后已经解决了。 1.一开始我考虑过改runid,但是似乎只有上传strava的时候才能知道strava的run id?这个时候才知道runid的话还需要去动数据库,为了简单点,选择放弃该方法。 2.只做gpx下载我也考虑过,但是不写入db的话,后面又要添加新旧记录的判断又会额外增加工作量。 3.我骑车是佳明码表,跑步和徒步是华为运动健康,所以最方便的办法是综合到strava,然后用strava做展示,所以即使注释掉这里的同步strava,我最后还是要用run strava sync来同步展示的😅。
所以最后我的思路是,keep和strava都写入db但是keep不写入act(因为我还需要data.db判断是否已经下载过该keep记录了)。不过这样做的另一个缺点就是,一旦写入了db,后面的gen_svg也需要补充一下过滤条件,过滤掉来自keep的记录,不然会重复统计。但是相对于其他的方法来说,这样的工作量与代码复杂性要小很多。由于我没有仔细读过代码,我不知道这样做是否还会引发其他的bug?
已经把问题都解决了。 写了一个支持多运动类型的keep_to_strava, 解决了无法上传和重复的问题,不需要额外的增加过滤之类的,也不会重复写入db和activities.json.
这个方案可以作为华为运动健康->strava的解决方案(理论上,只要支持和keep同步就可以同步到strava(包括oppo/vivo?)). 有必要提个PR?@yihong0618
借这个issue我其实有个一直想问的问题,为啥我们拿到了gpx或者tcx或者fit文件,没有办法直接传到Garmin呢? @SongJgit @yihong0618 我今天看了一下整体的逻辑,把欢太健康(就是OPPO)的数据算是打通了,晚上着手写一下直接oppo2strava,不走keep这一条路。试试看效果。
借这个issue我其实有个一直想问的问题,为啥我们拿到了gpx或者tcx或者fit文件,没有办法直接传到Garmin呢? @SongJgit @yihong0618 我今天看了一下整体的逻辑,把欢太健康(就是OPPO)的数据算是打通了,晚上着手写一下直接oppo2strava,不走keep这一条路。试试看效果。
我已经提了相关的pr。 huawei -> keep -> Strava 华为的缺点是无法直接拿到gpx,只能被迫走keep/咕咚/悦跑圈。 OPPO能直接拿到GPX的话,那就可以省略中转,而直接strava了。
借这个issue我其实有个一直想问的问题,为啥我们拿到了gpx或者tcx或者fit文件,没有办法直接传到Garmin呢? @SongJgit @yihong0618 我今天看了一下整体的逻辑,把欢太健康(就是OPPO)的数据算是打通了,晚上着手写一下直接oppo2strava,不走keep这一条路。试试看效果。
对了,提醒一下,避免掉入我之前的坑里。 我之前提示上传成功,但是实际上失败的原因是因为x = gpxpy.parse(f), 我猜是因为没有释放, 导致上传失败,今天看了strava api之后发现完全不需要额外识别运动类型的,它们会自动解析gpx的type字段。https://developers.strava.com/docs/uploads/
activity_type:
Deprecated: prefer using sport_type, will be ignored if sport_type is included. Overrides type detected from file, if left unspecified type detected from file will be used.
借这个issue我其实有个一直想问的问题,为啥我们拿到了gpx或者tcx或者fit文件,没有办法直接传到Garmin呢? @SongJgit @yihong0618 我今天看了一下整体的逻辑,把欢太健康(就是OPPO)的数据算是打通了,晚上着手写一下直接oppo2strava,不走keep这一条路。试试看效果。
对了,提醒一下,避免掉入我之前的坑里。 我之前提示上传成功,但是实际上失败的原因是因为x = gpxpy.parse(f), 我猜是因为没有释放, 导致上传失败,今天看了strava api之后发现完全不需要额外识别运动类型的,它们会自动解析gpx的type字段。https://developers.strava.com/docs/uploads/
activity_type: Deprecated: prefer using sport_type, will be ignored if sport_type is included. Overrides type detected from file, if left unspecified type detected from file will be used.
好的,感谢。
@yihong0618 @ben-29 问一下二位,我在处理数据的时候,看到直接解析oppo然后转出gpx的文件,和脚本解析出来的keep的有一些差别。 这是keep的数据截图:
这是oppo我做的脚本的截图:
二者为什么会有移动时长的区别,是因为我处理数据的采样点太多了么,差不多是每秒一次,数组长度在1480左右,而keep的数据长度是580左右。是这个原因么
这个应该是keep自己的问题。 因为传到keep里是没有问题的,但是从keep传到strava就会天然的多或少几十米。不知道keep自己内部是怎么处理的数据。 话说,同一个运动,keep导出的和oppo直出的gpx,两者的起始/结束点的时间以及经纬度一致吗。 很期待你的工作,因为我oppo健康里还有一年的运动数据无法导出
这个应该是keep自己的问题。 因为传到keep里是没有问题的,但是从keep传到strava就会天然的多或少几十米。不知道keep自己内部是怎么处理的数据。 话说,同一个运动,keep导出的和oppo直出的gpx,两者的起始/结束点的时间以及经纬度一致吗。 很期待你的工作,因为我oppo健康里还有一年的运动数据无法导出
@SongJgit 是一致的。 我这边基本上打通了,有一些小bug要调试。但是oppo的数据设计太垃圾了(不得不吐槽我司,真的)两个查询接口做的实在不好恭维。 还有就是这种开发者权限不知道短时间能不能开放给其他人,我帮你问问。方便的话加我个微信吧,我们细聊,vx:86836661
这个应该是keep自己的问题。 因为传到keep里是没有问题的,但是从keep传到strava就会天然的多或少几十米。不知道keep自己内部是怎么处理的数据。 话说,同一个运动,keep导出的和oppo直出的gpx,两者的起始/结束点的时间以及经纬度一致吗。 很期待你的工作,因为我oppo健康里还有一年的运动数据无法导出
我发现我换了一种更贴近keep的处理方法,能解决上面我说的移动时间的问题。导出的gpx放进佳明connect,甚至会告诉我说keep的一摸一样,重复导入了。两者的起始、结束时间以及经纬度都对的上,这就说明了现在这种做法和keep是一样的结果。
但是现在遇到的问题是如果用这个keep的方式,因为gps一开始可能没有搜到星就跑了,gps打点的数据漏了一部分。导致运动时长要丢失一部分,这个大佬们有没有遇到过,有没有好的处理方法? @ben-29 @yihong0618
但是现在遇到的问题是如果用这个keep的方式,因为gps一开始可能没有搜到星就跑了,gps打点的数据漏了一部分。导致运动时长要丢失一部分,这个大佬们有没有遇到过,有没有好的处理方法? @ben-29 @yihong0618
没遇到过,在意的话,建议就 跑步的时候,等搜星成功后再开跑。 如果是要 gps 点,没有记录到也没办法了。 如果在意的是时长,记录里有开跑时间吗?在gpx轨迹点最前面插入一个开跑时间的点,可以不
- 第二个问题,那就是keep保存了gpx时(会写入data.db和activity.json)并上传到strava之后,然后运行strava_sync,该记录会被重复写入到activity.json,导致展示页面出现重复数据。 比如这是我的https://songj.xyz/, 可以发现里面有重复数据
@SongJgit 造成重复的原因在这:
- .github/workflows/run_data_sync.yml 中修改了一下, RUN_TYPE: strava,以及keep位置动了一下
- name: Run sync Keep script if: env.RUN_TYPE == 'strava' run: | python run_page/keep_sync_walking.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/keep_sync_cycling.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/keep_sync_running.py ${{ secrets.KEEP_MOBILE }} ${{ secrets.KEEP_PASSWORD }} --with-gpx python run_page/gpx_to_strava_sync.py ${{ secrets.STRAVA_CLIENT_ID }} ${{ secrets.STRAVA_CLIENT_SECRET }} ${{ secrets.STRAVA_CLIENT_REFRESH_TOKEN }}
1.
keep_sync*
同步了 keep 的 gpx 记录 2.gpx_to_strava_sync
上传 gpx 的同时,也同步了 strava 新上传的记录 而这两个被当成了不同的记录 要想解决重复的问题也很简单,有以下三个方案:
- 检查 keep gpx 和 strava 的
run_id
字段, 看能否用同一个keep_sync*
注释掉保存 data.db 部分,只做 gpx 下载gpx_to_strava_sync
注释掉同步 strava 部分,只做 gpx 上传嗯,昨天下午看了一下你的代码之后已经解决了。 1.一开始我考虑过改runid,但是似乎只有上传strava的时候才能知道strava的run id?这个时候才知道runid的话还需要去动数据库,为了简单点,选择放弃该方法。 2.只做gpx下载我也考虑过,但是不写入db的话,后面又要添加新旧记录的判断又会额外增加工作量。 3.我骑车是佳明码表,跑步和徒步是华为运动健康,所以最方便的办法是综合到strava,然后用strava做展示,所以即使注释掉这里的同步strava,我最后还是要用run strava sync来同步展示的😅。
所以最后我的思路是,keep和strava都写入db但是keep不写入act(因为我还需要data.db判断是否已经下载过该keep记录了)。不过这样做的另一个缺点就是,一旦写入了db,后面的gen_svg也需要补充一下过滤条件,过滤掉来自keep的记录,不然会重复统计。但是相对于其他的方法来说,这样的工作量与代码复杂性要小很多。由于我没有仔细读过代码,我不知道这样做是否还会引发其他的bug?
这个数据重复的问题,我这边有一个我觉得比较好的方式,你可以参考一下:
Action的话你使用两个,一个是主Action,用于sync你的主要数据源并展示,同时注意你用一个特定的key来标记使用对应的Cache。
另外一个是数据同步的Action,用于把你的keep同步到Strava(我的是oppo到garmin到strava)的。使用另外一个key来标记特定的缓存Cache。
两个Action各自工作,分别使用不同的db和activitys.json。可以参考我的这笔提交:数据源和页面展示使用不同的Cache
首先感谢yihong大神,这个开源项目真的很赞!
然后是workflow和action,只要是部署成功一次之后,后续Github会自动帮我们运行拉取的操作么?如果是的话频率大概是多久一次呢?
折腾成功了终于把页面弄出来了,符合预期,想问问可否把我页面也加到yihong大神的readme里面(跑步正好10年,诚惶诚恐)。页面地址:https://vensent.github.io/workouts_page/
最近Garmin 945坏掉了,因为在OPPO上班,想强力支持一波我司的手表,所以最近换手表了,所以关于页面有些问题我想这么搞你看看行不行。
我首先拉一个主发布分支(也就是master),就只用Garmin的数据,其他所有的数据都不管。
为了发布更干净,我拉第二个数据分支(data_retrieve),前提是公司OPPO手表欢太健康的数据先通过手机上的账号绑定同步到keep,然后定时拉取keep到gpx的文件夹下,然后运行导入gpx到strava,然后再运行strava to Garmin和strava to Garmin CN,这样能保证第一个分支以及网页能拉到最新的数据。
能行不,这个思路?