Last active
March 5, 2017 12:41
-
-
Save dnas2/36c882f45457d3d7e8568560adec421e to your computer and use it in GitHub Desktop.
Fetch data from Delorme Inreach tracker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# Run as an hourly cronjob. It auto-learns when spots are sent, so handles them as quickly as possible after they are available. | |
# use module | |
use XML::Simple; | |
use Data::Dumper; | |
use LWP::Simple; | |
use Time::Local; | |
$data = &loadData(***USERNAME***); | |
&doCheck($data); | |
sub loadData | |
{ | |
$username = $_[0]; | |
# create object | |
$xml = new XML::Simple (KeyAttr=>[]); | |
if ($type =~ /testing/) | |
{ | |
$data = $xml->XMLin("data.xml"); | |
} | |
else | |
{ | |
my $url = 'https://explore.delorme.com/Feed/Share/' + $username; | |
print "Fetching KML feed from " . $url . "\n"; | |
my $content = get $url or die "Unable to get $url\n"; | |
$data = $xml->XMLin($content); | |
} | |
$data; | |
} | |
# ======================== Main Method ============================== | |
sub doCheck | |
{ | |
$data = $_[0]; | |
our $lat; | |
our $lon; | |
our $spd; | |
our $dir; | |
our $utc; | |
for (@{ $data->{Document}{Folder}{Placemark} }) { | |
$pm = $_; | |
for (@{ $pm->{ExtendedData}{Data} }) { | |
$d = $_; | |
$field = $d->{name}; | |
if ($field =~ /Longitude/) {$lon = $d->{value};} | |
elsif ($field =~ /Latitude/) {$lat = $d->{value};} | |
elsif ($field =~ /Velocity/) {$spd = $d->{value}; $spd =~ s/ km\/h//; $spd = $spd * 0.539957; $spd=int($spd);} #Speed in knots | |
elsif ($field =~ /Course/) {$dir = $d->{value}; $dir =~ s/[^\d.]//g; $dir = int($dir);} | |
elsif ($field =~ /Time UTC/) {$utc = $d->{value};} | |
} | |
} | |
my ($mon,$mday,$year,$hour,$min,$sec) = split(/[\s:\/]+/, $utc); | |
if ($utc =~ /PM/) {$hour = $hour+12;} | |
if ($hour == 24) {$hour = 12;} #Handle 12PM which becomes 24PM in the line above, which throws an exception | |
my $time = timelocal($sec,$min,$hour,$mday,$mon-1,$year); | |
my $nextcheck=600; #Default refresh = 10 mins | |
my $timeSinceSpot = time - $time; | |
print "Spot is " . ($timeSinceSpot / 60 / 60) . " hours old\n"; | |
# If the spot was within the last 10 minutes, the next check should be 11 mins after the spot time | |
if ($timeSinceSpot < 600) { | |
$elevenMinsAfterSpot = $time+660; | |
$nextcheck = ($elevenMinsAfterSpot-time); | |
} | |
#If the spot is over 2 hours old, the next check will be next hour | |
elsif ($timeSinceSpot > 7200) { | |
$nextcheck = 3600; | |
} | |
print "Longitude:\t" . $lon . "\nLatitude:\t" . $lat . "\nSpeed:\t" . $spd . "\nDirection:\t" . $dir . "\n"; | |
print "Next check in " . $nextcheck . " seconds\n"; | |
if ($timeSinceSpot < 665) | |
{ | |
#The spot is less than 10 mins old. Do something with it | |
} | |
#Time at the top of the next hour | |
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(); | |
$toth = timelocal(0,0,$hour+1,$mday,$mon,$year); | |
$timeToTOTH = $toth-time; | |
if ($nextcheck < $timeToTOTH) { | |
# This ensures that refreshes stop before the top of the hour and the script ends, allowing the next hour's cron job to take over | |
print "...\n" | |
&refreshAfterSleep($nextcheck); | |
} | |
} | |
# ======================== Ends main doCheck Method ===================================== | |
sub refreshAfterSleep | |
{ | |
$nextcheck = $_[0]; | |
print "Sleeping for " . $nextcheck . " secs\n"; | |
sleep $nextcheck; | |
$data = &loadData(*** USERNAME ***); | |
&doCheck($data); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment