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

#
# $Log: SRDACMonitor,v $
# Revision 1.5 2023/06/05 20:34:04 lobach
# Changes for APS-U
#
# Revision 1.4  1999/09/16 14:03:33  borland
# sddsmonitor job now runs for 1e4 hours by default.
#
# Revision 1.3  1998/10/29 14:36:02  borland
# Added context help in several places.
#
# Revision 1.2  1998/10/28 18:59:40  borland
# Changed location of monitor input file
#
# Revision 1.1  1998/10/28 18:40:36  borland
# Runs in a loop to check DAC-CurrentAO for all SR PS.  Alerts the user
# if a deviation larger than a specified limit occurs.
#
#

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.5 $ \$Author: lobach $"

APSApplication . -name SRDACMonitor -version $CVSRevisionAuthor 
set tcl_precision 15
set inputDir /home/helios/oagData/sr/powerSupplies/DACMonitor

proc SetMainStatus {text} {
    global mainStatus
    set mainStatus "[clock format [clock seconds]]: $text"
    update
}
proc SetDataStatus {text} {
    global dataStatus
    set dataStatus "[clock format [clock seconds]]: $text"
    update
}


SetMainStatus "Working..."
APSScrolledStatus .status -parent .userFrame -textVariable mainStatus -width 80 \
        -withButtons 1 -lineLimit 1000 -height 8 -label "Status"
set dataStatus " "
APSScrolledStatus .status1 -parent .userFrame -textVariable dataStatus -width 80 \
        -withButtons 1 -lineLimit 1000 -height 30 -label "Problem log"
update

set feedbackConfigFile /home/helios/FEEDBACK/op/ResponseMatrices/srfb-default.config
set slowCorrConfigFile(x) /home/helios/oagData/sr/orbitControllaw/lattices/default/h.default/config
set slowCorrConfigFile(y) /home/helios/oagData/sr/orbitControllaw/lattices/default/v.default/config

set tolerance 0.01
APSLabeledEntry .toler -parent .userFrame -label "Tolerance (A): " \
    -textVariable tolerance -contextHelp \
    "Tolerance on DAC-CurrentAO.  Only power supplies with errors larger than the tolerance will be displayed."

set excludeRTFB 0
set excludeOC 0
APSCheckButtonFrame .exclude -parent .userFrame -label "Exclude power supplies: " \
    -orientation horizontal -buttonList {"In RT feedback" "In orbit correction"} \
    -variableList {excludeRTFB excludeOC} \
    -contextHelp "Use these buttons to exclude certain power supplies that are expected to change frequently.  If these supplies are not excluded, you will get a large number of misleading reports of problems.  However, if RT feedback or orbit correction are not in use, you should release the exclusion."

APSButton .run -parent .userFrame -command RunMonitor \
  -text Run -contextHelp "Runs monitoring of DACs and CurrentAOs.  May be stopped using the Stop button.  Running this application only monitors the system and will not change anything."
APSButton .abort -parent .userFrame -command "bell; set abortMonitor 1" \
  -text Stop -contextHelp "Stops monitoring of DACs and CurrentAOs.  May be restarted using the Run button."

APSDisableButton .userFrame.abort.button

set abortMonitor 0
set ID [APSUniqueName SRDAC]
set apsSlaveMonProcFid$ID ""
set apsSlaveMonProcFlag$ID 0


