#!/usr/bin/perl
#$Id: change_config.cgi,v 1.88 2023/12/19 09:02:00 sqko Exp $
use strict;
use warnings;
use RFC::Rig;
use RFC::Main;
use RFC::RFCCGI qw(:cgi :html);
use CGI qw(:standard :netscape);
my $ref = &RFC::RFCCGI::get_user_data_ref();
my $r = param('rig');

unless ($r)
{
    print header(-charset=>'utf-8');
    print "No rig specified!\n";
    exit;
}

my $rig = RFC::Rig->new($r);
my $acmode = get_cv('global','access_mode');
$acmode = 'celltest' unless ($acmode);
print header(-charset=>'utf-8');
my $usermode = user_auth($acmode,'m');
if (RFC::RFCCGI::rig_mode())
{
    ####  Read and use mode deprecated after initialisation of rig authentification ####
    $usermode = 1;
}
unless (RFC::RFCCGI::rig_auth())
{
    $usermode = 0;
}

unless (login_ok() && $usermode)
{
    print "Warning: You are not authorised to change parameters on $rig, changes aborted! (Session timeout?)";
    exit;
}

my $ac = param('action');
unless ($ac)
{
    print "";
    exit;
}

### Ok, if we got here, the user is authenticated and a action parameter is specified

if ($ac eq 'list_devices')
{
    my $type = param('type');
    unless ($type)
    {
	print "Warning: No device type was specified!";
    }
    my @list = $rig->list_devices($type);
    print "OK\n";
    print join("\n",sort {$< cmp $b} @list);
    exit;
}


if ($ac eq 'help_func')
{
    my $type = param('type');
    my $device = param('device');
    my $dev = $rig->init_device($type,$device);
    unless ($dev)
    {
        print "Warning: Device $device of type $type was not found!";
	exit;
    }
    my $str = $dev->ui_fn_description(param('func_name'));
    print $str;
    exit;
}


if ($ac eq 'help_tag')
{
    my $type = param('type');
    my $device = param('device');
    my $dev = $rig->init_device($type,$device);
    unless ($dev)
    {
        print "Warning: Device $device of type $type was not found!";
	exit;
    }
    my $str = $dev->tag_description(param('key'));
    $str = "Device type" if (!$str && param('key') && param('key') eq 'type');
    print $str;
    exit;
}

if ($ac eq 'test_device')
{
    my $type = param('type');
    my $device = param('device');
    my $dev = $rig->init_device($type,$device);
    unless ($dev)
    {
        print "Warning: Device $device of type $type was not found!";
    }
    eval {
	my $data = RFC::Cache->new();
        print $dev->test_string($data);
    };
    if ($@ && $dev)
    {
	print "Error: Could not initilaise $type device '$device': $@";
        exit;
    }
    exit;
}


if ($ac eq 'read_device')
{
    my $type = param('type');
    my $device = param('device');
    my $dev = $rig->init_device($type,$device);
    unless ($dev)
    {
        print "Warning: Device $device of type $type was not found!";
    }
    eval {
	my @l = localtime();
	my $val = $dev->monitor();
	if ($val =~ /^[\d\.\-\+eE]$/)
	{
	    printf("%02i:%02i:%02i   %.6f",$l[2],$l[1],$l[0],$val);
	}
	else
	{
	    printf("%02i:%02i:%02i   %s",$l[2],$l[1],$l[0],$val);
	}
    };
    if ($@ && $dev)
    {
	print "Error: Could not initilaise $type device '$device': $@";
        exit;
    }
    exit;
}

if ($ac eq 'read_multi')
{
    ### Format for devlist:  class1-name1,class2-name2,... ###
    my $devices = param('devlist');
    unless ($devices)
    {
	print "Warning: No devices was specified!";
	exit;
    }
    my @list = split(/\s*\,\s*/,$devices);
    my $data = RFC::Cache->new();
    my @l = localtime();
    printf("%02i:%02i:%02i",$l[2],$l[1],$l[0]);
    eval {
	foreach my $item (@list)
	{
	    my ($class,$name) = split(/\-/,$item);
	    next unless ($class && $name);
	    my $dev = $rig->init_device($class,$name);
	    next unless ($dev);
	    my $val = -32768;
	    eval {
		$val = $dev->read($data);
	    };
	    printf("   %.6f",$val);
	}
    };
    if ($@)
    {
	print "Error: $@";
        exit;
    }
    exit;
}

