summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--lib/postrunner/EPO_Downloader.rb25
-rw-r--r--lib/postrunner/Main.rb8
3 files changed, 32 insertions, 4 deletions
diff --git a/README.md b/README.md
index 8d58728..c8c9e6f 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,8 @@
PostRunner is an application to manage FIT files such as those
produced by Garmin products like the Forerunner 620 (FR620). It allows you to
-import the files from the device and inspect them.
+import the files from the device and inspect them. It can also update
+satellite orbit prediction data on the device to speed-up fix times.
## Installation
diff --git a/lib/postrunner/EPO_Downloader.rb b/lib/postrunner/EPO_Downloader.rb
index 30ccd9f..0aa3fd9 100644
--- a/lib/postrunner/EPO_Downloader.rb
+++ b/lib/postrunner/EPO_Downloader.rb
@@ -79,6 +79,13 @@ module PostRunner
epo_fixed = ''
0.upto(27) do |i|
offset = i * 2307
+ # The fill bytes always seem to be 0. Let's issue a warning in case
+ # this ever changes.
+ unless epo[offset].to_i == 0 &&
+ epo[offset + 1].to_i == 0 &&
+ epo[offset + 2].to_i == 0
+ Log.warning "EPO fill bytes are not 0 bytes"
+ end
epo_fixed += epo[offset + 3, 2304]
end
@@ -92,6 +99,9 @@ module PostRunner
Log.error "EPO file has wrong length (#{epo.length})"
return false
end
+ date_1980_01_01 = Time.parse("1980-01-01T00:00:00+00:00")
+ now = Time.now
+ largest_date = nil
# Split the EPO data into Arrays of 32 * 72 bytes.
epo.each_slice(32 * 72).to_a.each do |epo_set|
# For each of the 32 satellites we have 72 bytes of data.
@@ -103,8 +113,23 @@ module PostRunner
Log.error "Checksum error in EPO file"
return false
end
+ # The first 3 bytes of every satellite record look like a timestamp.
+ # I assume they are hours after January 1st, 1980 UTC. They probably
+ # indicate the start of the 6 hour window that the data is for.
+ hours_after_1980_01_01 = sat[0] | (sat[1] << 8) | (sat[2] << 16)
+ date = date_1980_01_01 + hours_after_1980_01_01 * 60 * 60
+ # Either the start point (1980-01-01) is not correct or Garmin is
+ # publishing data that can be up to 5 days old. We check the date
+ # with some more relaxed ranges.
+ if date > now + 8 * 24 * 60 * 60
+ Log.warn "EPO timestamp (#{date}) is in the future"
+ elsif date < now - 8 * 24 * 60 * 60
+ Log.warn "EPO timestamp (#{date}) is too old"
+ end
+ largest_date = date if largest_date.nil? || date > largest_date
end
end
+ Log.info "EPO data is valid until #{largest_date + 6 * 60 * 60}."
true
end
diff --git a/lib/postrunner/Main.rb b/lib/postrunner/Main.rb
index ddec18e..1e75767 100644
--- a/lib/postrunner/Main.rb
+++ b/lib/postrunner/Main.rb
@@ -162,8 +162,8 @@ units <metric | statute>
htmldir <directory>
Change the output directory for the generated HTML files
-update-gps Download the current set of GPS ephemeris data and store them
- on the device.
+update-gps Download the current set of GPS Extended Prediction Orbit (EPO)
+ data and store them on the device.
<fit file> An absolute or relative name of a .FIT file.
@@ -364,7 +364,9 @@ EOT
epo_file = File.join(epo_dir, 'EPO.BIN')
if !File.exists?(epo_file) ||
- (File.mtime(epo_file) < Time.now - (24 * 60 * 60))
+ (File.mtime(epo_file) < Time.now - (6 * 60 * 60))
+ # The EPO file only changes every 6 hours. No need to download it more
+ # frequently if it already exists.
if EPO_Downloader.new.download(epo_file)
unless (remotesw_dir = @cfg[:import_dir])
Log.error "No device directory set. Please import an activity " +