mlt / schwinn810

Software for Schwinn 810 (and also some Mio, Cresta, and RedClover) GPS sport watch with heart rate monitor (Linux, Windows, and Mac OS)
https://github.com/mlt/schwinn810/wiki/Windows
14 stars 6 forks source link

Managed to make it work on Ubuntu 12.10, but there is a bug line 67 in reader_cresta.py #27

Open rickco opened 11 years ago

rickco commented 11 years ago

Hi, I have a watch sold by french supermarket Carrefour, that can use the Redclover software under windows, so I decided to have a look at your work on linux

I tried to install you driver on Ubuntu 12.10 but it is not working straightforward. First, there is no automatic recognition when plugin it in.

  1. I had to comment all lines related to "checkpoints" in device.py
  2. Modified line 67 of reader_cresta.py:
       return {'Track': track_name, 'Points': pts, 'Start': date(2000+yr1, mm1, dd1)}

by

        return {'Track': track_name, 'Points': pts, 'Start': datetime(2000+yr1, mm1, dd1, hr1, min1, 0)}

otherwise it returns an error in another script as the return 'Start' value was a date type instead of a datetime type who are 2 differents types.

as the driver is not working automaticly, I manually download the tracks from the watch and then create the tcx manually as follow :

sudo /usr/share/schwinn810/download.py --port /dev/ttyUSB0
/usr/share/schwinn810/csv2tcx.py 0609102.points > 0609102.tcx

For information, lsusb returns :

Bus 005 Device 003: ID 10c4:ea61 Cygnal Integrated Products, Inc. CP210x UART Bridge

thanks for the driver anyway, that is just my small contribution for some who may try to use their watch under linux and still get issues

mlt commented 11 years ago

Hey! Thanks for the feedback! It was quiet around this project for a while so I though that either everything was working or everybody gave up on it :-)

Could you send a link to an exact model of your watch? I failed to find anything similar at online.carrefour.fr. montre gps query results in Garmin & Nike products only.

It looks like you installed it from source and not from ppa. For port recognition to work, one has to copy corresponding udev rule to /etc/udev/rules.d/50-schwinn810.rules and restart udev with sudo service udev restart. Alternatively, add yourself to dialout (?) group so you don't have to sudo while extracting points. Also beware of modem manager if you don't use udev rules. Though this is crucial only if you use watch monitor for automatic extraction.

I'm a bit surprised that you refer to Cresta as RedClover software works fine with Schwinn watch. The change you suggest is in Schwinn version. Cresta lacks altitude data and transmits data in shorter blocks. There is a chance that my code incorrectly decided that your watch belongs to Cresta-alike platform and not Schwinn-alike. It might be the chance as for absent value there are better proper constructs in Python as zero might be a valid value in this particular case.

It would be nice if you could share (e.g. via a Dropbox) a binary dump with a short track.

P.S. Have you tried MapMyRun or Garmin uploader?

rickco commented 11 years ago

Hi thanks for your feedback.

I cant find the watch anywhere online, it is sold (and maybe it is not anymore) in a basic package only instore. It is provided with a small CD with GPS NE PRO software and the cable, that's it, like an OEM device. Not really more information on it. I discovered that RedClover could be used after reading this thread : http://www.courseapied.net/forum/msg/101124.htm The watch does not provide altitude information when tracking, but only in waypoints. Some pictures of the watch : http://stoc.free.fr/gps

I think I installed it from ppa, but it was 3 weeks ago (took me a while to make it work), so maybe i am wrong. Even if I installed with ppa, the scripts are installed in the /usr/share/schwinn810/ directoy, and as it was not working at all when pluging the cable, I tried to see if I could use manual commands.

I think you are right the watch is not recognized as a schwinn, especially because your script request a device code from the watch and I think it returns 0 in sign1 (i tried a lot of stuff while debugging my situation and this is what I remember, but I am neither an expert in Linux nor Python, so I am not efficient in that). However, are you sure your script is working with Cresta ? because when using the cresta_reader file functions, there is still a miscomptability with the types date and datetime if you do not do my correction ...

