esrf

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


# Set of macro to define security rules when moving motors.
# You can define functions to call before moving in order to
# avoid collisions by example.
# A.Homs

# Works like a pseudo motor.

#%UU% []
#%MDESC%
#    Adds a call to "security_check_all" in "user_checkall".
def security_setup '{
    local _flags

    global SECU_A[]

    global SECU[]

    _flags = (motor_num("secu") >= 0) ? 0x10 : 0

    cdef("user_checkall", "security_check_all; ", "secu", _flags)

    security_on
    setup_tail("secu")

}'

def security_status '{
    print "No customization of security macros."
}'


# Turns ALL security checks on.
def security_on '{
    SECU["on"] = 1
}'

# Turns ALL security checks off.
def security_off '{
    SECU["on"] = 0
}'


# Removes cdefs calls for security.
def security_unsetup '{
    cdef("user_checkall", "", "secu", "delete")
    security_off
}'


#%IU%
#%MDESC%
#    Ternminates the running macro in case of security problem.
def security_check_all '{
    if (security_check_funct() == -1)
        exit
}'


#%IU%
#%MDESC%
#    Returns  0 in case of success.
#    Returns -1 in case of security problem.
def security_check_funct() '{
    local _rmsg

    if (!SECU["on"])
        return 0

    # ???
    _rmsg = security_check(0)

    if (_rmsg != "") {
        print ""
        cprint("BL security error: trying to move to invalid state: \n ", 1)
        cprint( _rmsg, 5)
        print ""
        # Stop all asynchronous activity
        stop()
        return -1
    }

    return 0
}'



#%IU% (<update>, <arr>)
#%MDESC%
#    Returns "" in case of success.
#    Returns same thing as user_security_chk_conds in case of problem.
def security_check(update, arr) '{
    local mnum rmsg

    # Copies the A array.
    security_get_angles

    # Updates the copy Array if requiered.
    if (update) {
        for (mnum in arr)
            SECU_A[mnum] = arr[mnum]
    }

    # Checks conditions filled by user.
    user_security_chk_conds

    return ""
}'


#%UU% (<mot>, <newpos>)
#%MDESC%
#
def security_check_simple_mv(mot, newpos) '{
    local arr[] rmsg

    if (!SECU["on"])
        return 0

    arr[mot] = newpos

    if ((rmsg = security_check(1, arr)) != "") {
        print "\nBL security error: trying to move to invalid state:"
        print "  ", rmsg
        return -1
    }
    return 0
}'


#%IU% []
#%MDESC%
#    Saves a copy of A array.
def security_get_angles '{
    SECU_A = A
}'


#%UU%  (<condname>, <cond>, <message>)
#%MDESC%
#    Adds a condition in security macro "user_security_chk_conds".
# -<condname> : condition name to allow to remove it later.
# -<cond>     : name of the condition test macro.
# -<message>  : string returned to be displayed.
def secuaddcond(condname, cond, msg) '{
    local _mstr

    _mstr = sprintf("if (!(%s)) return \"%s\"\n", cond, msg)

    cdef("user_security_chk_conds", _mstr, condname)
}'

# 
def secuaddcondfunc(condname, condfunc) '{
    local _mstr

    _mstr = sprintf("if ((rmsg = %s) != \"\") return rmsg\n", condfunc)

    cdef("user_security_chk_conds", _mstr, condname)

    # For status displaying.
    SECU[condname] = "on"
}'


#%UU% (<condname>)
#%MDESC%
#    Removes <condname> condition.
def securemovecondfunc(condname) '{

    printf ("Removing security rule \"%s\"  \n", condname)

    cdef("user_security_chk_conds", "", condname, "delete")

    # For status displaying.
    SECU[condname] = "off"
}'

# Creates the stub macros hosting others secu functions.
cdef("user_security_chk_conds")




######################################################################
##############################           #############################
##############################  EXAMPLE  #############################
##############################           #############################
######################################################################

# Example of secu customization

def exsecu_chk() '{

    if (SECU_A[m1] > 25){
        return "m1 too high"
    }

    if (SECU_A[m2] < -2){
        return "m2 too low"
    }

    # do not forget to return "" in case of success.
    return ""
}'

# add security rule for example.
def exsecu_on '{
    # to be sure that security is initialized.
    security_setup

    print "Setting  \"exsecu\"  security rule ON"
    secuaddcondfunc("exsecu", "exsecu_chk()")
}'

#and disable it.
def exsecu_off '{
    securemovecondfunc("exsecu")
}'



######################################################################
#######################                        #######################
#######################  STATUS CUSTOMIZATION  #######################
#######################                        #######################
######################################################################

# 1 ligne per rule.

def security_status '{
    print "----------------------  SECURITY RULES ------------------------"
    print "Example Status of securities:"
    printf (" - exsecu is : ")
    if(SECU["exsecu"]=="off"){
        cprint("off\n", 1, 8, 1)
    }
    else if(SECU["exsecu"]=="on") {
        cprint("on\n", 2, 8, 1)
    }
    else{
        cprint("unknown\n",3, 8, 1, 1)
    }
    print "---------------------------------------------------------------"
}'


######################################################################
############################               ###########################
############################  MACRO MOTOR  ###########################
############################               ###########################
######################################################################


#def security_config(mnum, type, unit, module, chan) '{
#  local id nsecu allsecu[] alldep i
#
#  id = get_ctrl_id("security", module)
#  nsecu = split(get_property(id, motor_mne(mnum)), allsecu, ",")
#  alldep = allsecu[0]
#  for (i = 1; i < nsecu; i++)
#    alldep = sprintf("%s %s", alldep, allsecu[i])
#
#  return alldep
#}'
#
#def security_calc(mnum, mode) '{
#  security_check_all
#}'