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
- delete files and directories
- create directories
- upload files
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_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)
Tested with:
- Polar A370
- Polar M200
- Polar M400
- Polar M430
- Polar M450
- Polar V800
- might also work on other models (A360, 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-rulesInstall 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 rubyto 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_usbUnplug 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.dlltoC:\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 and polar_training2gpxDownload 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 MKDIR <directory>
$ polar_ftp PUT <source_file> <remote_path>
$ polar_ftp DEL <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.000Convert 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.gpxConvert 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.smlRead 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.txtRead 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- 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