I think I already tried adding the udev rule and addind dialout group with no success ....

What do you mean by tried MapMyRun or Garmin uploader ? to download the track data from the watch to the computer? under linux or windows?

I will try tomorrow to get a bin dump, as I need to reboot under ubuntu and its time to sleep here. If you have any special try that you want me to do, let me know

rickco commented 11 years ago

and I forgot to say : I tried to force the use of reader_scwhim by forcing sign1, but then the watch did not reply to the 0x24 read command... so the watch understand a 0x20 read command, which shoes that it behaves more like a cresta ...

mlt commented 11 years ago

Thanks for the pics. It looks like it is a non-branded version. I recall seeing similar at some Chinese retailers.

The watch does not provide altitude information when tracking, but only in waypoints.

Schwinn does not show that on the screen either. However once extracted with regular windows software, it does show elevation.

When using ppa version, make sure you quit Schwinn Monitor that sits in a system tray before attempting manual commands as they might interfere.

However, are you sure your script is working with Cresta ? because when using the cresta_reader file functions, there is still a miscomptability with the types date and datetime if you do not do my correction ...

Perhaps we can ask @jomu if it still works for him.

I think I already tried adding the udev rule and addind dialout group with no success ....

You might want to relogin for group to take an effect. Though udev should work after restarting the daemon. You can play around with cable only (without watch attached) to see if /dev/schwinn810 appears and look at system log files for details.

What do you mean by tried MapMyRun or Garmin uploader ?

I meant automatic uploading of workouts to those services.

I will try tomorrow to get a bin dump

That would be great! Note that you can use this software under windows as well if that is your main platform.

I can't seem to find some more or less detailed instructions in other issue on how to play around with windows terminal emulator (hyperterm?) & log all data coming from device. But it might be non-trivial to send commands manually without some experience.

jomu commented 11 years ago

I don't work with the watch anymore. Wrong GPS Data im some areas (Netherlands for example)

mlt commented 11 years ago

@jomu It is sad to hear that. I'm just curious whether it was a hardware issue, e.g., you was getting the wrong data even with original software, or is it decoding issue with this software? I recall first time incorrectly decoding longitude and latitude as if those were given in degrees, minutes, and second. It resulted in some track jumps when compared to aerial image. However after I changed decoding routine to treat incoming data as fractional degrees everything worked well.

jomu commented 11 years ago

The  km and speed diplayed on the watch was wrong in the Netherlands. While inlineskating my average speed is

about 20-22 km/h and after 1 hour skating the watch measured more than 26 km.

The handling is bad, too. In the moment I am looking for an used garmin forerunner!

rickco commented 11 years ago
  1. the way I installed the software was
sudo add-apt-repository ppa:mtitov/schwinn810
sudo apt-get install schwinn810
sudo dpkg-reconfigure -plow schwinn810
  1. I just added myself to dialout and added the rule in /etc/udev/rules.d/50-schwinn810.rules I can now see the /dev/schinn810 on connection of the cable
  2. I had to create the ~/.schwinn810.conf file with DIR="~/temp/run" in it to not have this error message when lunching schwinn810 command :
IOError: [Errno 13] Permission denied: '/var/lib/schwinn810/2013/waypoints.csv'
  1. Nothing happen when I connect the watch. There is no Schwinn Monitor that sits in a system tray Is it because I am on Xubuntu 12.10 and not Ubuntu ?
  2. Now, the command "schwinn810" gives me the following output : I can see the pop up windows downloading the track, but I dont know where it download it ... and i have then the following error in the terminal :
WARNING:core.device:Sign1 = 0 and e1 = 0 (warning message added by myself in the script)
WARNING:core.device:cresta
WARNING:core.device:File a bug if you are not using Cresta or Mio watch!
/usr/bin/gpsbabel
Traceback (most recent call last):
  File "/usr/share/schwinn810/download.py", line 88, in <module>
    main()
  File "/usr/share/schwinn810/download.py", line 74, in main
    d.read_settings(w)
  File "/usr/share/schwinn810/core/device.py", line 158, in read_settings
    s = self.reader.read_settings()
