#!/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.12 $ \$Author: soliday $"

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

set rampModAnode 0

set station [lindex $argv 0]
switch $station {
    1 {
        set inputVariables {
            S1C1ProbePower S1C2ProbePower S1C3ProbePower S1C4ProbePower \
              S4C1ProbePower S4C2ProbePower S4C3ProbePower S4C4ProbePower \
          }
        set inputPVs {
            SRF:S40:ED1:Ch2KWatt SRF:S40:ED2:Ch2KWatt SRF:S40:ED3:Ch2KWatt SRF:S40:ED4:Ch2KWatt \
              SRF:S38:ED1:Ch2KWatt SRF:S38:ED2:Ch2KWatt SRF:S38:ED3:Ch2KWatt SRF:S38:ED4:Ch2KWatt \
          }
        set enableLimitInitial {
            1 1 1 1 \
              1 1 1 1 \
          }
        set limitValueInitial {
                49 49 49 49 \
                49 49 49 49 \
          }
        set outputToUseGroup 0
    }
    2 {
        set inputVariables {
              S2C1ProbePower S2C2ProbePower S2C3ProbePower S2C4ProbePower \
              S3C1ProbePower S3C2ProbePower S3C3ProbePower S3C4ProbePower \
          }
        set inputPVs {
              SRF:S36:ED1:Ch2KWatt SRF:S36:ED2:Ch2KWatt SRF:S36:ED3:Ch2KWatt SRF:S36:ED4:Ch2KWatt \
              SRF:S37:ED1:Ch2KWatt SRF:S37:ED2:Ch2KWatt SRF:S37:ED3:Ch2KWatt SRF:S37:ED4:Ch2KWatt \
          }
        set enableLimitInitial {
              1 1 1 1 \
              1 1 1 1 \
          }
        set limitValueInitial {
                65 65 65 65 \
                50 50 50 50 \
          }
        set outputToUseGroup 1
    }
    - {
        puts stderr "unknown station: $station"
        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 }
    set outputActiveDefault {1 1 1 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 33000 0 33000 }
    set outputVarGroup { 0 0 1 1 }
    set rampPause { 0.0 1.0 0.0 1.0 }
    set outputActiveDefault {1 0 1 0}
}

set Variables [concat $inputVariables $outputVariables]
set PVs [concat $inputPVs $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 SRrfLimitProbePower -version $CVSRevisionAuthor \
  -overview {This application is intended to limit storage ring rf gap voltage by limiting the probe power.}


set mainStatus "Ready."
APSScrolledStatus .record -parent .userFrame -textVariable mainStatus -width 60  \
        -height 2
       
#APSLabeledOutput .record -parent .userFrame -width 60 \
#  -textVariable ActivityRecord \
#  -label "Last activity: " \
#  -contextHelp "Shows the last action taken and the time it was taken."


set tcl_precision 4

set index 0
set w .userFrame.foutput.frame
set activeVarList {}
set activeNameList {}
foreach outputVar $outputVariables {
    if {[lindex $outputVarGroup $index]==$outputToUseGroup} {
        set outputActiveVar ${outputVar}Active
        set ${outputVar}Active [lindex $outputActiveDefault $index]
        lappend activeVarList ${outputVar}Active
        lappend activeNameList $outputVar
    }
    incr index
}
APSCheckButtonFrame .outputcb -parent .userFrame -label "Control Parameters" \
  -buttonList $activeNameList -variableList $activeVarList \
  -contextHelp "These buttons show and control which process variables are used to reduce the power in the event of an over-limit condition.  If the hardware collector power interlock is functional, then only the rf drive should be active."

set index 0
foreach inputVar $inputVariables {
    APSFrame .f$inputVar -parent .userFrame -label ""
    set w .userFrame.f$inputVar.frame
    set $inputVar 0
    set limitVar ${inputVar}Lim
    set enableVar ${inputVar}Enb
    set $limitVar [lindex $limitValueInitial $index]
    set $enableVar [lindex $enableLimitInitial $index]
    incr index
    APSLabeledOutput .value -parent $w -label "$inputVar value: " \
      -textVariable $inputVar -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


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

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]"
}

set InEvaluateValues 0
proc EvaluateValues {} {
    global limitingOn inputVariables outputVariables outputPVs faultValues
    global InEvaluateValues enableLimit limitValue outputEnables
    global errorCode
    global outputToUseGroup outputVarGroup
    global rampPause outputActive

    foreach inputVar $inputVariables {
        global $inputVar
        if [pv getw $inputVar]!=0 {
            puts stderr "$errorCode"
        }
        set $inputVar [subst \$$inputVar]
    }
    if !$limitingOn return

    set ivIndex 0
    foreach inputVar $inputVariables {
        global ${inputVar}Enb ${inputVar}Lim
        incr ivIndex
        set enabled [subst \$${inputVar}Enb]
        if !$enabled continue
        set value [subst \$$inputVar]
        set limit [subst \$${inputVar}Lim]
        if $limit<$value {
            set ovIndex 0
            SetMainStatus "$inputVar at $value--limit is $limit"
            foreach outputVar $outputVariables {
                if [lindex $outputVarGroup $ovIndex]==$outputToUseGroup {
                    set outputActiveVar ${outputVar}Active
                    global $outputActiveVar
                    set active [subst \$$outputActiveVar]
                    if $active {
                        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
                        SetMainStatus "Done ramping $outputPV [exec date +%H:%M:%S]."
                        update
                    }
                }
                incr ovIndex
            }
            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
}

