#! /usr/bin/perl



use Device::SerialPort;
use DBI;

#MYSQL-Datenbank Verbindung
$verbinden1="DBI:mysql:heizungssensorik"; 
$verbinden2="user";
$verbinden3="passwort";

use DBI;
my $dbh = DBI->connect( "$verbinden1","$verbinden2","$verbinden3") || die 
"Database connection not made: $DBI::errstr";



# Suche entsprechenden USB-Port
print("Search for USB-Port exists\n");
$i=0;
do{
	$portdev="/dev/ttyUSB".$i;
	print("Device:".$portdev."\n");
	if($i>10) {die"No Device found";}
	$i++;
} while(!(-e $portdev));
print("Found: ".$portdev."\n");

# Set up the serial port
# 19200, 81N on the USB ftdi driver
my $port = Device::SerialPort->new($portdev) || die "Can't open $portdev: $!\n";;
$port->databits(8);
$port->baudrate(9600);
$port->parity("none");
$port->stopbits(1);

#Einige Benutzer-Variablen
my $aa_flag=0;     #Start-Flag
my $finish_flag=0;   #End-Flag
my $hexchars="";
my @val_array;       #Eingangsdaten
my @sequence=(170, 16, 0, 17, 66); #Header
my @vbus_data;


sub init(){
  $aa_flag=0;
  $finish_flag=0;
  $hexchars="";
  @val_array=();
  @sequence=(170, 16, 0, 17, 66);
}

#Prüfe das Array auf den Header
sub check_array{
  my $i;
  for ($i=0;$i<@sequence;$i+=1){ 
    if(@val_array[$i]!=@sequence[$i]){
      #print "Wrong sequence at $i @val_array[$i]!=@sequence[$i], reinit\n"; 
      init(); 
      return 0;
    }
  }
  return 1;
}

#Wandelt in verwertbare Binaerdaten um
sub process_data{
  my @data=@_;
  my @t_values;
  my $sept=@data[4];
  my $crc=0x7F;
  #print "\nData: @data\n";
  for ($i=0;$i<4;$i+=1){
    $crc-=@data[$i];
    @data[$i]|= (($sept>>$i) & 0x01) << 7;
  }
  $crc-=@data[4];
  $crc&=0x7F;
  #check checksum
  #print "CRC:$crc\n";
  if ($crc!=@data[5]) {exit -1;}
  #print "\nData(sept): @data\n";
  @t_values[0] = @data[0] | (@data[1] <<8);
  @t_values[1] = @data[2] | (@data[3] <<8);

  return  @t_values;
}

#Ausgabe formatieren
sub format_string{
  return (
    sprintf(@_[0]*0.1."°C"),
    sprintf(@_[1]*0.1."°C"),
    sprintf(@_[2]*0.1."°C"),
    sprintf(@_[3]*0.1."°C"),
    sprintf("ToDo")
  );
}



sub temp_insert
{
	my $sql = qq{insert into  temperaturen (sensor,wert) values ($_[0],$_[1])};
	print $sql."\n";
	my $sth = $dbh->prepare( $sql );
	$sth->execute();
}




init();
do{
   # Poll to see if any data is coming in
  my $char = $port->lookfor();
  # If we get data, then check it
  if ($char) {
    @char_array=split(//,$char); 
    foreach my $c (@char_array) {
      #printf ("0x%2X,",ord($c));
      if (ord($c)==170 ){    #Suche nach Anfangs-Sequenz
        if (!$aa_flag) {$aa_flag = 1;}
        else {$finish_flag=1;}  # Nach Anfang folgt Ende
      }
      if ($aa_flag && !$finish_flag) { push(@val_array,ord($c));}		  #Solange wir nicht am Ende sind bauen wir uns ein Array
      if ($finish_flag){
        #Ausgabe
        #print "\n@val_array\n";
        if (check_array()) {   #Prüfe die empfangene Sequenz, sonst fange von vorn an
          last;   #Und Tschüß, Schleife! 
        }
      }
    }
   
    
  }
  
}while(!$finish_flag);
                                                
my $n_data=@val_array[8];
#Remove Header
for ($i=0;$i<10;$i+=1){ shift(@val_array);}

for ($j=0;$j<$n_data;$j+=1){
  #get frist data packet and remove data packet
  for ($i=0;$i<6;$i+=1){ @data[$i]=shift(@val_array);}
  @vbus_data=(@vbus_data,process_data(@data));
}

my @vbus_string=format_string(@vbus_data);
print   "@vbus_string\n";

#Trage Temp-Werte in Datenbank ein
temp_insert(0,@vbus_data[0]*.1);
temp_insert(1,@vbus_data[1]*.1);
temp_insert(2,@vbus_data[2]*.1);


$dbh->close();