AttributeError: 'CrestaReader' object has no attribute 'read_settings'
  1. Please find in http://stoc.free.fr/gps some files : 0609_red.tcx and gpx => extracted with redclover under windows. Note that there is an altitude (negative!) in the gpx but no heartrate whereas in the tcx there is heartrate but no altitude. I am still not sure you can extract altitude on tracks (on waypoints yes). If you can do that with your driver, it will be an improvement compare to redclover 0609102.laps .points and .track => extracted with your driver (with my modification in the reader script) under xubuntu with following command : /usr/share/schwinn810/download.py (no need to sudo neither put the port following action 2/) schwinn810.bin => extracted using /usr/share/schwinn810/download.py --debug command

thanks again for you work, please give me your feedback so we can go further : A. can we extract altitude from my watch B. is my script modification necessary for my watch ..? is their any need to add a third case where the watch is neither swchinn neither cresta but chinese C. How to make Schwinn Monitor working under Xubuntu ?

mlt commented 11 years ago

@rickco, thanks for raw binary.

2) It is probably a coincidence. Adding yourself to dialout would give you an access to /dev/ttyUSB0 as a regular user, whereas once udev rules are in effect you'd get /dev/schwinn810. If I recall correctly no membership in dialout is required.

3) Could you post results of

ls -ld /var/lib/schwinn810
ls -ld /var/lib/schwinn810/2013

Anyway your customization is correct. It is appropriate to have per-user settings. All that debian-alike per-package customization was meant for a single set-up. With D-Bus monitor launched upon user login, it is better to have per-user settings and not to use system folders. Similar device insertion monitoring is possible for Windows but it is not finished yet.

4,C) I had been running 11.10 for quite a while before upgrading. I do use XFCE (Xubuntu). There got to be a file /etc/xdg/autostart/schwinn810.desktop that should be handled upon logging in into X session.

5) Could you try an updated version?

A,B) It looks like your device is Cresta-alike thus no elevation data. You said you can record waypoints. Could you produce another raw dump containing waypoints? Or does this one have any?

rickco commented 11 years ago

3)

rickco@bogoss:~/temp/tmplun$ ls -ld /var/lib/schwinn810
drwxrwsr-x 4 root users 4096 Jun 28 19:53 /var/lib/schwinn810
rickco@bogoss:~/temp/tmplun$ ls -ld /var/lib/schwinn810/2013
drwxr-sr-x 2 root users 4096 Jun 28 19:53 /var/lib/schwinn810/2013

5) I just updated device.py and reader_cresta.py with your changes, and now it crashes quickly :

rickco@bogoss:~/temp/tmplun$ schwinn810 
schwinn810  Copyright (C) 2012 Mikhail Titov

This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under the terms of GPL-3 or later version.

WARNING:core.device:File a bug if you are not using Cresta or Mio watch!
Traceback (most recent call last):
  File "/usr/share/schwinn810/download.py", line 88, in <module>
    main()
  File "/usr/share/schwinn810/download.py", line 71, in main
    d.read(w, p)
  File "/usr/share/schwinn810/core/device.py", line 139, in read
    point = self.reader.read_point()
  File "/usr/share/schwinn810/core/reader_cresta.py", line 84, in read_point
    point['Latitude'] = pack_coord(b"\x00" + lat0, b'S')
  File "/usr/share/schwinn810/core/utils.py", line 18, in pack_coord
    c2=[unpack_bcd(x) for x in c1[0:3]]
  File "/usr/share/schwinn810/core/utils.py", line 10, in unpack_bcd
    raise Exception("Non-BCD argument {:X} in {:X}".format(digit, x00))
Exception: Non-BCD argument A in 1A

