#!/usr/bin/perl -w # This program downloads records from your Sleeptracker Pro # and displays them as text, xml, or csv # # Sleeptracker and Sleeptracker Pro are trademarks of # # Innovative Sleep Solutions # 2870 Peachtree Road #140 # Atlanta, GA 30305 # # This program is NOT developed or supported by Innovative Sleep Solutions # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # You can purchase your Sleeptracker or Sleeptracker Pro from: # # http://www.sleeptracker.com # http://www.sleeptracker.de # http://www.sleeptracker.fr # ... and some other stores # # Chagelog: # -------------- # 09.12.2007: fixed bug in xml output tag # 10.12.2007: fixed wrong cecksum calculation # 11.12.2007: added browser output # # # use Device::SerialPort; use Time::Local; use strict; my $browser="firefox"; # which browser to call my $uploadURL="http://www.sleeptracker.net/import.php"; # which upload URL to call my $numArgs = $#ARGV + 1; my $ttyPath=""; my $format="browser"; #set default if($numArgs > 1){ $format=$ARGV[0]; $ttyPath=$ARGV[1]; } elsif ($numArgs == 1){ $ttyPath=$ARGV[0]; } else { help(); exit 1; } if (not -w $ttyPath) { print STDERR "Can't access Sleeptracker at device '$ttyPath'\n"; exit 1; } print STDERR "Reading Sleeptracker data from $ttyPath\n\n"; my $serial = Device::SerialPort->new("$ttyPath"); $serial->baudrate(2400); $serial->databits(8); $serial->purge_all(); $serial->rts_active(0); $serial->dtr_active(1); # Send request $serial->write("V"); # Wait one second select(undef, undef, undef, 1); # Read response my($count, $data) = $serial->read(250); # goog for more than 70 awake moments if($count<15){ print STDERR "Error while reading from Sleeptracker!\nWatch showing DATA screen?\n"; exit 1; } my @stBytes=(); my $cnt=0; my $crc=0; foreach my $byu (split (//, $data)) { $cnt++; # for debug #printf "%03d: %02x = %d \n",$cnt,ord($byu),ord($byu); push @stBytes,ord($byu); if($cnt>1 && $cnt<$count-1){ $crc+=ord($byu); } } #printf "%x=%d\n\n",$crc,$crc; $crc=$crc%256; # compare checksum if($crc!=$stBytes[$count-2]){ print STDERR "Checksum Error while reading. $crc!=$stBytes[$count-2]"; exit 1; } # calculations and data formating my $pos=1; my (undef,undef,undef,$mday,$mon,$year,undef,undef,undef)=localtime(); my $jahr=$year+1900; my $monat=$mon+1; my $tag=$mday; my $stTag=$stBytes[$pos+1]; my $stMonat=$stBytes[$pos+0]; my $stJahr=$jahr; if($stMonat>$monat || ($stMonat==$monat && $stTag>$tag) ){ $stJahr=$jahr-1; } my $datum = sprintf "%02d.%02d.%4d",$stTag,$stMonat,$stJahr; $pos+=2; #$unknown=$stBytes[$pos]; $pos+=1; my $window = sprintf "%2d",$stBytes[$pos]; $pos+=1; my $toBed= sprintf "%02d:%02d",$stBytes[$pos+0],$stBytes[$pos+1]; my $toBedTS = timelocal(0,$stBytes[$pos+1],$stBytes[$pos],$tag,$monat-1,$jahr); $pos+=2; my $alarm =sprintf "%02d:%02d",$stBytes[$pos],$stBytes[$pos+1]; $pos+=2; my $cntData=$stBytes[$pos]; $pos+=1; my @almostAwake=(); my @almostAwakePst=(); my $lastAwake=$toBedTS; my $thisAwake=$lastAwake; my $alltimes=""; for(my $i=0;$i<$cntData;$i++){ my $aaw=sprintf "%02d:%02d:%02d", $stBytes[$pos+($i*3)+0],$stBytes[$pos+($i*3)+1],$stBytes[$pos+($i*3)+2]; my $aawShort=sprintf "%02d:%02d", $stBytes[$pos+($i*3)+0],$stBytes[$pos+($i*3)+1]; $alltimes.=$aawShort.","; push @almostAwake,$aaw; $thisAwake = timelocal($stBytes[$pos+($i*3)+2],$stBytes[$pos+($i*3)+1],$stBytes[$pos+($i*3)+0],$tag,$monat-1,$jahr); if($thisAwake<$lastAwake){ $thisAwake+=(24*60*60); # day has changed } my $slept=sprintf "%d",($thisAwake-$lastAwake)/60; $lastAwake=$thisAwake; push @almostAwakePst, $slept; #period sleeping time in sec } $pos+=($cntData*3); if($thisAwake<$toBedTS){ $thisAwake+=(24*60*60); # day has changed } my $dataAVal=($stBytes[$pos+1]*0xff)+$stBytes[$pos]; my $dataASec=$dataAVal%60; my $dataA=sprintf "%d:%2d",(($dataAVal-$dataASec)/60),$dataASec ; my $dataACalc=sprintf "%d:%2d",(($thisAwake-$toBedTS)/$cntData)/60,(($thisAwake-$toBedTS)/$cntData)%60; # output Browser if($format eq "browser"){ my $URLParam=sprintf "a=%s&w=%s&t=%s&dt=%s&da=%s",$alarm,$window,$toBed,$alltimes,$dataA; my $callFirefox=sprintf "%s \"%s?%s\" &",$browser,$uploadURL,$URLParam; print "\n"; print $callFirefox; print "\n"; my $ret=system($callFirefox); } # output Text if($format eq "text"){ print "Date: $datum\n"; print "To Bed: $toBed\n"; print "Alarm Time: $alarm\n"; printf "Effective Alarm Time: %s\n",$almostAwake[@almostAwake-1]; print "Window: $window min\n"; print "Data A (Clock): $dataA min\n"; print "Data A (Calculated): $dataACalc min\n\n"; print "Awake moments ($cntData): \n"; my $aawCnt=0; foreach my $awm (@almostAwake) { printf " Data %2d: %s (slept: %3d min)\n",$aawCnt+1,$awm,$almostAwakePst[$aawCnt]; $aawCnt++; } print "\n"; } # output CSV if($format eq "csv"){ printf "%s;%s;%s;%s;%s;%s;%s;%s",$datum,$toBed,$alarm,$almostAwake[@almostAwake-1],$window,$dataA,$dataACalc,$cntData; my $aawCnt=0; foreach my $awm (@almostAwake) { printf ";%s",$awm; $aawCnt++; } print ";\n"; } # output XML if($format eq "xml"){ print "\n"; print " $toBed\n"; print " $alarm\n"; printf " %s\n",$almostAwake[@almostAwake-1]; print " $window\n"; print " $dataA\n"; print " \n"; my $aawCnt=0; foreach my $awm (@almostAwake) { printf " %s\n",$aawCnt+1,$awm,$almostAwakePst[$aawCnt]; $aawCnt++; } print " \n"; print "\n"; } sub help { print STDERR "Usage: sleeptracker [format] device\n"; print STDERR "format: browser(default), text, csv, xml\n"; }