Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Send course to watch functionality #36

Open
lcorbet opened this Issue Oct 12, 2012 · 21 comments

Comments

Projects
None yet
6 participants

lcorbet commented Oct 12, 2012

I know, it's not the intention of the application, but I wanted to put this concept out there.

Send course to watch:

  • Using something like bikeroutetoaster, create a course.
  • Save it to the computer as a *.tcx.
  • Send it to the watch via the ant stick.

I find it useful to use when jogging in a foreign/unfamiliar place.

Perhaps we can assess interest via comments to this 'issue'?
Is it possible?
It is feasible?

Owner

Tigge commented Oct 17, 2012

It's very much possible, and feasible. I'm planning to add the remaining file actions, such as create, upload, delete to the program at some point. This should not be that hard to add. The hardest part is probably to convert the course to the correct format. I'm guessing it should be in a FIT format.

But before doing this I need to refactor some code and make it possible to recover from errors -- i.e. reconnecting and retrying.

Owner

Tigge commented Nov 6, 2012

Some work done towards this is merged in 19bc8dc. Still missing some functionality but we are definitely closer to making this possible.

lcorbet commented Nov 7, 2012

Outstanding.
Love your work @Tigge !

Brilliant stuff, looking forward to this working - let me know if I can be any help with e.g. logs.

It'd be perfect if it wasn't restricted to courses, and allowed us to upload e.g. custom workouts, heart rate & pace zones and the like. These are all handled in variants on FIT files though so it shouldn't involve any extra work to handle them.

Owner

Tigge commented Nov 8, 2012

Yeah, It's coming along nicely and It will not be restricted to courses. Should be able to upload all types of supported FIT files

Owner

Tigge commented Nov 9, 2012

Created my first file on my 610 today, writing the CRC algorithm took a while. So to create a file: request write to special file 0xfffe, check response, upload create file command data to 0xfffe, check response, download request of 0xffe, check response for data, check data to see if create file command succeeded. That could have been a bit more easy, heh.

So, just gotta write to that file index I got from the create file response then. And then there is also the matter of knowing the file type of the file we are going to upload.. might need to bring in a dependency on dtcooper/python-fitparse here. (@dtcooper, is that possible to do with python-fitparse, or is it the file_id.type always at a specific offset that can be easily read? sorry for dragging you in here for questions 😄)

dtcooper commented Nov 9, 2012

You rang? 😛

It's definitely possible to check a field on any record (of any type) with python-fitparse. You can go through the <Activity>.records list, use a convenience function like <Activity>.get_records_by_type(...), or do so at parse time by hooking into <Activity>.parse(hook_func=<hook_function>).

Owner

Tigge commented Nov 10, 2012

But it is not the case that file_id.type is always located at a specific offset, since the file_id block is always first in the file? I've not up to speed on FIT files yet unfortunately. I'm a bit reluctant to add dependencies, but if there is no dead simple reliant way to do it then it shall be done :).

Ah. I haven't worked on the project in some time, so I'm not entirely sure. The FIT SDK docs that describe the file format might have your answer. Find them @ http://www.thisisant.com/pages/developer-zone/fit-sdk. 😃

Owner

Tigge commented Nov 20, 2012

Okay, some initial should work-thingy is available on the https://github.com/Tigge/Garmin-Forerunner-610-Extractor/tree/uploading branch. Note that this branch uses a slightly different directory structure so you might want to recreate your .config/garmin-extractor folder -- it'll warn you otherwise so. Start with --upload to upload new files placed in your profile folder.

And of course a big warning: ALWAYS BACKUP YOUR DATA, THIS MIGHT MESS STUFF UP.