if ($ac eq 'include_device')
{
    unless ($$ref{'cert'})
    {
	print "Warning: You are not authorised to change configuration for rig $rig, only certified users may do so";
	exit;	
    }
    my $fn = $rig->config->filename();
    chomp $fn;
    unless (-w $fn)
    {
	print "Warning: Configuration file is readonly, changes aborted!\n";
	exit;
    }
    my $type = param('type');
    my $device = param('device');
    my $key = param('key');
    my $value = param('value');
    unless ($type && $device && $key && defined($value))
    {
	print "Warning: Type, device, key or value not specified for changing configuration value for $rig";
	exit;
    }
    my $i = 0;
    my @list = $rig->list_names($type);
    my $found = 0;
    foreach my $d (@list)
    {
	next unless ($d eq $device);
	$found = 1;
	last;
    }
    if ($value)
    {
	push @list,$device unless ($found);
    }
    else
    {
	if ($found)
	{
	    my @l = ();
	    foreach (@list)
	    {
		push @l,$_ unless ($_ eq $device);
	    }
	    @list = @l;
	}
    }
    @list = sort {$a cmp $b} @list;
    eval {
	### Check for valid data ###
	$rig->begin;
	my $oldval = $rig->get_cv('main',$rig->list_names_tag($type));
	$oldval = '' unless defined($oldval);
	my $res = $rig->change_config_value('main',$rig->list_names_tag($type),@list);
	$rig->init();
	$rig->commit;
	my $dstr = join(',',@list);
	$dstr = '' unless defined($dstr);
	my $section = $rig->list_names_tag($type);
	my $string = "Key '$section' in section 'main' was changed from '$oldval' to '$dstr'";
	$rig->proglog($string,&get_user());
    };
    if ($@)
    {
	$rig->rollback;
	print "Error: change resulted in an invalid configuration, issuing rollback; error: $@";
	print "$key\n";
	print "$value\n";
	exit;
    }
    print "OK\n";
    print "$key\n";
    print "$value\n";
    print "\n";
    exit;    
}


