A set of command line tools written in Ruby to interact with Polar watches and decode raw data files.
polar_ftp
: access the Polar file system through USB- list content on the Polar watch
- download raw files
- backup complete content
polar_physdata2txt
: convert raw polar user physical data to TXT formatpolar_dailysummary2txt
: convert raw polar daily summary to TXT formatpolar_activitysamples2csv
: convert raw polar daily activity samples (activity, steps, metabolic equivalent, sport id and inactivity notifications) to CSV formatpolar_training2sml
: convert raw polar training sessions data files to the Suuntu SML file formatpolar_training2gpx
: convert raw polar training sessions data files to the Garmin GPX file formatpolar_training2tcx
: convert raw polar training sessions data files to the Garmin TCX file formatpolar_fitnesstest2txt
: displays content of fitness test result and exports to TXT filepolar_rrrecord2txt
: displays content of RR recording results and exports to TXT file (V800)polar_sleepanalysis2txt
: displays content of sleep analysis daily report and exports to TXT file (M430)
Tested with:
- Polar M200
- Polar M430
- Polar V800
- might also work on other models (A360, M400, Loop...), but this is untested
Tested on Linux (Ubuntu 16.10), macOS (Yosemite) and Windows (10).
Install the ruby language (>= 2.1) and dev tools (C compiler & co), if necessary.
To be able to connect to the watch from an unpriviledged user, you may want to add a udev rule to grant all users access to the USB device:
$ sudo cp pkg/99-polar.rules /etc/udev/rules.d
$ sudo udevadm control --reload-rules
Install the ruby language (>= 2.1) and dev tools, if necessary:
- install Xcode from the AppStore and Xcode Command Line Tools (
xcode-select --install
). - install Homebrew package manager
- run
brew install ruby
to get the latest version of ruby
To connect to the watch, macOS needs to be told not to attach it's default driver to the USB connection:
$ sudo gem install hidapi
$ pkg/macos_usb
$ sudo kextunload -b com.apple.driver.usb.IOUSBHostHIDDevice
Unplug the watch if already connected, and plug it again.
Install the ruby language (>= 2.1):
- RubyInstaller. Pick the 32 bits (not x64) version - Ruby 2.3 works fine.
To connect to the watch, you need the libusb-1.0.dll
DLL:
- copy the one provided in
pkg\libusb-1.0.dll
toC:\Windows\SYSTEM32
- or download it from libusb.info (extract the 7-Zip archive, and use the DLL found in MinGW32\dll)
NOTE: use the Windows command line (cmd
) to run the Ruby programs included in this project.
Example:
C:\Users\...> C:\Ruby23\bin\ruby.exe C:\path\to\this\project\directory\polar_ftp DIR /
C:\Users\...> C:\Ruby23\bin\ruby.exe C:\path\to\this\project\directory\polar_ftp DIR /U/0/
C:\Users\...> C:\Ruby23\bin\ruby.exe C:\path\to\this\project\directory\polar_ftp SYNC
C:\Users\...> C:\Ruby23\bin\ruby.exe C:\path\to\this\project\directory\polar_training2sml C:/Users/.../Polar/<device_id>/U/0/<YYYYMMDD>/E/<training_session_id>/ /temp/output.sml
C:\Users\...> C:\Ruby23\bin\ruby.exe C:\path\to\this\project\directory\polar_training2gpx C:/Users/.../Polar/<device_id>/U/0/<YYYYMMDD>/E/<training_session_id>/ /temp/output.gpx
Install the following Ruby gems:
$ gem install ruby-protocol-buffers
$ gem install varint # Optional (increases ruby-protocol-buffers performance)
$ gem install libusb # Required by polar_ftp
$ gem install nokogiri # Required by polar_training2sml, polar_training2gpx and polar_training2tcx
Download this repository and put it's content wherever you want (or use git clone https://github.com/cmaion/polar
to clone it locally).
List and download raw files from the Polar watch, connected through USB:
$ polar_ftp DIR </path/to/directory>
$ polar_ftp GET </path/to/file> [<output_file>]
$ polar_ftp SYNC [</path/to/local/archive>]
# Examples:
$ polar_ftp DIR /
Connected to Polar V800 serial XXXXXXXX
Listing content of '/'
JOURNAL.DAT 10240
PRODCONF.TXT 27
SYS/
U/
SYSLOG.BPB 18
MUSCF.BIN 12
PRODDATA.BIN 152
USAGECNT.BPB 110
DEVICE.BPB 120
SYNCINFO.BPB 79
$ polar_ftp DIR /U/
[...]
$ polar_ftp DIR /U/0/
[...]
$ polar_ftp DIR /U/0/<YYYYMMDD>/
[...]
$ polar_ftp DIR /U/0/<YYYYMMDD>/E/
[...]
$ polar_ftp DIR /U/0/<YYYYMMDD>/E/<training_session_id>/
[...]
$ polar_ftp DIR /U/0/<YYYYMMDD>/E/<training_session_id>/00/
[...]
$ polar_ftp GET /U/0/<YYYYMMDD>/E/<training_session_id>/00/SAMPLES.GZB
Connected to Polar V800 serial XXXXXXXX
Downloading '/U/0/<YYYYMMDD>/E/<training_session_id>/00/SAMPLES.GZB' as 'SAMPLES.GZB'
$ polar_ftp SYNC # Copy watch file system to ~/Polar/<device_id>
[...]
Convert user physical data to TXT file:
$ polar_physdata2txt <path/to/raw/polar/phys_data> [<output_txt_file>]
# Example:
$ polar_ftp SYNC # Copy watch file system to ~/Polar/<device_id>
$ polar_physdata2txt ~/Polar/<device_id>/U/0/S/ /tmp/physdata.txt
$ polar_physdata2txt ~/Polar/<device_id>/U/0/<YYYYMMDD>/PHYSDATA/<snapshot_id>/ /tmp/physdata.txt
$ polar_physdata2txt ~/Polar/<device_id>/U/0/<YYYYMMDD>/E/<training_session_id>/ /tmp/physdata.txt
$ cat /tmp/physdata.txt
Snapshot date : ...
Last modified : YYYY-MM-DD HH:MM:SS +TZ00
Gender : ...
Birthday : ...
Weight : ...
Height : ...
HR max : ...
HR resting : ...
Aerobic threshold : ...
Anaerobic threshold : ...
VO2max : ...
Training background : ...
Typical day : ...
Weekly recovery time sum : ...
Functional threshold power: ...
Convert daily summary to TXT file:
$ polar_dailysummary2txt <path/to/raw/polar/daily_summary> [<output_txt_file>]
# Example:
$ polar_ftp SYNC # Copy watch file system to ~/Polar/<device_id>
$ polar_dailysummary2txt ~/Polar/<device_id>/U/0/<YYYYMMDD>/DSUM/ /tmp/daily.txt
$ cat /tmp/daily.txt
Date : DD/MM/YYYY
Recorded activity : 24:00:00
Steps : 12000
Distance : 6841 m
BMR calories : 1755 kcal
Activity calories : 427 kcal
Training calories : 1118 kcal
TOTAL calories : 3300 kcal
Activity NON_WEAR : 01:27:00.000
Activity SLEEP : 08:41:30.000
Activity SEDENTARY : 08:43:00.000
Activity LIGHT : 03:27:00.000
Activity CONTINUOUS_MODERATE : 00:00:00.000
Activity INTERMITTENT_MODERATE : 00:03:30.000
Activity CONTINUOUS_VIGOROUS : 01:22:00.000
Activity INTERMITTENT_VIGOROUS : 00:16:00.000
TOTAL activity time : 05:08:30
Activity goal : 291% (926.8/318.0)
Activity goal (time to go, standing): 00:00:00.000
Activity goal (time to go, walking) : 00:00:00.000
Activity goal (time to go, running) : 00:00:00.000
Convert daily activity samples to CSV file:
$ polar_activitysamples2csv <path/to/raw/polar/daily_activity_samples> [<output_csv_file>]
# Example:
$ polar_ftp SYNC # Copy watch file system to ~/Polar/<device_id>
$ polar_activitysamples2csv ~/Polar/<device_id>/U/0/<YYYYMMDD>/ACT/ /tmp/daily.csv
$ cat /tmp/daily.csv
Time,Activity,Steps,Metabolic equivalent,Sport,Inactivity notification
[...]
YYYY-MM-DD 09:53:00 +0100,SEDENTARY,2,1.25,-1,
YYYY-MM-DD 09:53:30 +0100,SEDENTARY,,1.5,-1,
YYYY-MM-DD 09:54:00 +0100,LIGHT,20,1.75,-1,
YYYY-MM-DD 09:54:30 +0100,LIGHT,,2.0,-1,
YYYY-MM-DD 09:55:00 +0100,LIGHT,22,2.75,-1,
YYYY-MM-DD 09:55:30 +0100,LIGHT,,2.375,-1,
YYYY-MM-DD 09:56:00 +0100,LIGHT,20,2.625,-1,
YYYY-MM-DD 09:56:30 +0100,LIGHT,,2.375,-1,
YYYY-MM-DD 09:57:00 +0100,LIGHT,28,2.25,-1,
YYYY-MM-DD 09:57:30 +0100,LIGHT,,2.25,-1,
YYYY-MM-DD 09:58:00 +0100,INTERMITTENT_VIGOROUS,108,3.125,-1,
YYYY-MM-DD 09:58:30 +0100,INTERMITTENT_VIGOROUS,,10.25,1,
YYYY-MM-DD 09:59:00 +0100,INTERMITTENT_VIGOROUS,85,9.75,1,
YYYY-MM-DD 09:59:30 +0100,INTERMITTENT_VIGOROUS,,9.0,1,
YYYY-MM-DD 10:00:00 +0100,INTERMITTENT_VIGOROUS,100,9.75,1,
YYYY-MM-DD 10:00:30 +0100,INTERMITTENT_VIGOROUS,,10.375,1,
YYYY-MM-DD 10:01:00 +0100,INTERMITTENT_VIGOROUS,100,10.25,1,
YYYY-MM-DD 10:01:30 +0100,INTERMITTENT_VIGOROUS,,10.0,1,
YYYY-MM-DD 10:02:00 +0100,INTERMITTENT_VIGOROUS,89,9.75,1,
YYYY-MM-DD 10:02:30 +0100,INTERMITTENT_VIGOROUS,,10.5,1,
YYYY-MM-DD 10:03:00 +0100,CONTINUOUS_VIGOROUS,85,10.625,1,
YYYY-MM-DD 10:03:30 +0100,CONTINUOUS_VIGOROUS,,10.375,1,
YYYY-MM-DD 10:04:00 +0100,CONTINUOUS_VIGOROUS,87,10.25,1,
[...]
Convert a training session to Garmin GPX file:
$ polar_training2gpx <path/to/raw/polar/training_session_id> [<output_gpx_file>]
# Example:
$ polar_ftp SYNC # Copy watch file system to ~/Polar/<device_id>
$ polar_training2gpx ~/Polar/<device_id>/U/0/<YYYYMMDD>/E/<training_session_id>/ /tmp/output.gpx
Convert a training session to Garmin TCX file:
$ polar_training2tcx <path/to/raw/polar/training_session_id> [<output_rcx_file>]
# Example:
$ polar_ftp SYNC # Copy watch file system to ~/Polar/<device_id>
$ polar_training2tcx ~/Polar/<device_id>/U/0/<YYYYMMDD>/E/<training_session_id>/ /tmp/output.tcx
Convert a training session to Suunto SML file:
$ polar_training2sml <path/to/raw/polar/training_session_id> [<output_sml_file>]
# Example:
$ polar_ftp SYNC # Copy watch file system to ~/Polar/<device_id>
$ polar_training2sml ~/Polar/<device_id>/U/0/<YYYYMMDD>/E/<training_session_id>/ /tmp/output.sml
Read fitness test result and convert to TXT file:
$ polar_fitnesstest2txt <path/to/raw/polar/fitness_test_result> [<output_txt_file>]
# Example:
$ polar_ftp SYNC # Copy watch file system to ~/Polar/<device_id>
$ polar_fitnesstest2txt ~/Polar/<device_id>/U/0/<YYYYMMDD>/FT/<fitness_test_id>/ /tmp/output.txt
Read RR recording result and convert to TXT file:
$ polar_rrrecord2txt <path/to/raw/polar/rr_record_result> [<output_txt_file>]
# Example:
$ polar_ftp SYNC # Copy watch file system to ~/Polar/<device_id>
$ polar_rrrecord2txt ~/Polar/<device_id>/U/0/<YYYYMMDD>/RRREC/<rr_record_id>/ /tmp/output.txt
Read sleep analysis report and convert to TXT file:
$ polar_sleepanalysis2txt <path/to/raw/polar/sleep> [<output_txt_file>]
# Example:
$ polar_ftp SYNC # Copy watch file system to ~/Polar/<device_id>
$ polar_sleepanalysis2txt ~/Polar/<device_id>/U/0/<YYYYMMDD>/SLEEP /tmp/output.txt
For now, only the first activity of a multisport training session (eg, triathlon) is exported by the SML/GPX/TCX converters.
- bipolar for the initial inspiration
- v800 downloader for the initial USB protocol
- loophole for the .proto files
- Andrew Faraday for the sample Ruby USB code
GPL3