#!/bin/sh
# \
exec oagwish -f "$0" "$@"



set auto_path [linsert $auto_path 0  /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]
APSDebugPath
set CVSRevisionAuthor "\$Revision: 1.8 $ \$Author: soliday $"

if [llength $argv]==0 {
    puts stderr "usage: SRrfLimitProbePower <station>"
    exit
}

set station [lindex $argv 0]
switch $station {
    1 {
        set inputVariables {S1KPSbeamPower}
        set inputPVs  {SRF:P1:beamPower }
        set offsetVariables {S1KPSbeamPowerOffset}
        set offsetPVs {SRF:K1:ED1:Ch1KWatt }
        set limitValueInitial { 800 }
        set diffNames { S1CollectorPower }
        set outputToUseGroup { 0 }
    }
    2 {
        set inputVariables {S2KPSbeamPower}
        set inputPVs  {SRF:P2:beamPower }
        set offsetVariables {S2KPSbeamPowerOffset}
        set offsetPVs {SRF:K2:ED1:Ch1KWatt }
        set limitValueInitial { 800 }
        set diffNames { S2CollectorPower  }
        set outputToUseGroup { 1 }
    }
    - {
        puts stderr "unknown station $station given"
        exit
    }
}

set debug 0
if $debug {
    set outputVariables { BTSAH1 BTSAV1 BTSAH2 BTSAV2 }
    set outputPVs { BTS:AH1:CurrentAO  BTS:AV1:CurrentAO BTS:AH2:CurrentAO BTS:AV2:CurrentAO }
    set faultValues { 0 0 0 0 }
    set outputVarGroup { 0 0 1 1 }
    set rampPause {0.0 0.1 0.0 0.1 }
} else {
    set outputVariables { S1rfInhibit S1KModAnodeVoltageAdj S2rfInhibit S2KModAnodeVoltageAdj }
    set outputPVs { S1:K:rfDriveInhibit SRF:P1:modAnodeVoltageAdj S2:K:rfDriveInhibit SRF:P2:modAnodeVoltageAdj }
    set faultValues  { 0 20000 0 20000 }
    set outputVarGroup { 0 0 1 1 }
    set rampPause { 0.0 1.0 0.0 1.0 }
}
        
set Variables [concat $inputVariables $offsetVariables $outputVariables ]
set PVs [concat $inputPVs $offsetPVs $outputPVs ]

set count [llength $PVs]
for {set i 0} {$i<$count} {incr i} {
    if {[pv linkw [lindex $Variables $i] [lindex $PVs $i]] !=0 } {
        puts $errorCode
        exit
    }
}


APSApplication . -name SRrfLimitCollPower -version $CVSRevisionAuthor \
  -overview {This application is intended to limit storage ring klystron collector power.}


set mainStatus "Ready."
APSScrolledStatus .record -parent .userFrame -textVariable mainStatus -width 60  \
        -height 2

proc SetMainStatus {text} {
    global mainStatus
    set mainStatus $text
    update
}

set tcl_precision 4

set index 0
foreach inputVar $inputVariables {
    APSFrame .f$inputVar -parent .userFrame -label ""
    set w .userFrame.f$inputVar.frame
    set diffVar ${inputVar}Diff
    set limitVar ${inputVar}Lim
    set enableVar ${inputVar}Enb
    set offsetVar ${inputVar}Offset
    set $limitVar [lindex $limitValueInitial $index]
    set $enableVar 1
    set $diffVar 0
    set diffName [lindex $diffNames $index]
    incr index
    APSLabeledOutput .value -parent $w -label "$diffName value: " \
      -textVariable $diffVar -packOption "-side left -fill x" \
      -width 10
    APSLabeledEntry .limit -parent $w -label "limit: " \
      -textVariable $limitVar -packOption "-side left -fill x" \
      -width 6
    checkbutton $w.enb -variable $enableVar 
    pack $w.enb -side left
}


proc DisableEntryBoxes {} {
    global inputVariables
    foreach inputVar $inputVariables {
        .userFrame.f$inputVar.frame.limit.entry configure -state disabled
    }
}

proc EnableEntryBoxes {} {
    global inputVariables
    foreach inputVar $inputVariables {
        .userFrame.f$inputVar.frame.limit.entry configure -state normal
    }
}


APSButton .run -parent .userFrame -text "RUN" \
        -command StartLimiting \
        -contextHelp "Initiate limiting of readbacks within parameters given above."
APSButton .stop -parent .userFrame -text "STOP" \
        -command StopLimiting \
        -contextHelp "Stop limiting readbacks."
APSDisableButton .userFrame.stop.button


set limitingOn 0
proc StartLimiting {} {
    global limitingOn limitsFrame
    APSDisableButton .userFrame.run.button
    APSEnableButton .userFrame.stop.button
    DisableEntryBoxes
    EvaluateValues
    SetMainStatus "Limiting activated [exec date]"
    set limitingOn 1
}

proc StopLimiting {} {
    global limitingOn
    set limitingOn 0
    APSEnableButton .userFrame.run.button
    APSDisableButton .userFrame.stop.button
    EnableEntryBoxes
    SetMainStatus "Limiting deactivated [exec date]"
}

proc EvaluateValues {} {
    global limitingOn inputVariables outputVariables faultValues
    global enableLimit limitValue outputEnables  offsetVariables
    global errorCode outputToUseGroup outputPVs outputVarGroup

    foreach elem $inputVariables {
        global $elem ${elem}Offset ${elem}Diff
    }

    if [pv getw [concat $inputVariables $offsetVariables]]!=0 {
        puts stderr "$errorCode"
        return 
    }

    foreach inputVar $inputVariables {
        set offsetVar  ${inputVar}Offset
        set diffVar    ${inputVar}Diff
        set value0 [subst \$$inputVar]
        set offset [subst \$$offsetVar]
        set $diffVar [expr $value0-$offset]
    }

    if !$limitingOn return

    set ivIndex 0
    foreach inputVar $inputVariables {
        global ${inputVar}Enb ${inputVar}Lim 
        set outputGroup [lindex $outputToUseGroup $ivIndex]
        incr ivIndex
        set enabled [subst \$${inputVar}Enb]
        if !$enabled continue
        set limit [subst \$${inputVar}Lim]
        set diffVar    ${inputVar}Diff
        set diff [subst \$$diffVar]
        if {$diff>$limit} {
            set ovIndex 0
            SetMainStatus "$inputVar at $diff--limit is $limit"
            foreach outputVar $outputVariables {
                if [lindex $outputVarGroup $ovIndex]==$outputGroup {
                    global rampPause
                    set pause [lindex $rampPause $ovIndex]
                    set outputPV [lindex $outputPVs $ovIndex]
                    set end [lindex $faultValues $ovIndex]
                    SetMainStatus "Ramping $outputPV to $end [exec date +%H:%M:%S]."
                    update
                    APScaRamp -pvList $outputPV -variableList $outputVar -endList $end -steps 30 -pause $pause
                }
                incr ovIndex
            }
            SetMainStatus "Done ramping $outputPV [exec date +%H:%M:%S]."
            update
            global debug
            if $debug StopLimiting
            return
        }
    }
}


APSEnableButton .userFrame.run.button
APSDisableButton .userFrame.stop.button
if $debug {SetMainStatus "Debug mode"}
while 1 {
    EvaluateValues
    update
    after 500
}