proc RunMonitor {} {
    global abortMonitor ID tolerance feedbackConfigFile
    global apsSlaveMonProcFid$ID apsSlaveMonProcFlag$ID inputDir
    global excludeRTFB excludeOC slowCorrConfigFile
    SetMainStatus "Running..."

    set abortMonitor 0
    APSEnableButton .userFrame.abort.button
    APSDisableButton .userFrame.run.button

    while 1 {
        if [string length [set apsSlaveMonProcFid$ID]] {
            if [catch {APSStopSddsmonitorSlave -ID $ID} result] {
                SetMainStatus "$result"
            }
            set apsSlaveMonProcFid$ID ""
        }

        SetMainStatus "Starting subprocess..."
        set snapshot /tmp/[APSTmpString]
        if [catch {APSStartSddsmonitorSlave -ID $ID \
                     -sddsmonitorOptions "-time=1e4,h $inputDir/SR-DAC+CurrentAO+Status.mon $snapshot -generations=rowlimit=1,digits=5"} \
              result] {
            SetMainStatus "$result"
        }

        set generation 0
        set dataFile ""
        set restart 0
        while {!$restart} {
            set excludeRTFB1 $excludeRTFB
            set excludeOC1 $excludeOC
            if $abortMonitor {
                catch {APSStopSddsmonitorSlave -ID $ID}
                catch {eval file delete [glob -nocomplain ${snapshot}*]}
                APSDisableButton .userFrame.abort.button
                APSEnableButton .userFrame.run.button
                SetMainStatus "Aborted."
                return
            }

            incr generation
            set dataFile $snapshot-[format %05ld $generation]
            SetMainStatus "Taking data..."
            if [catch {APSSddsMonitorSlaveTakePoint -ID $ID} result] {
                SetMainStatus "$result"
            }
            if $abortMonitor continue
            SetMainStatus "Processing..."

            set RTFBCmd cat
            if $excludeRTFB1 {
                if [catch {exec sddsprocess $feedbackConfigFile $dataFile.fb \
                             -nowarning -match=parameter,NameType=CorrectorNames \
                             -filter=column,Flag,1,1} result] {
                    SetMainStatus "Processing error: $result"
                    bell
                    continue
                }
                set RTFBCmd "sddsselect -invert -pipe -match=PSName=Name $dataFile.fb"
            }
            if $abortMonitor continue

            set OCCmd cat
            if $excludeOC1 {
                if [catch {exec sddscombine $slowCorrConfigFile(x) $slowCorrConfigFile(y) -pipe=out \
                             | sddsprocess -pipe -nowarning -match=parameter,NameType=CorrectorNames \
                             -filter=column,Flag,1,1 \
                             | sddscombine -merge -pipe=in $dataFile.oc} result] {
                    SetMainStatus "Processing error: $result"
                    bell
                    continue
                }
                set OCCmd "sddsselect -invert -pipe -match=PSName=Name $dataFile.oc"
            }
            if $abortMonitor continue

            if ![file exists $dataFile] {
                set try 10
                while {$try} {
                    if [file exists $dataFile] break
                    after 500
                    update
                    incr try -1
                }
                if ![file exists $dataFile] {
                    bell 
                    SetMainStatus "File not found: $dataFile"
                    SetMainStatus "Restarting sddsmonitor."
                    set restart 1
                    continue
                }
            } 

            if [catch {eval exec sddscollect $dataFile -pipe=out \
                         -collect=suffix=:DacCurrentM,column=DAC \
                         -collect=suffix=:SetCurrentM,column=Setpoint \
                         -collect=suffix=:FaultStatusM,column=Status \
                         | sddsconvert -pipe -rename=column,Rootname=PSName \
                         | $RTFBCmd \
                         | $OCCmd \
                         | sddsprocess -pipe -nowarning -filter=column,Status,0,0 \
                         {"-define=column,Error,DAC Setpoint - abs"} \
                         -filter=column,Error,0,$tolerance,! \
                         | sddssort -pipe -column=Error,decr \
                         | tee $dataFile.proc \
                         | sdds2stream -rows -pipe} result] {
                SetMainStatus "Processing error: $result"
                bell
                catch {eval file delete [glob -nocomplain ${dataFile}*]}
                continue
            }
            if [expr [lindex [split $result] 0]>0] {
                # 1 or more rows in result file
                bell
                if [catch {exec sdds2stream -column=PSName $dataFile.proc} result] {
                    SetMainStatus "Processing error: $result"
                    catch {eval file delete [glob -nocomplain ${dataFile}*]}
                    bell
                    continue
                }
                bell
                SetDataStatus "Out of tolerance:\n[join $result {, }]"
                bell
            }
            catch {eval file delete [glob -nocomplain ${dataFile}*]}
        }
    }
}

dp_atexit append AbortMonitor
SetMainStatus "Ready."
