#!/usr/bin/perl -T
#$Id: PID_fast_control.pl,v 1.16 2021/09/15 14:54:43 sqko Exp $
use strict;
use warnings;
use RFC::Rig;
use RFC::Visitor;
my $v = RFC::DisableProglogVisitor->new();
use Fcntl qw(:DEFAULT :flock);
die "No rig specified!\n" unless (@ARGV);
my $r = shift;
if ($r && $r =~ /(\d+)/)
{
    $r = $1;
}
else
{
    die "'$r' is not a valid rig name!\n";
    exit;
}
my $lock = '/home/rig'.$r.'/PID_fast_control.lock';
sysopen(MFH, $lock, O_WRONLY | O_CREAT) or CORE::die "Error: Could not open $lock $!";
sleep(20) unless (@ARGV);
&main();
sleep(1);
exit;

sub main
{
    my $res = flock(MFH,LOCK_EX | LOCK_NB);
    return unless ($res);
    my $rig = RFC::Rig->new($r);
    $rig->check_run;
    $rig->Accept($v);
    my $modtime = time + 600;
    my @devices = $rig->list_devices('PID');
    while (1)
    {	
	last unless (@devices);
	if (time > $modtime)
	{
	    $rig = undef;
	    select(undef,undef,undef,0.5);
	    $rig = RFC::Rig->new($r);
	    $rig->Accept($v);
	    $modtime = time + 600;
	    @devices = $rig->list_devices('PID');
	}
	foreach my $name (@devices)
	{
	    my $d = $rig->get_device('PID',$name);
	    next unless ($d);
	    unless ($d->fast)
	    {
		$d->remove();
		$name = '';
		next;
	    }
	    $d->init(); ## load any changes in configuration ###
	    my $out = $d->control(); ## Do calculation and control ##
	    next unless(defined($out)); ## do nothing if in deadband or outside range            
	    my $res = $d->store(); ## Save state for future calls ##
	    next if ($res);
	    $rig->errorlog("Could not store PID settings, reloading.");
	    $modtime = 0; ## Force reload of rig if PID has errors ###
	    last;
	}
	sleep(1);
    }
    $rig->DESTROY();
    return;
}