A,B) Yes there are 3 waypoints in my watch memory so they should be in the raw

mlt commented 11 years ago

3) That is odd why write permission for group users is missing. I just tried to create another folder in /var/lib/schwinn810 with umask 0002 using mkdir -p -m 2775 123 and permissions were correct. Anyway as I said earlier I also do have a dedicated folder in my ~/Documents folder. There will be no need in /var/lib/schwinn810 in the future.

5) Could you clone this repo anew into some folder? I feel like you might have a mixed set up. As I am able to completely reparse your data from the binary dump you gave me. Something along the following lines should work

cd somewhere
sudo apt-get install git
git clone https://github.com/mlt/schwinn810.git
cd schwinn810/src
./download.py --port /dev/schwinn810

Once again make sure you have no Schwinn810 Monitor in the tray if you managed to launch it. A,B) Waypoints are extracted with a separate command sent to the watch. If that command was not sent, there is no waypoints in binary dump. I added some preliminary implementation that needs to be tested. If it fails on waypoints, could you upload a newer binary dump?

rickco commented 11 years ago

5) same result :

WARNING:core.device:File a bug if you are not using Cresta or Mio watch!
Fetching track 0609102 [1/1] with 538 points
0%
Traceback (most recent call last):
  File "./download.py", line 88, in <module>
    main()
  File "./download.py", line 71, in main
    d.read(w, p)
  File "/home/rickco/temp/schwinn810/schwinn810/src/core/device.py", line 139, in read
    point = self.reader.read_point()
  File "/home/rickco/temp/schwinn810/schwinn810/src/core/reader_cresta.py", line 86, in read_point
    point['Latitude'] = pack_coord(b"\x00" + lat0, b'S')
  File "/home/rickco/temp/schwinn810/schwinn810/src/core/utils.py", line 18, in pack_coord
    c2=[unpack_bcd(x) for x in c1[0:3]]
  File "/home/rickco/temp/schwinn810/schwinn810/src/core/utils.py", line 10, in unpack_bcd
    raise Exception("Non-BCD argument {:X} in {:X}".format(digit, x00))
Exception: Non-BCD argument A in 1A
rickco commented 11 years ago

and for info, the following command output could explain why I do not see Schwinn810 Monitor in the tray :

/usr/share/schwinn810/schwinn810-tray.py
Traceback (most recent call last):
  File "/usr/share/schwinn810/schwinn810-tray.py", line 89, in <module>
    Schwinn810Tray()
  File "/usr/share/schwinn810/schwinn810-tray.py", line 77, in __init__
    DeviceAddedListener(self)
  File "/usr/share/schwinn810/schwinn810-tray.py", line 16, in __init__
    "/org/freedesktop/Hal/Manager")
  File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 241, in get_object
    follow_name_owner_changes=follow_name_owner_changes)
  File "/usr/lib/python2.7/dist-packages/dbus/proxies.py", line 248, in __init__
    self._named_service = conn.activate_name_owner(bus_name)
  File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 180, in activate_name_owner
    self.start_service_by_name(bus_name)
  File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 278, in start_service_by_name
    'su', (bus_name, flags)))
  File "/usr/lib/python2.7/dist-packages/dbus/connection.py", line 651, in call_blocking
    message, timeout)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.Hal was not provided by any .service files
mlt commented 11 years ago

5) same result

That is odd. Can you reparse your own existing dump with ./download.py --port /tmp/or/wherever/schwinn810.bin. Could you produce yet another dump in /tmp/schwinn810.bin with --debug ? Just rename it to distinguish from the former one.

dbus.exceptions.DBusException: org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.Hal was not provided by any .service files

Try sudo apt-get install hal

rickco commented 11 years ago

./download.py --port /tmp/or/wherever/schwinn810.bin :

