FMB-DCM: ExitOffset, Tango

The following virtual motor changes the ExitOffset parameter of FMB Oxford monochromators using the following procedure: the current energy is read and stored in symbol $posOld, the ExitOffset is changed to the requested value and finally the energy is moved to $posOld. The Bragg axis stays at their position, the translations are moved.

#!/usr/bin/perl -w
#
# file name: /online_dir/vm35.pl
#

my ($method, $value_new) = @ARGV; 
my ( $min, $max) = ( 15, 23); 

my $status = 1; 

if( $method eq "set_position")
{
    if( $value_new < $min ||
	$value_new > $max)
    {
	$status = Spectra::error( "vm35: requested position $value_new outside limits $min, $max"); 
	goto finish;
    }
    $posOld = Spectra::tng_attrDoubleRd( "fmbenergy", "Position");
    $ret = Spectra::tng_attrDoubleWrt( "fmbenergy", "ExitOffset", $value_new);
    $ret = Spectra::tng_attrDoubleWrt( "fmbenergy", "Position", $posOld);
    my $startTime = Spectra::Secnds(); 
    while( Spectra::tng_state( "fmbenergy") == 6)
    {
	Spectra::wait( 0.1); 
        #
        # refresh the motor positions and sense 'Stop' clicks
        #
        Util::refresh(); 
	if( (Spectra::secnds() - $startTime) > 5)
	{
	    $status = Spectra::error( "vm35: move didn't finish within 5s"); 
	    goto finish;
	}
    }
}
elsif( $method eq "get_position")
{
    $SYM{RETURN_VALUE} = Spectra::tng_attrDoubleRd( "fmbenergy", "ExitOffset");
}
elsif( $method eq "get_limit_min")
{
    $SYM{RETURN_VALUE} = $min;
}
elsif( $method eq "get_limit_max")
{
    $SYM{RETURN_VALUE} = $max;
}
elsif( $method eq "exec_stop")
{
    Spectra::tng_inout( "fmbenergy", "StopMove"); 
}
else
{
    Spectra::error( "vm1: failed to identify $method"); 
    $status = 0;
    goto finish;
}
finish:
 $status;