if ($ac eq 'change_config_value')
{
    my %allowed_keys = (
	'main' => ['warning_mails'],
	'IV_control' => ['temp_label','current_label','voltage_label','pressure_label','voltagelimit_iv','ivpause','currentstep1','currentstep2','currentstep3','epsilon','currentlimit','diff_current_limit','OCV_measure_number','electrolysis_limit_voltage','voltage_limit_vogt','voltage_limit_iv','electrolysis_lmit_voltage','iv_control_names','allow_caching','OCV_measure_number'],
	);
    my $cert = $$ref{'cert'};
    my $auth = $$ref{'auth'};
    my $section = param('section');
    my $key = param('key');
    my $value = param('value');
    unless ($section && $key)
    {
	print "Warning: Section or key not specified for changing configuration value for $rig";
	exit;
    }
    unless ($cert)
    {
	my $cv = $allowed_keys{$section};
	my @l = ();
	@l = @{$cv} if ($cv);
	my $found = 0;
	foreach (@l)
	{
	    next unless $_ eq $key;
	    $found = 1;
	    last;
	}
	unless ($found && $auth)
	{
	    print "Warning: You are not allowed to change configuration $key for rig $rig, only the certified users may do so";
	    exit;	    
	}
    }
    my $fn = $rig->config->filename();
    chomp $fn;
    unless (-w $fn)
    {
	my $oldval = $rig->get_cv($section,$key);
	print "Warning: Configuration file is readonly, changes aborted!\n";
	exit;
    }
    my $warn = '';
    my $res;
    my $val = $rig->get_cv($section,$key);
    $rig->begin;
    my $mincurrent = get_cv('iVcurves','minimum_current_step');
    $mincurrent = 0.05 unless ($mincurrent);
    if ($section eq 'IV_control')
    {
	### Business rules for iV control ###
	$value = 0 unless (defined($value));
	if (($key eq 'currentstep1') && $value > 1) 
	{
	    $warn = "Warning: Current step 1 must be between $mincurrent and 1 A";
	    $value = 1;
	}
	if (($key eq 'currentstep1') && $value < $mincurrent) 
	{
	    $warn = "Warning: Current step 1 must be between $mincurrent and 1 A";
	    $value = $mincurrent;
	}
	if (($key eq 'currentstep2') && $value > 3) 
	{
	    $warn  = "Warning: Current step 2 must be between $mincurrent and 3 A";
	    $value = 3;
	}
	if (($key eq 'currentstep2') && $value < $mincurrent) 
	{
	    $warn = "Warning: Current step 2 must be between $mincurrent and 3 A";
	    $value = $mincurrent;
	}
	if (($key eq 'currentstep3') && $value > 0.5) 
	{
	    $warn = "Warning: Current step 3 must be between $mincurrent and 0.5 A";
	    $value = 0.5;
	}
	if (($key eq 'currentstep3') && $value < $mincurrent) 
	{
	    $warn = "Warning: Current step 3 must be between $mincurrent and 0.5 A";
	    $value = $mincurrent;
	}
	my $miniv = get_cv('iVcurves','minimum_cell_voltage_for_iv');
	my $maxiv = get_cv('iVcurves','maximum_cell_voltage_for_iv');
	$maxiv = 2000 unless (defined($maxiv));
	$miniv = 0 unless (defined($miniv));
	$maxiv -= 25;
	$miniv += 25;
	my $maxi = get_cv('iVcurves','current_limit');
	$maxi = 40 unless (defined($maxi));
	$maxi = 0.05 unless ($maxi > 0.05);
	my $mini = 0.05;
	my @list = $rig->list_devices('PSU');
	foreach (@list)
	{
	    my $d = $rig->get_device('PSU',$_);
	    $maxi = $d->maxcurrent() if ($d->maxcurrent < $maxi);
	    $miniv = $d->minvoltage()*1000 if ($d->minvoltage() * 1000 > $miniv);
	    $maxiv = $d->maxvoltage()*1000 if ($d->maxvoltage() * 1000 < $maxiv);
	}
	if (($key eq 'currentlimit') && $value > $maxi) 
	{
	    $warn = "Warning: current limit for iV curves must bebetween 0.05 and  $maxi A";
	    $value = $maxi;
	}
	if (($key eq 'currentlimit') && $value < 0.05) 
	{
	    $warn = "Warning: current limit for iV curves must bebetween 0.05 and  $maxi A";
	    $value = 0.05;
	}

	if (($key eq 'voltagelimit_iv') && $value > $maxiv) 
	{
	    $warn = "Warning: voltage limit for iV curves must be between $miniv and $maxiv mV in fuel cell mode";
	    $value = $maxiv;
	}
	if (($key eq 'voltagelimit_iv') && $value < $miniv) 
	{
	    $warn = "Warning: voltage limit for iV curves must be between $miniv and $maxiv mV in fuel cell mode";
	    $value = $miniv;
	}
	if (($key eq 'electrolysis_limit_voltage') && $value < $miniv) 
	{
	    $warn = "Warning: voltage limit for iV curves must be between $miniv mV and $maxiv mV in electrolysis mode";
	    $value = $miniv;
	}
	if (($key eq 'electrolysis_limit_voltage') && $value > $maxiv) 
	{
	    $warn = "Warning: voltage limit for iV curves must be between $miniv mV and $maxiv mV in electrolysis mode";
	    $value = $maxiv;
	}
	if (($key eq 'ivpause') && $value < 0.1) 
	{
	    $warn = "Warning: iv pause must be between 0.1 and 1000 seconds";
	    $value = 1;
	}
	if (($key eq 'ivpause') && $value > 1000) 
	{
	    $warn = "Warning: iv pause must be between 0.1 and 1000 seconds";
	    $value = 1000;
	}
	if (($key eq 'OCV_measure_number') && $value < 2) 
	{
	    $warn = "Warning: OCV measure number pause must be between 2 and 10";
	    $value = 2;
	}
	if (($key eq 'OCV_measure_number') && $value > 10) 
	{
	    $warn = "Warning: OCV measure number pause must be between 2 and 10";
	    $value = 10;
	}
    }
    if ($section =~ /^PSU/i || $section =~ /^current$/i)
    {
	if (($key eq 'parallel' || $key eq 'serial') && ($value !~ /^\d+$/ || $value < 1))
	{
	    $warn = "Warning: '$key' can only be set to positive integers!";
	    if ($value =~ /(\d+)/)
	    {
		$value = $1;
	    }
	    $value = 1 if ($value < 1);
	}
    }
    if ($section =~ /gas_multiplex/ && $key ne 'type')
    {
	### Set channel key coorectly ###
	if ($section =~ /_(\d+)/)
	{
	    my $n = $1;
	    my $type = $rig->get_cv($section,'type');
	    my $device = RFC::Device::new_Multiplexer($rig,$n,$type);
	    unless ($device->type eq 'Selector')
	    {
		my @gasses = ();
		my $controler = 0;
		foreach my $c ($rig->avaliable_devices('MFC'))
		{
		    my $dev = $rig->init_device('MFC',$c);
		    next unless ($dev && $dev->multiplexer && $dev->multiplexer->name eq $device->name);
		    @gasses = $dev->gasses();
		    $controler = $dev->name;
		}
		unless ($controler)
		{
		    $val = '' unless (defined($val));
		    print "Error: could not find any MFC with multiplexer ".$device->name."\n";
		    print "$key\n";
		    print "$val\n";
		    exit;	    
		}
		my @list = ();
		foreach my $gas (@gasses)
		{
		    my $ch = $device->channel($gas);
		    $ch = $value if ($gas eq $key);
		    push @list,$ch;
		}
		$rig->change_config_value($section,'channels',join(',',@list));
	    }
	}
	else
	{
	    $val = '' unless (defined($val));
	    print "Error: could not initialise multiplxexer deivce $section";
	    print "$key\n";
	    print "$val\n";
	    exit;	    
	}
    }
    if ($section =~ /^gas_(\w+)/ && $section !~ /gas_multiplex/ && $key ne 'mode')
    {
	### Update cotoff_report if it is not set (or too small) and gas is configured as automatic ###
	### Minimum value is 0.75 times the accuracy of the controler                                ###
	my $gas = $1;
	eval {
	    unless ($rig->get_cv($section,'mode') =~ /manual/)
	    {
		my $user = &get_user();
		my $contr = $rig->get_cv($section,'controler');
		my $dev = $rig->get_device('MFC',$contr);
		if ($dev)
		{
		    my $cut = $dev->accuracy() * 0.75;
		    if ($cut && !$rig->get_cv($section,'cutoff_report') && (!$rig->get_cv($section,'cutoff_report') || $rig->get_cv($section,'cutoff_report') < $cut)) 
		    {
			$rig->change_config_value($section,'cutoff_report',$cut);
		    }
		}
	    }
	};
    }
    if ($section =~ /^gas_(\w+)/ && $section !~ /gas_multiplex/  && $key eq 'mode')
    {
	my $gas = $1;
	eval {
	    ### Check for valid data ###
	    my $oldval = $rig->get_cv($section,$key);
	    $oldval = '' unless defined($oldval);
	    $res = $rig->change_config_value($section,$key,$value);
	    my $user = &get_user();
	    if ($value =~ /manual/i)
	    {
		$res = $rig->change_config_value($section,'controler',0);
		my $string = "Key 'controler' in section '$section' was changed to '0'";
		$rig->proglog($string,$user);
	    }
	    else
	    {
		my @controler = ();
		foreach my $mfc ($rig->avaliable_devices('MFC'))
		{
		    my $mfcdev = $rig->get_device('MFC',$mfc);
		    $mfcdev = $rig->init_device('MFC',$mfc) unless ($mfcdev);
		    my @glist = ();
		    @glist = $mfcdev->gasses() if ($mfcdev);
		    my $gstr = join(' ',@glist);
		    push @controler,$mfc if ($gstr && ($gstr eq $gas || $gstr =~ /\b$gas\b/));
		}
		if (@controler == 1)
		{
		    my $contr = $rig->get_cv($section,'controler');
		    my $ok = 1;
		    if ($contr ne $controler[0])
		    {
			$rig->proglog("Warning MFC setup for gas '$gas' incorrect (was $contr, should be $controler[0]), correcting...",$user);
		    }
		    $rig->change_config_value($section,'controler',$controler[0]);
		    my $mfcdev = $rig->get_device('MFC',$controler[0]);
		    my $cut = $mfcdev->accuracy() * 0.75;
		    unless ($rig->get_cv($section,'cutoff_report') && $rig->get_cv($section,'cutoff_report') > $cut)
		    {
			$rig->change_config_value($section,'cutoff_report',$cut);
		    }
		}
		else
		{
		    die "Warning, No controlers was founs for gas '$gas'!" unless (@controler);
		    die "Warning, More than one controler found for gas '$gas'!";
		}
	    }
	    $rig->init();
	    $rig->commit;
	    $value = '' unless defined($value);
	    my $string = "Key '$key' in section '$section' was changed from '$oldval' to '$value'";
	    $rig->proglog($string,&get_user());
	};
	if ($@)
	{
	    $rig->rollback;
	    $val = '' unless (defined($val));
	    print "Error: change resulted in an invalid configuration, issuing rollback; error: $@";
	    print "$key\n";
	    print "$val\n";
	    exit;
	}
	$val = $rig->get_cv($section,$key);
	if ($warn)
	{
	    print "WARN\n";
	}
	else
	{
	    print "OK\n";
	}
	$val = '' unless (defined($val));
	print "$key\n";
	print "$val\n";
	print "$warn\n";
	exit;
    }
    if ($section =~ /^temp_/)
    {
	$key = 'type' if ($key eq 'mode');
	$value = '' if ($key eq 'type' && $value eq 'Analog');
    }
    if (($section =~ /^gas_/ && $section !~ /gas_multiplex/  && $key eq 'link') || ($section eq 'main' && ($key eq 'vogt_gasses' || $key eq 'additional_vogt_gasses_cutoff')))
    {
	my @list = split(/\s*\,\s*/,$value);
	my @gasses = $rig->avaliable_devices('gas');
      OUTER:
	foreach my $g (@list)
	{
	  INNER:
	    foreach (@gasses)
	    {
		next INNER unless ($g eq $_);
		next OUTER;
	    }
	    $val = '' unless (defined($val));
	    print "WARN\n";
	    print "$key\n";
	    print "$val\n";
	    print "Error: gas $g not found in configuration for $rig\n";
	    exit;
	}
    }
    if ($section =~ /controler_(\w+)/i && $key eq 'gas')
    {
	my $name = $1;
	my $oldval = $rig->get_cv($section,$key);
	eval {
	    ### Check for valid data ###
	    $res = $rig->change_config_value($section,$key,$value);
	    $rig->init();
	    ### Explicit check for valid gas ###
	    my $dev = $rig->init_device('gas',$value);
	    die "No gas found with name '$value'\n" unless ($dev);
	    $rig->commit;
	    my $string = "Key '$key' in section '$section' was changed from '$oldval' to '$value'";
	    $rig->proglog($string,&get_user());
	};
	if ($@)
	{
	    $rig->rollback;
	    $oldval = '' unless (defined($oldval));
	    print "Error: change resulted in an invalid configuration, issuing rollback; error: $@";
	    print "$key\n";
	    print "$oldval\n";
	    exit;
	}
	$value = '' unless (defined($value));
	print "OK\n";
	print "$key\n";
	print "$value\n";
	exit;
    }
    if ($section =~ /controler_(\w+)/i && $key eq 'gasses')
    {
	my $name = $1;
	my $oldval = $rig->get_cv($section,$key);
	eval {
	    ### Check for valid data ###
	    foreach my $g (split(/\s*\,\s*/,$oldval))
	    {
		my $dev = $rig->init_device('gas',$g);
		next unless ($dev);
		$dev->change_cv('controler',0);
		$dev->change_cv('mode','Manual');
	    }	    
	    $res = $rig->change_config_value($section,$key,$value);
	    ### Explicit check for valid gas list ###
	    my %h = ();
	    foreach my $g (split(/\s*\,\s*/,$value))
	    {
		my $dev = $rig->init_device('gas',$g);
		die "No gas found with name '$g'\n" unless ($dev);
		die "Duplicate gas '$g' found!\n"if (exists($h{$g}));
		$h{$g} = 1;
		### Check that gas has corrct controler set and fix if not defined
		my $cont = $dev->get_conf('controler');
		next if ($cont eq $name);
		die "gas '$g' had a different controler ($cont) already specified!" if ($cont);
		$dev->change_cv('controler',$name);
		$dev->change_cv('mode','Automatic');
	    }
	    $rig->init();
	    $rig->commit;
	    my $string = "Key '$key' in section '$section' was changed from '$oldval' to '$value'";
	    $rig->proglog($string,&get_user());
	};
	if ($@)
	{
	    $rig->rollback;
	    $oldval = '' unless (defined($oldval));
	    print "Error: change resulted in an invalid configuration, issuing rollback; error: $@";
	    print "$key\n";
	    print "$oldval\n";
	    exit;
	}
	$value = '' unless (defined($value));
	print "OK\n";
	print "$key\n";
	print "$value\n";
	exit;
    }
    if ($section =~ /controler_(\w+)/i && $key eq 'gas_change')
    {
	my $name = $1;
	my $oldval = $rig->get_cv($section,$key);
	$oldval = 'Manual' unless defined($oldval);
	eval {
	    ### Check for valid data ###
	    $res = $rig->change_config_value($section,$key,$value);
	    $rig->init();
	    ### Explicit check for valid multiplexer ###
	    my $dev = $rig->init_device('MFC',$name);
	    $rig->commit;
	    $value = '' unless defined($value);
	    my $string = "Key '$key' in section '$section' was changed from '$oldval' to '$value'";
	    $rig->proglog($string,&get_user());
	};
	if ($@)
	{
	    $rig->rollback;
	    $oldval = '' unless (defined($oldval));
	    print "Error: change resulted in an invalid configuration, issuing rollback; error: $@";
	    print "$key\n";
	    print "$oldval\n";
	    exit;
	}
	$value = '' unless (defined($value));
	print "OK\n";
	print "$key\n";
	print "$value\n";
	exit;	
    }
    if ($section eq 'control_logic' && $key =~ /limit_vogt$/)
    {
	my $oldval = $rig->get_cv($section,$key);
	$oldval = '' unless defined($oldval);
	eval {
	    ### Check for valid data ###
	    $res = $rig->change_config_value($section,$key,$value);
	    $rig->init();
	    $rig->commit;
	    $value = '' unless defined($value);
	    my $string = "Key '$key' in section '$section' was changed from '$oldval' to '$value'";
	    $rig->proglog($string,&get_user());
	};
	if ($@)
	{
	    $rig->rollback;
	    print "Error: change resulted in an invalid configuration, issuing rollback; error: $@";
	    $oldval = '' unless (defined($oldval));
	    print "$key\n";
	    print "$oldval\n";
	    exit;
	}
	$value = '' unless (defined($value));
	print "OK\n";
	print "$key\n";
	print "$value\n";
	exit;
    }
    if ($section eq 'userinterface' || $section eq 'report' || ($section eq 'control_logic' && $key !~ /logic|additional/))
    {
	my @list = split(/\s*\,\s*/,$value);
	my @names = ();
	@names = ($rig->avaliable_devices('templog'),$rig->avaliable_devices('tempcontrol')) if ($key eq 'temp' || $key eq 'temp_names_history' || $key =~ /templog/);
	@names = $rig->avaliable_devices('gas') if ($key eq 'gas' || $key eq 'gas_names_history' || $key eq 'gas_names_ivtable');
	@names = $rig->avaliable_devices('water') if ($key eq 'water_names_history');
	@names = $rig->avaliable_devices('Alert') if ($key eq 'alert');
	@names = $rig->avaliable_devices('simplechannel') if ($key eq 'voltage' || $key eq 'current' || $key eq 'current_names_history' || $key eq 'simple_names_history' || $key eq 'voltage_label_vogt');
      OUTER:
	foreach my $g (@list)
	{
	  INNER:
	    foreach (@names)
	    {
		next unless $_;
		next INNER unless ($g eq $_);
		next OUTER;
	    }
	    print "WARN\n";
	    $val = '' unless (defined($val));
	    print "$key\n";
	    print "$val\n";
	    print "Error: ".ucfirst($key)." device $g not found in configuration for $rig\n";
	    exit;
	}
    }
    eval {
	### Check for valid data ###
	my $oldval = $rig->get_cv($section,$key);
	$oldval = '' unless defined($oldval);
	$res = $rig->change_config_value($section,$key,$value);
	$value = '' unless defined($value);
	my $string = "Key '$key' in section '$section' was changed from '$oldval' to '$value'";
	$rig->init();
	### Test if device config is invalid ##
	if ($section =~ /filter_(\w+)/)
	{
	    my $dev = $rig->init_device('filter',$1);
	    $dev->init() if ($dev);
	}
	$rig->commit;
	$rig->proglog($string,&get_user());
    };
    if ($@)
    {
	$rig->rollback;
	print "Error: change resulted in an invalid configuration, issuing rollback; error: $@";
	$val = '' unless (defined($val));
	print "$key\n";
	print "$val\n";
	exit;
    }
    $val = $rig->get_cv($section,$key);
    if ($warn)
    {
	print "WARN\n";
    }
    else
    {
	print "OK\n";
    }
    $val = '' unless (defined($val));
    print "$key\n";
    print "$val\n";
    print "$warn\n";
    exit;
}



