esrf

Beamline Instrument Software Support
SPEC Macro documentation: [ Macro Index | BCU Home ]

#%TITLE% LOCK.MAC
#%NAME% Software Lock motor macros
#%CATEOGRY% Positioning, Tools
#%DESCRIPTION%
#
# These macros allow the user to lock a motor and prevent it for moving.
# The checking is done before every movement and it is done at the macro
# level... this means that motors are locked for one user but perhaps
# not for another one.
# If you want to prevent a motor to be moved by ANY user... you should
# check the restrictions flag in the config file for that motor to
# "CANT MOVE"
#
# This macros are NOT HACK-PROOF. The idea is just to make life easier
# by avoiding consequences of forgetting a motor should not be moved...
# then spec will remind it to you. I am sure you will still be able to
# move if you really want to.
#
# Should we define only authorised users for locking? The answer is
# no. If you really want by all means to avoid a motor be moved by the
# user use config and protections in UNIX file system.
#
#%OVERVIEW%
#   Basic commands are:
#   %DL%
#   %DT%lock%DD%   Locks a motor and a comment can be stored with the lock
#                  flag
#   %DT%unlock%DD% Unlocks a motor that was previously locked.
#   %DT%lockshow%DD%   Shows all the motor locks.
#   %DT%lockclear%DD%  Clear all the locks.
#   %XDL%
#%BR%
#
#%EXAMPLE%
#   %DL%
#   %DT% %B% laposmenu%B%  %DD% (Opens the menu)
#   %DT% %B% lock %B% %B% mu %B% %B% "It is broken" %B% %B% Vicente %B% %DD%
#             (Locks the motor "mu" with message and user name
#   %DT% %B% laposconfig %B% %B% lapos.dat%B% %B% %DD%
#             ( Configure the system from file lapos.dat)
#   %XDL%
#%BR%
#
#%SETUP%
#   The macro locksetup must be executed once when SPEC is started fresh
#   before any of the other macros in this macro set.
#
#%END%

##
#  locksetup
##


#%UU%
#%MDESC%
#  Do all the necessary setup and variable definition.
#  TAKE CARE : lock does not work if locksetup has not been executed...
def locksetup '{
    global LOCKTABLE LOCKNO LOCKOLD LOCK_ON LOCK_OFF
    global LOCKMESS LOCKUSER LOCK_SETUP
    global COMSTR

    COMSTR = "Comment="

    LOCK_ON  = 1
    LOCK_OFF = 0

    cdef("user_checkall",   "_lockcheck;",     "LOCK")
    cdef("user_getpangles", "_lockgetangles;", "LOCK")

    LOCK_SETUP = 1
}'


#%UU%
#%MDESC%
#  Clean all lock stuff 
def lockunsetup '{

    cdef("user_checkall",   "", "LOCK", "delete")
    cdef("user_getpangles", "", "LOCK", "delete")

    unglobal LOCKTABLE LOCKNO LOCKOLD LOCK_ON LOCK_OFF
    unglobal LOCKMESS LOCKUSER
    unglobal COMSTR

}'


#%UU% [filename]
#%MDESC%
#   Saves the lock state into a file. Can be restored later with
#   lockrestore
#   !! take care : if saving in an existing file, the file is not flushed...
def locksave '{

    local nbparam
    local lockfile
    local ii

    nbparam = $#

    if (nbparam > 1) {
        print "Usage:  locksave filename"
        exit
    }

    # get filename.
    if (nbparam != 1) {
        lockfile = getval("File name for saving locks", 0)
    }
    else {
        lockfile = "$1"
    }

    # warn if lockfile alredy exits.
    if(file_info(lockfile, "-e")){
        printf ("locksave WARNING : file \"%s\" exists\n", lockfile)
    }

    on(lockfile)
    offt

    for( ii = 0 ; ii < MOTORS ; ii++) {
        if (LOCKTABLE[ii] == LOCK_ON) {
            printf("%d %s Comment=%s\n", ii, LOCKUSER[ii], LOCKMESS[ii])
        }
    }
    ont
    close(lockfile)
}'

##
#  lockrestore
##
#%UU% [filename]
#%MDESC%
#
#   Restores saved by a previous locksave.
#
def lockrestore '{

    local rline
    local nbparam
    local lockfopen

    nbparam = $#

    if (nbparam > 1) {
        print "Usage: lockrestore filename"
        exit
    }

    if (nbparam != 1) {
        lockfile = getval("File name for restoring locks",0)
    }
    else {
        lockfile = "$1"
    }

    if (getline(lockfile, "open") != 0){
        printf("Error opening file %s for reading\n", lockfile)
        lockfopen = 0
    }
    else {
        lockfopen = 1
    }

    while(lockfopen)
        {
            rline = getline(lockfile)

            if (rline == "-1")  {
                lockfopen = 0
                getline(lockfile, "close")
                continue
            }

            nn = sscanf(rline, "%d %s %*s", lomotor, louser)
            buf = substr(rline, index(rline, COMSTR) + length(COMSTR))
            locomment = substr(buf, 1, length(buf)-1)
            LOCKOLD[lomotor]   = A[lomotor]
            LOCKTABLE[lomotor] = LOCK_ON
            LOCKMESS[lomotor]  = locomment
            _lockmess(lomotor)
        }

}'
##
#  lockclear
##
#%UU%
#%MDESC%
#
#   Clears all the locks in the system.
#
def lockclear '{
    local ii

    for(ii = 0 ; ii < MOTORS ; ii++) {
        LOCKTABLE[ii] = LOCK_OFF
    }
}'

##
#  lock
##
#%UU% motor [comment] [user]
#%MDESC%
#
#   Locks a motor for moving. Comment (like reason of the locking) and
#   a name identifying the user should be given in the command line or
#   the macro will prompt for them.
#
def lock '{
    #
    # Check usage:
    #
    local nbparam
    nbparam = $#


    if (LOCK_SETUP != 1){
        print "ERROR : lock is not initialized : use locksetup"
        exit
    }

    if (nbparam < 1) {
        print "Usage:  lock motor [comment] [user]"
        exit
    }

    _check0 "$1"

    LOCKOLD[$1] = A[$1]
    LOCKTABLE[$1] = LOCK_ON

    if (nbparam > 1 ) LOCKMESS[$1] = "$2"
    if (nbparam > 2 ) LOCKUSER[$1] = "$3"

    if (nbparam < 2 ) {
        LOCKMESS[$1] = getval("lock message",LOCKMESS[$1])
    }

    if (nbparam < 3 ) {
        LOCKUSER[$1] = getval("username",LOCKUSER[$1])
    }

    printf("Locking motor %s \(%s\). %s\n",    \
           motor_name($1),motor_mne($1),LOCKMESS[$1])

}'

##
#  unlock
##
#%UU% motor
#%MDESC%
#
#   Clear the lock for a motor.
#
def unlock '{
    local nbparam
    nbparam = $#

    if (nbparam < 1) {
        print "Usage:  unlock motor"
        exit
    }

    _check0 "$1"

    if (LOCKTABLE[$1] == LOCK_ON) {
        LOCKTABLE[$1] = LOCK_OFF
        printf("Motor %s \(%s\) unlocked\n",motor_name($1),motor_mne($1))
    } else {
        printf("Motor %s \(%s\) was not locked\n",motor_name($1),motor_mne($1))
    }
}'

##
#  lockshow
##
#%UU%
#%MDESC%
#
#   Shows a list of all the locks in the system.
#
def lockshow '{
    local ii

    for (ii=0 ; ii < MOTORS ; ii++) {
        if ( LOCKTABLE[ii] == LOCK_ON ) {
            _lockmess(ii)
        }
    }
}'

#%IU% (motor_number)
#%MDESC%
#   Prints a short message on the screen informing that the motor is locked.
def _lockmess(mot_nb) '{
    printf("Motor %s \(%s\) locked by %s. %s\n",   \
           motor_name(mot_nb),motor_mne(mot_nb),LOCKUSER[mot_nb],LOCKMESS[mot_nb])
}'


##
# _lockcheck
##
#%IU%
def _lockcheck '{
    local mot_nb

    for ( mot_nb=0 ; mot_nb < MOTORS ; mot_nb++) {
        if (LOCKTABLE[mot_nb] == LOCK_ON) {
            if (LOCKOLD[mot_nb] != A[mot_nb]) {
                A[mot_nb] = LOCKOLD[mot_nb]
                _lockmess(mot_nb)
                exit
            }
        }
    }
}'

##
# _lockgetangles
##
#%IU%
def _lockgetangles '{
    local ii

    for (ii=0 ; ii<MOTORS ; ii++) {
        if (LOCKTABLE[ii] == LOCK_ON) {
            LOCKOLD[ii] = A[ii]
        }
    }
}'

#%MACROS%
#%IMACROS%
#%AUTHOR% Vicente Rey 20 Jan. 1995
#%TOC%