Managed to succesfully send both a course and a workout (created using Garmin Connect, and downloaded using the Garmin Plugin at http://www.andreas-diesner.de/garminplugin/doku.php?id=start) to my 310xt, brilliant stuff. It did take several attempts to get the course to send succesfully but it got there in the end.

For some reason, once the course upload is successful the rename fails with:

  • Failed 96 heaton.FIT list index out of range

And despite the fact that the workout was renamed succesfully, it will still attempt to resend it next time it is run with --upload.

I guess there may be an issue now where if older activities are removed from the watch to free up space, running with --upload will attempt to resend them to the device?

All the same, brilliant stuff. I've tested the workout, and if the torrential rain stops I'll go for a run with the uploaded course then sync the activity back, which means I genuinely no longer have a reason to ever use my Windows virtual machine!

The most frequent exception during upload seems to me to be:

Uploading 2012-11-22_17-24-38_6_58.fit [.......Traceback (most recent call last):
File "./garmin.py", line 346, in main
g.start()
File "/home/steve/Garmin-Forerunner-610-Extractor/ant/fs/manager.py", line 191, in start
self._main()
File "/home/steve/Garmin-Forerunner-610-Extractor/ant/fs/manager.py", line 123, in _main
self.on_transport(beacon)
File "./garmin.py", line 254, in on_transport
index = self.upload_file(typ, filename)
File "./garmin.py", line 317, in upload_file
index = self.create(typ, data, self._get_progress_callback())
File "/home/steve/Garmin-Forerunner-610-Extractor/ant/fs/manager.py", line 221, in create
self.upload(result.get_index(), data, callback)
File "/home/steve/Garmin-Forerunner-610-Extractor/ant/fs/manager.py", line 236, in upload
upload_response = self._get_command()
File "/home/steve/Garmin-Forerunner-610-Extractor/ant/fs/manager.py", line 160, in _get_command
c = self._queue.get(True, timeout)
File "/usr/lib/python2.7/Queue.py", line 176, in get
raise Empty
Empty
Interrupted:

Owner

Tigge commented Nov 22, 2012

Great! If possible I'd like to take a look at those log files, it would be great if you can send them to me at tiggex@gmail.com.

As for the delete issue you mention; yeah, that is the case. Each time it connects to a device it needs to store the file index somewere and compare it with the old listings, but yeah, this isn't done yet. Hopefully this will also give a better way to keep track of added files to avoid the re-uploading issue.

Also, sometimes the watch downloads a totals file - then if those totals change on the watch, the next use of --upload will try and upload the old totals file. I believe I've read somewhere that certain fit filetypes are read only, including totals.

In this situation, you seem to get an AntFSCreateFileException.

I've also sent you the logs for the raise Empty issue above.

Owner

Tigge commented Nov 22, 2012

Yeah, that's true, some files are read only, should make sure those are not uploaded. I'll get started on this and the keeping track of files on the watch thingy. Will also analyse that log and see if something weird is going on. Thanks.

lcorbet commented Dec 25, 2012

Having some time over the holidays I've been able to test the uploading branch too.
Here's a traceback that I encounter when uploading a workout (downloaded from garminConnect using the linux plugin) :
...
Downloading 0 file(s) and uploading 2 file(s)
Uploading workout_622926.FIT [Traceback (most recent call last):
File "garmin.py", line 344, in main
g.start()
File "/home/linton/Apps/Garmin-Forerunner-610-Extractor/ant/fs/manager.py", line 191, in start
self._main()
File "/home/linton/Apps/Garmin-Forerunner-610-Extractor/ant/fs/manager.py", line 123, in _main
self.on_transport(beacon)
File "garmin.py", line 252, in on_transport
index = self.upload_file(typ, filename)
File "garmin.py", line 315, in upload_file
index = self.create(typ, data, self._get_progress_callback())
File "/home/linton/Apps/Garmin-Forerunner-610-Extractor/ant/fs/manager.py", line 221, in create
self.upload(result.get_index(), data, callback)
File "/home/linton/Apps/Garmin-Forerunner-610-Extractor/ant/fs/manager.py", line 241, in upload
upload_response._get_argument("response"))
AntFSUploadException: ('Upload request failed', 2)
Interrupted: ('Upload request failed', 2)

Not sure yet what the second file is.
Haven't been successful in the first upload.
Downloading from the watch works fine.
Log file at http://www.uschovna.cz/zasilka/L92D4ULHTXB6CP23-AN4 until 8 Jan 2013. can put it up again of course.
Best,
L.

I discovered this project few weeks ago. Really good job. By the way, I tried to upload a .tcx or a gpx file on my 310XT and got the error message as above. The soft tries to upload 45 files (probably fit files in ~/.config/garmin....)
If I can help you by any way, let me know.
Loic

Downloading 1 file(s) and uploading 45 file(s)
Downloading 2012-12-27_22-10-19_4_28.fit []
Uploading 2012-12-26_22-03-23-80-1060.fit [Traceback (most recent call last):
File "Garmin-Forerunner-610-Extractor/garmin.py", line 344, in main
g.start()
File "/home/ponger/CAP/Garmin-Forerunner-610-Extractor/ant/fs/manager.py", line 191, in start
self._main()
File "/home/ponger/CAP/Garmin-Forerunner-610-Extractor/ant/fs/manager.py", line 123, in _main
self.on_transport(beacon)
File "Garmin-Forerunner-610-Extractor/garmin.py", line 252, in on_transport
index = self.upload_file(typ, filename)
File "Garmin-Forerunner-610-Extractor/garmin.py", line 315, in upload_file
index = self.create(typ, data, self._get_progress_callback())
File "/home/ponger/CAP/Garmin-Forerunner-610-Extractor/ant/fs/manager.py", line 221, in create
self.upload(result.get_index(), data, callback)
File "/home/ponger/CAP/Garmin-Forerunner-610-Extractor/ant/fs/manager.py", line 241, in upload
upload_response._get_argument("response"))
AntFSUploadException: ('Upload request failed', 2)
Interrupted: ('Upload request failed', 2)

Owner

Tigge commented Jan 4, 2013

@lamenace91 Only FIT files are supported when uploading files. Which types are supported depends a little bit on the watch. @lcorbet, I'll try to analyze what happened with your log file.

I need navigation on my 310XT, so I put together https://github.com/SuperTaiyaki/fitconverter to convert courses. It hasn't been thoroughly tested yet, but it works for me.

Hello Jeremy,

Thanks a lot for your fit converter. It works fine to convert tracKs.

I'm wondering if you tried to transfer a workout to the gps under
Linux. Garmin training center (running under Windows) is able to save
workouts in TCX or GPX format. I would like to convert GPX/TCX
workouts in fit format before to transfer them on the GPS unit. Where
did you get the specifications about the fit format? Perhaps, it would
be possible to apply them to workout files, no?

Thanks for your help,
Loic

----- Message from notifications@github.com ---------
Date: Tue, 10 Sep 2013 22:51:43 -0700
From: Jeremy Chin notifications@github.com
Reply-To: Tigge/Garmin-Forerunner-610-Extractor
reply@reply.github.com
Subject: Re: [Garmin-Forerunner-610-Extractor] Send course to watch
functionality (#36)
To: Tigge/Garmin-Forerunner-610-Extractor
Garmin-Forerunner-610-Extractor@noreply.github.com
Cc: lamenace91 ponger@mnhn.fr

I need navigation on my 310XT, so I put together
https://github.com/SuperTaiyaki/fitconverter to convert courses. It
hasn't been thoroughly tested yet, but it works for me.


Reply to this email directly or view it on GitHub:
Tigge#36 (comment)

----- End message from notifications@github.com -----

I haven't looked into supporting workouts yet as I don't use them. The format is detailed in the FIT SDK (http://www.thisisant.com/resources/fit). Downloading it requires agreeing to terms that aren't open-source compatible.

Converting TCX workouts to FIT shouldn't be complicated, just time-consuming. Constantly having to look numbers up across several documents gets tiresome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment