#!/usr/bin/perl
#
# get_power_data_sail.pl - Steven Lerner 6/2005
#                          Woods Hole Oceanographic Institution
#
#       Description: Quick script that gets data via mars power
#                    controller via obc xbar7/sail/NPC serial port and logs
#                    raw and space-separated records to Data dir
#                    which can be plotted via gen_daily_plots.pl script.
#
#       Assumptions: Reguires that the serial connection to power ctrl
#                    is already logged-in (ie; open minicom session,
#                    log-in, and then quit w/o reset via ctl-a q)
#                    
#       Usage: get_power_data_sail.pl [-l]
#
#       Output: Generates timestamped power ctlr data for currents,
#               voltages, and temperatures.
#
# History:
#       Date       Who    Description
#       ----       ---    ---------------------------------------------------
#      06/05/2005  SL     Create
#      06/12/2005  SL     Added gettine switch states and set sleep_amt to 4sec
#      08/20/2005  SL     Ported for sail interface. Added -l, -d options
#      08/27/2005  SL     Updated for new sensor names and order
#################################################################################
require "getopts.pl";
require "flush.pl";
require "ctime.pl";
require "timelocal.pl";

$VERSION = "v1.0";

&Getopts('dl');
if (! defined ($opt_l)) {$loop_once = 0;}
                   else {$loop_once = 1;}
if (! defined ($opt_d)) {$DEBUG = 0;}
                   else {$DEBUG = 1;}

$sail = "/home/stevel/sail_driver/sail";
$ddir = "/home/stevel/power_obc/Data";

use FileHandle;
use IPC::Open3;

my $in  = new FileHandle;
my $out = new FileHandle;
my $err = new FileHandle;

open3 ($out,$in,$err,"$sail -s#S01A -x7") || die "Unable to open sail driver $!\n";

$sleep_amt = 4;
$prev_datafile = "";

# Loop-forever polling currents and voltages and temps (sensors)
while (1)
  {$tag = gmtimestamp_file();
   #$datafile = "Data/$tag";
   $datafile = "$ddir/$tag";
   if ($datafile ne "$prev_datafile")
     {#Open daily data files
      open(CURR_RAW,">>$datafile.cur.raw") || die "Unable to open data file: $datafile.cur.raw\n";
      open(CURR_DAT,">>$datafile.cur.dat") || die "Unable to open data file: $datafile.cur.dat\n";
      open(STATE_RAW,">>$datafile.state.raw") || die "Unable to open data file: $datafile.state.raw\n";
      open(STATE_DAT,">>$datafile.state.dat") || die "Unable to open data file: $datafile.state.dat\n";
      open(VOLT_RAW,">>$datafile.vlt.raw") || die "Unable to open data file: $datafile.vlt.raw\n";
      open(VOLT_DAT,">>$datafile.vlt.dat") || die "Unable to open data file: $datafile.vlt.dat\n";
      open(SEN_RAW,">>$datafile.sen.raw") || die "Unable to open data file: $datafile.sen.raw\n";
      open(SEN_DAT,">>$datafile.sen.dat") || die "Unable to open data file: $datafile.sen.dat\n";

      #write header record for dat file
      print CURR_DAT "#fields: date,time,load01,load02,load03,load04,load05,load06,load07,load08,";
      print CURR_DAT "load09,load10,load11,load12,load13,load14,load15,load16\n";
      flush(CURR_DAT);

      print STATE_DAT "#fields: date,time,load01,load02,load03,load04,load05,load06,load07,load08,";
      print STATE_DAT "load09,load10,load11,load12,load13,load14,load15,load16\n";
      flush(STATE_DAT);

      #write header record for dat file
      print VOLT_DAT "#fields: date,time,v12_mV,v48_mV,v-12_mV,v5_mV\n";
      flush(VOLT_DAT);

      #write header recorder for sensor file
      #print SEN_DAT "#fields: date,time,mv1,mv2,mv3,mv4,mv5,mv6,edfaE,mv8,xlca,edfaW,";
      #print SEN_DAT "bottom,top,ilc,pres_lv,laserE,bm,xlcb,pres_fluid,mv,humid,";
      #print SEN_DAT "laserW,tbd1,commsa,idc,pres_mv,comsb\n";
      #Sensor order updated 8/27/2005
      print SEN_DAT "#fields: date,time,humid,pres_fluid,pres_lv,pres_mv,bm,bottom,edfaE,edfaW,";
      print SEN_DAT "idc,ilc,mv1,mv2,mv3,mv4,mv5,mv6,mv7,mv8,neE75,neW75,oeE75,oeW75,";
      print SEN_DAT "tbd1,top,xlca,xlcb\n";
      }
   $prev_datafile = "$datafile";


   #Get Current values
   $cmd = "getc 0\n";
   print "Sending $cmd to $port\n" if $DEBUG;
   print $out "$cmd"; #flush(COM);
   $cnt = 0;
   while ($line = <$in>)
     {if ($DEBUG) {print "$line"; flush(STDOUT);}
      if ($cnt++ == 1) {$timestamp = gmtimestamp(1);
                        print "time=$timestamp\n" if ($DEBUG);
                        print CURR_RAW "time=$timestamp\n";
                        print CURR_DAT "$timestamp ";
                        flush(CURR_RAW); flush(CURR_DAT)
                        }
      if ($line =~ /load/) {$line =~ s/\> //;
                            print CURR_RAW "$line"; flush(CURR_RAW);
                            ($attr,$val) = split('=',$line,2);
                            chop($val); chop($val);
                            print CURR_DAT "$val "; flush(CURR_DAT);
                            }
      #last if ($line =~ /^>/);
      if ($line =~ /load16/) {print CURR_DAT "\n"; flush(CURR_DAT);
                              last;
                              }
      }



   #Get State values
   $cmd = "gets 0\n";
   print "Sending $cmd to $port\n" if $DEBUG;
   print $out "$cmd"; #flush(COM);
   $cnt = 0;
   while ($line = <$in>)
     {if ($DEBUG) {print "$line"; flush(STDOUT);}
      if ($cnt++ == 1) {$timestamp = gmtimestamp(1);
                        print "time=$timestamp\n" if ($DEBUG);
                        print STATE_RAW "time=$timestamp\n";
                        print STATE_DAT "$timestamp ";
                        flush(STATE_RAW); flush(STATE_DAT)
                        }
      if ($line =~ /load/) {$line =~ s/\> //;
                            print STATE_RAW "$line"; flush(STATE_RAW);
                            ($attr,$val) = split('=',$line,2);
                            chop($val); chop($val);
                            print STATE_DAT "$val "; flush(STATE_DAT);
                            }
      #last if ($line =~ /^>/);
      if ($line =~ /load16/) {print STATE_DAT "\n"; flush(STATE_DAT);
                              last;
                              }
      }



   #Get Voltage values
   $cmd = "getv\n";
   print "Sending $cmd to $port\n" if $DEBUG;
   print $out "$cmd"; #flush(COM);
   $cntv = 0;
   while ($line = <$in>)
     {if ($DEBUG) {print "$line"; flush(STDOUT);}
      if ($cntv++ == 1) {$timestamp = gmtimestamp(1);
                         print "time=$timestamp\n" if ($DEBUG);
                         print VOLT_RAW "time=$timestamp\n";
                         print VOLT_DAT "$timestamp ";
                         flush(VOLT_RAW); flush(VOLT_DAT)
                         }
      if ($line =~ /mV/) {$line =~ s/\> //;
                          print VOLT_RAW "$line"; flush(VOLT_RAW);
                          ($attr,$val_str) = split('=',$line,2);
                          chop($val_str); chop($val_str);
                          ($val,$units) = split(' ',$val_str);
                          print VOLT_DAT "$val "; flush(VOLT_DAT);
                          }
      #last if ($line =~ /^>/);
      if ($line =~ /v5/) {print VOLT_DAT "\n"; flush(VOLT_DAT);
                          last;
                          }
      }


   #Get sensors - temperature, pressure, humidity
   $cmd = "getsens\n";
   print "Sending $cmd to $port\n" if $DEBUG;
   print $out "$cmd"; #flush(COM);
   $cnt2 = 0;
   while ($line = <$in>)
     {if ($DEBUG) {print "$line"; flush(STDOUT);}
      if ($cnt2++ == 1) {$timestamp = gmtimestamp(1);
                         print "time=$timestamp\n" if ($DEBUG);
                         print SEN_RAW "time=$timestamp\n";
                         print SEN_DAT "$timestamp ";
                         flush(SEN_RAW); flush(SEN_DAT)
                         }
      if ($line =~ /temp|pressure|humidity/) 
                           {$line =~ s/\> //;
                            print SEN_RAW "$line"; flush(SEN_RAW);
                            ($attr,$val_str) = split('=',$line,2);
                            chop($val_str); chop($val_str);
                            ($val,$units) = split(' ',$val_str,2);
                            print SEN_DAT "$val "; flush(SEN_DAT);
                            }
      #last if ($line =~ /^>/);
      #if ($line =~ /temp\/comms\/b/) {print SEN_DAT "\n"; flush(SEN_DAT);
      #                                last;
      #                                 }
      if ($line =~ /temp\/xlc\/b/) {print SEN_DAT "\n"; flush(SEN_DAT);
                                    last;
                                    }
      }


   if ($loop_once) {exit;}
   
   print "Sleeping $sleep_amt...\n" if ($DEBUG);
   sleep $sleep_amt;
   }


exit;

#
#Subroutines Follow
#
sub gmtimestamp {local($no_gmtlabel) = $_[0];
        local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime;
        # zero fill hour,min,sec and month
        if ($sec < 10) {$sec = "0$sec";}
        if ($min < 10) {$min = "0$min";}
        if ($hour < 10) {$hour = "0$hour";}
        $mon += 1; #from gmtime defined 0-11, make it 1-12
        if ($mon < 10) {$mon = "0$mon";}
        if ($mday < 10) {$mday = "0$mday";}
        #make year 4-digits - Note: Year is years since 1900
        $year += 1900;
        if ($no_gmtlabel)
             {return "$year/$mon/$mday $hour:$min:$sec";}
        else {return "$year/$mon/$mday $hour:$min:$sec GMT";}
}




sub gmtimestamp_file {
        local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime;
        # zero fill hour,min,sec and month
        if ($sec < 10) {$sec = "0$sec";}
        if ($min < 10) {$min = "0$min";}
        if ($hour < 10) {$hour = "0$hour";}
        $mon += 1; #from gmtime defined 0-11, make it 1-12
        if ($mon < 10) {$mon = "0$mon";}
        if ($mday < 10) {$mday = "0$mday";}
        #make year 4-digits - Note: Year is years since 1900
        $year += 1900;
        return "$year$mon$mday";
}

####Sample output from Node power controller (8/27/2005)
#help
#The following commands are recognized:
#
#sets N 0|1   set switch for Load N (1-16) on (1) or off (0)
#gets N       get the state of Load N
#getc N       read current for Load N
#getv         read voltage on all internal buses
#getsens      read all engineering sensors
#quit         exit the program
#
#gets 0
#load01=1
#load-2=0
#...
#
#getc 0
#load01=-10
#load02=27
#...
#
#getv
#v12=61 mV
#v48=488 mV
#v-12=242 mV
#v5=41 mV
#
##Sample getsens response 8/27/2005
#getsens
#humidity=-25.205 %rh
#pressure/fluid=-15.419 psi
#pressure/lv=35.703 psi
#pressure/mv=-46.791 psi
#temp/bm=-13.641 degrees C
#temp/bottom=-182.72 degrees C
#temp/edfa/east=-186.78 degrees C
#temp/edfa/west=-185.23 degrees C
#temp/idc=-0.10681 degrees C
#temp/ilc=-21.835 degrees C
#temp/mv/1=-185.53 degrees C
#temp/mv/2=-185.55 degrees C
#temp/mv/3=-185.53 degrees C
#temp/mv/4=-185.47 degrees C
#temp/mv/5=-185.5 degrees C
#temp/mv/6=-185.59 degrees C
#temp/mv/7=-185.52 degrees C
#temp/mv/8=-185.47 degrees C
#temp/ne/switch/e75=-1.4038 degrees C
#temp/ne/switch/w75=-4.3945 degrees C
#temp/oe/e75=-1.2054 degrees C
#temp/oe/w75=-1.2207 degrees C
#temp/tbd1=-182.51 degrees C
#temp/top=-189.01 degrees C
#temp/xlc/a=0.83923 degrees C
#temp/xlc/b=-47.15 degrees C