WARNING:core.device:Parsing existing dump in /home/rickco/temp/schwinn810.bin
WARNING:core.device:File a bug if you are not using Cresta or Mio watch!
Fetching track 0609102 [1/1] with 538 points
0%
19%
37%
56%
74%
93%
Traceback (most recent call last):
  File "./download.py", line 88, in <module>
    main()
  File "./download.py", line 71, in main
    d.read(w, p)
  File "/home/rickco/temp/schwinn810/schwinn810/src/core/device.py", line 150, in read
    wpt = self.reader.read_waypoint()
  File "/home/rickco/temp/schwinn810/schwinn810/src/core/reader_cresta.py", line 97, in read_waypoint
    struct.unpack("=6B  6s 3x 5s 6s  2B HxB", raw)
struct.error: unpack requires a string argument of length 32

I can't produce another schwinn810.bin, I get the same error Exception: Non-BCD argument A in 1A when I use --debug or not I installed hal, it doesnt change anything

mlt commented 11 years ago

Huh... so it parses existing dump okay. The unpacking error is caused by missing waypoints in the dump. Is it the only track in the watch?

I'm confused as I don't see 0x1A byte at coordinate fields for a point but at what would be a coordinate field position in track summary which has different signature that should cause BadSignature exception if it was attempted to be parsed. http://i.troll.ws/d7301d85.png

I can't produce another schwinn810.bin, I get the same error

It still should produce a truncated dump which would be good enough.

I installed hal, it doesnt change anything

Hm.. that was what popped up from google. Though it should have restarted udev or something, have you tried to manually restart it or just reboot before starting schwinn810-tray.py ?

I'll set up later a separate branch with extensive debug output not to mess with the main tree much.

rickco commented 11 years ago

Hi, sorry for the delay, here are some news : first, I now have the schwinn monitor in tray when connecting the watch, probably since I reboot (just launching /usr/share/schwinn810/schwinn810-tray.py was not enough). However nothing happens when I connect the watch.

Then, now I just did a git clone https://github.com/mlt/schwinn810.git to get your last changes. And when I do ./download.py --debug, the result is better :

WARNING:core.device:File a bug if you are not using Cresta or Mio watch!
Fetching track 0609102 [1/1] with 538 points
0%
19%
37%
56%
74%
93%
Traceback (most recent call last):
  File "./download.py", line 88, in <module>
    main()
  File "./download.py", line 71, in main
    d.read(w, p)
  File "/home/rickco/temp/schwinn810_2/schwinn810/src/core/device.py", line 151, in read
    wpt = self.reader.read_waypoint()
  File "/home/rickco/temp/schwinn810_2/schwinn810/src/core/reader_cresta.py", line 100, in read_waypoint
    wpt['Time'] = datetime(2000+yy, mm, dd, hh, mn, ss)
ValueError: month must be in 1..12

For info, I have 3 waypoints in the watch, but I never managed to read them with this scwhinn driver as I commented the lines related to it as stated in my first post. I uploaded the new debug binary file here http://stoc.free.fr/gps/schwinn810_110713.bin

mlt commented 11 years ago

Huh... now it looks like your watch does expect points summary as it was attempting to read waypoint a bit too early when there was a last track point. Somehow previously I thought it was a difference from Cresta watch.

Just a reminder to quit Schwinn Monitor that sits in tray before using ./download.py manually. Also you should be able to run it from console like /usr/share/schwinn810/schwinn810-tray.py. In the upcoming version it will be necessary to start Monitor for the first time manually and explicitly mark it as auto start on login in its GUI. So there will be no unconditional Monitor launch for all users but per user with their consent.

If you have a clean cloned copy of this repo without your modifications, you can get updates by changing directory into that cloned copy and doing git pull. If you have your own changes, things may be more involving :-)

Could you try it again and make another binary dump? You can just post a link to binary no need for a screen output.

P.S. There is a nice markup in here

rickco commented 11 years ago

well done, it looks better : new debug bin file no error messages now :

....
93%
Done

waypoints.csv looks good except for altitudes :

