#!/usr/bin/perl

# Trida pro komunikaci s RadioReset jednotkou

package tradioreset;

use Device::SerialPort qw( :PARAM :STAT 0.07 );


# konstruktor
sub new {
  my ($type,$serialport)=@_;
  my ($self)={
    _message => "",
    _active => 0,
    _error => 0,
    _readtime => 200
  };
  bless($self,$type);
  $port=Device::SerialPort->new($serialport);
  $port->baudrate(9600);
  $port->parity("none");
  $port->databits(8);
  $port->stopbits(1);
  $port->handshake("none");
  $port->read_char_time(0);
  $port->read_const_time(1000);
  return($self);
}


# test pripojene jednotky
# vraci 1 pokud je jednotka pripojena, 0 pokud neodpovida
sub ping {
 my ($self)=@_;
 $port->write("P\n");
 if(!$self->readstring(3)) { return(0); }
 if($self->{_message} !~ /^OK/) { return(0); }
 return(1);
}


# provede reset vzdalene jednotky
sub remotereset {
 my ($self,$adresa,$output,$time)=@_;
 my ($stav);
 if(!$self->testot($output,$time)) {
   $self->{_message}='Spatne zadany vystup nebo cas';
   return(0);
 }    
 if($adresa !~ /^\d{3}$/) {
   $self->{_message}='Spatne zadany format adresy';
   return(0);
 }
 print "Remote reset executed\n";
 $port->write("C$adresa$output$time\n");
 $stav=1;
 while($stav) {
   $self->readstring(15);
   $self->{_message} =~ s/\n$//g;
   $self->{_message} =~ s/\n/\n |-> /g;
   print " |-> $self->{_message} \n";
   if($self->{_message} =~ /EM-\d{1,2}/) { return(0); }
   if($self->{_message} =~ /GM-\d{1,2}/) { return(1); }
  }
 return(0);
}


# provede reset vzdalene jednotky pres opakovac
sub rptrreset {
 my ($self,$adresa,$opakovac,$output,$time)=@_;
 my ($stav);
 if(!$self->testot($output,$time,$timeout)) {
   $self->{_message}='Spatne zadany vystup nebo cas';
   return(0);
 }    
 if($adresa !~ /^\d{3}$/) {
   $self->{_message}='Spatne zadany format cilove adresy';
   return(0);
 }
 if($opakovac !~ /^\d{3}$/) {
   $self->{_message}='Spatne zadany format adresy opakovace';
   return(0);
 }
 print "Repeater reset executed\n";
 $port->write("D$adresa$opakovac$output$time\n");
 $timeout=60;
 $stav=1;
 while($stav) {
   $stav=$self->readstring($timeout);
   $self->{_message} =~ s/\n$//g;
   $self->{_message} =~ s/\n/\n |-> /g;
   print " |-> $self->{_message} \n";
   if($self->{_message} =~ /EM-\d{1,2}/) { return(0); }
   if($self->{_message} =~ /GM-\d{1,2}/) { return(1); }
  }
 return(0);
}


# provede reset pomoci primo pripojene jednotky
sub dreset {
 my ($self,$output,$time)=@_;
 my ($stav);
 if(!$self->testot($output,$time)) {
   $self->{_message}='Spatne zadany vystup nebo cas';
   return(0);
 }    
 print "Direct reset executed\n";
 $port->write("X$output$time\n");
 if(!$self->readstring(3)) { return(0); }
 print " |->$self->{_message} ";
 if($self->{_message} !~ /Direct reset accepted/) { return(0); }
 return(1);
}



# otestuje output a time na spravny rozsah hodnot
sub testot {
 my ($self,$output,$time)=@_;
 if($output !~ /^[1-8]{1}$/) {return(0);}
 if($time !~ /^[0-9]{1}$/) {return(0);}
 return(1);
}



sub command {
 my ($self,$par)=@_;
 my ($msg);
 $self->{_readtime}=1000;
 $port->write("$par\n");
 if(!$self->readstring(1)) { return(0); }
 $self->{_readtime}=200;
 return(0);
}


# vrati posledni message co byla prijata ze seriaku
sub readmsg {
 my ($self)=@_;
 return($self->{_message});
}



# precte string ze serioveho portu, parametr je timeout v sec
sub readstring {
 my ($self, $timeout) = @_;
 my ($buffer,$saw,$count);
 $saw="";
 $buffer="";
 $timeout *= 5;
 while (($timeout>0)&&($saw !~ /[\n]/)) {
  ($count,$saw)=$port->read($self->{_readtime});
  $buffer.=$saw;
  $timeout--;
 }
 $buffer =~ s/\r//g;
 if($timeout == 0) { $buffer .= "<timeout>"; }
 $self->{_message}=$buffer;
 if($timeout == 0) { return(0); }
 return(1);
}


# destruktor, uvolni port
sub DESTROY {
 $port->close || warn "Port nejde zavrit";
 undef $port;
}


return(1);
