Skip to content

Instantly share code, notes, and snippets.

@dnas2
Last active March 5, 2017 12:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dnas2/36c882f45457d3d7e8568560adec421e to your computer and use it in GitHub Desktop.
Save dnas2/36c882f45457d3d7e8568560adec421e to your computer and use it in GitHub Desktop.
Fetch data from Delorme Inreach tracker
#!/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