Time            Name    Latitude        Longitude   x1  x2  Elevation   No
2013-04-01 13:25:55 1YWZZ0  -33.948166666666665 151.140005          2.55
2013-04-01 13:28:47 Z-----  -33.94408833333333  151.14079           2.55
2013-04-14 11:53:05 041401  28.33207        120.670115          2.55    

Altitudes should be respectively (according to the watch) 29m, 29m and 752m For info, Redclover allows me to download waypoints but not altitudes of theses points whereas I can read their altitudes in the waypoints menu of the watch.

rickco commented 11 years ago

maybe I should open a new thread for that, but csv2tcx.py changes the time according to the timezone we specify in the command line (or using America/Chicago as default), considering download.py would put GMT times in the .points files, which is not the case as the time saved in the .points file is the local time of the watch. So to keep the time consistent, when launching csv2tcx.py we have to manually specify that our local zone is GMT+0 (which is not the case). We should either :

second point : babelize.cmd refers to /etc/schwinn810/schwinn810.conf whereas this file path is /etc/schwinn810.conf edit : speaking about the src/babelize.cmd (unused?) file not the linux/babelize.sh one ...

rickco commented 11 years ago

just tested your last fix, look fixed regarding waypoints elevation.

So do you confirm there is no way to get elevations from points of tracks with this watch ? (redclover does not do it and we cant see them in the watch menu anyway)

mlt commented 11 years ago

Indeed it is quite odd that watch reports local time. Also It would not hurt to guess GMT offset & DST from GPS signal instead of asking user to set those up.

Anyway, many web services expect TCX to have timestamps in GMT in spite of TCX specification and ISO standard. IIRC it drives MapMyRun nuts when TCX has +0500 instead of Z. Perhaps you can call it like csv2tcx.py --tz Australia/Sydney 0609102.points > 0609102.tcx. Apparently zone setting (and DST ?) can be read from watch but it requires further investigation. Most software should handle correctly GMT time in TCX.

just tested your last fix, look fixed regarding waypoints elevation.

Nice!

I'll see what can be done for track points. There is no elevation stored. But that is not a big deal. First of all GPS-based elevation is not quite reliable unless combined with barometric altimeter like in higher Garmin models. For example, Garmin Connect by default uses its own DEM to fetch track profile for non-high-end devices. Schwinn does not report those on watch either. I was surprised to see that Cresta saves elevation in meters while Schwinn in cm.

second point : babelize.cmd refers to /etc/schwinn810/schwinn810.conf whereas this file path is /etc/schwinn810.conf

Thanks! While easy fix, I'll postpone it till next version with per-user GUI-based configuration saved in JSON format in standard locations on both Linux & Windows.

P.S. Does the watch return to charge only mode after extraction, i.e. says charging on its screen?

rickco commented 11 years ago

Perhaps you can call it like csv2tcx.py --tz Australia/Sydney 0609102.points > 0609102.tcx

ok you're right, it is the correct way to do it as the output would be the good one. Better way would be that csv2tcx.py change the Z of the time by +10:00 or whatever than changing the local time to the UTC one by removing 10 hours (in case of Sydney) and keeping the Z, but as you said maybe some services are not able to understand that format. Redclover keeps the local time with a Z, it means Redclover is wrong, but finally it maybe does it the best way regarding the way services behave.

Exemple : The watch saves a point with a local time of 14:24 download.py outputs 14:24 csv2tcx.py --tz Australia/Sydney outputs 04:24Z I would prefer csv2tcx.py --tz Australia/Sydney to output 14:24+10:00 but as you said not compatible with all online services Redclover outputs 14:24Z which is not the same time ...

However, we could still change the default time zone of csv2tcx.py line 12 from America/Chicago to nothing or UTC or its correct syntax because for those who do not worry about timezones, it would reacts by default as Redclover and would keep the local time by default, with a wrong Z behind, which is an invisible mistake for most of online services that would interpret the time as local one anyway ...

P.S. Does the watch return to charge only mode after extraction, i.e. says charging on its screen?

YES, and I can then restart a new download as many times as I want. good work !