#!/bin/sh  
# \
exec oagtclsh "$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)]

APSStandardSetup

set runControlPV OAG011RC

if {[catch {exec cavget -list=${runControlPV}.RUN -printErrors -pend=30} results]} {
   # APSSendEMail -address shang -message "LinacRFFaultLogger failure: Unable to check runControl state: $results" -subject "LinacRFFaultLogger Error"
    exit
}
if {$results == 1} {
    exit
}
if {$results == "?"} {
    exit
}

catch {exec cavput -list=${runControlPV}.CLR=1}

set lastPing 0
set pingTimeout 20
proc PingRunControl {args} {
    global runControlPV lastPing
    set sec [clock seconds]
    if {[expr $lastPing + 2] > $sec} {
        return
    } else {
        set lastPing $sec
    }

    catch {APSRunControlPing} status
    switch $status {
        RUNCONTROL_OK {}
        RUNCONTROL_ABORT {
            return -code error "LinacRFFaultLogger was aborted."
        }
        RUNCONTROL_TIMEOUT -
        RUNCONTROL_ERROR {
            return -code error "Unable to ping runcontrol record of $runControlPV: $status."
        }
    }
}

set monDir /home/helios/oagData/linac/Linac_RF_Faults
proc ProcessData {args} {
    set RF ""
    set type ""
    set dataFile ""
    APSParseArguments {RF type dataFile}

    global monDir
    
    set dataDir $monDir/data
    set tmpRoot /tmp/[APSTmpString]
    set col $type
    if {$type=="arcTrip"} {
        set col ArcTrip
    }
    set outFile $dataDir/${RF}$col.sdds
    if [catch {exec sddsprocess $dataFile -pipe=out -match=col,ControlName=*${type}*StrM \
                 "-match=col,ValueString=*Cleared*,!" -nowarnings \
                 -reprint=col,${col}Comment, \
                 | sddsconvert -pipe -retain=col,ValueString,*Comment \
                 | sddssort -pipe -col=ValueString,decreasing \
                 | sddsconvert -pipe=in -rename=col,ValueString=${col}TimeStamp $tmpRoot.$type } result] {
        puts stderr "Error processing data for $type: $result"
        exit 1
    }
    set rows [exec sdds2stream -rows=bar $tmpRoot.$type]
    if !$rows {
        return
    }
    if ![file exist $outFile] {
        if [catch {exec sddsprocess $tmpRoot.$type $outFile \
                     -redefine=col,Index,i_row,type=long -nowarnings } result] {
            puts stderr "Error defining index column: $result"
        }
    } else {
        if [catch {exec sddsselect $tmpRoot.$type $outFile -match=${col}TimeStamp -invert $tmpRoot.$type.new } result] {
            puts stderr "Error checking if there is new faults: $result"
            exit 1
        }
        set rows [exec sdds2stream -rows=bar $tmpRoot.$type.new]
        if !$rows {
            #no new faults
            return
        }
        if [catch {exec sddscombine $tmpRoot.$type.new $outFile -merge -pipe=out \
                     | sddsprocess -pipe=in $outFile -redefine=col,Index,i_row,type=long } result] {
            puts stderr "Error combine data: $result"
            exit 1
        }
        exec rm $tmpRoot.$type.new
        catch {exec rm ${outFile}~}
    }
    exec rm $tmpRoot.$type
}


if [catch {APSRunControlInit -pv $runControlPV \
	       -description "Linac RF Faults Logger" \
	       -timeout [expr $pingTimeout * 1000] } result] {
    puts stderr "[exec date] Unable to initialize runcontrol Linac RF Faults Logger, the runcontrol record may not be cleared, press the clear button on the medm screen to clear the record and restart: $result"
    exit
}
APSRunControlLogMessage -message "Running" -severity 0
PingRunControl
set RFList {L1 L2 L3 L4 L5 L6}
set typeList {VSWR1 VSWR2 VSWR3 arcTrip}

foreach RF $RFList {
    foreach type $typeList {
        lappend pvList ${RF}:misc${type}Cnt
        lappend varList Count($RF.$type)
    }
}

if [pv linkw $varList $pvList 30] {
    puts stderr "Error linking pvs"
    exit 1
}
PingRunControl
if [pv getw $varList] {
    puts "Error reading pvs"
}

if {0} {
    foreach RF $RFList {
        foreach type $typeList {
            pv umon Count($RF.$type) "LogData -RF $RF -type $type"
        }
    }
}

foreach RF $RFList {
    foreach type $typeList {
        set Count($RF.$type.old) $Count($RF.$type)
    }
}

if {0} {
    set RF L2
    set stamp [clock format [clock seconds] -format %Y-%j-%m%d:%H:%M:%S]
    set dataFile $monDir/data/$RF/${RF}Faults-$stamp
    if [catch {exec sddscasr -save $monDir/${RF}Faults.mon $dataFile -pend=30} result] {
        puts stderr "Error reading $RF fault pvs: $result"
    }
    ProcessData -RF $RF -type VSWR3 -dataFile $dataFile
    exit
}

while {1} {
    PingRunControl
    if [pv getw $varList] {
        puts "Error reading pvs"
    }
    set stamp [clock format [clock seconds] -format %Y-%j-%m%d:%H:%M:%S]
    foreach RF $RFList {
        set changed($RF) 0
        foreach type $typeList {
            if {$Count($RF.$type)!=$Count($RF.$type.old)} {
                set changed($RF) 1
                break
            }
        }
    }
    #added 1 second wait here to wait for the timestamp pvs being updated before save the data
    after 1000
    foreach RF $RFList {
        if $changed($RF) {
            set dataFile $monDir/data/$RF/${RF}Faults-$stamp
            if [catch {exec sddscasr -save $monDir/${RF}Faults.mon $dataFile -pend=30} result] {
                puts stderr "Error reading $RF fault pvs: $result"
            } else {
                foreach type $typeList {
                    if {$Count($RF.$type)!=$Count($RF.$type.old)} {
                        ProcessData -RF $RF -type $type -dataFile $dataFile
                        set Count($RF.$type.old) $Count($RF.$type)
                        PingRunControl
                    }
                }
            }
            PingRunControl
        }
    }
}

exit 0

