#!/bin/bash #Shell script for downloading the latest 2 h ACE real-time MAG + SWEPAM data files and writing alerts into a RSS XML file. #rssfeed simple Kp estimate alert #get file location and name: thisFile=$(readlink -f $BASH_SOURCE) thisFilePath=$(dirname $(readlink -f $BASH_SOURCE)) thisFileName=$(basename $thisFile) #echo $thisFile $thisFilePath $thisFileName date --utc -d 'now' "+%Y-%m-%d %H:%M:%S $thisFileName" #define file namens: xmlFile=${thisFileName/.sh/.xml} #replace .sh with .xml statusFile="status.txt" archiveFile="alerts.txt" archiveDir="alert_archive" #apPlotFile="/srv/www/htdocs/rssfeeds/ace_ap_plot/ace_realtime_ap_plot.png" apPlotFile="/opt/rh/httpd24/root/var/www/html/rssfeeds/ace_ap_plot/ace_realtime_ap_plot.png" apConversionTableFile="ConversionTablevBzToapB.txt" #define date strings of different format: unixTime=`date -d 'now' '+%s'` #1363274017 dateRssPub=`date --utc -d 'now' '+%a, %d %b %Y %H:%M:%S UT'` #Tue, 19 Feb 2013 16:01:59 UT dateFull=`date --utc -d 'now' '+%Y-%m-%d %H:%M:%S %Z on %A'` #2013-02-19 16:01:56 UTC on Friday dateRssTitle=`date --utc -d 'now' '+%Y-%m-%d %H:%M'` #2013-02-19 16:01 dateStandard=`date --utc -d 'now' '+%Y-%m-%d_%H%M%S'` #2013-02-19_160156 #test if status.txt exists, if not create it: if [ ! -f $thisFilePath"/"$statusFile ]; then echo "Alert status: ? DATE = $dateFull FILE = $thisFile The current user defined minimal alert interval: MIN_INTERVAL = 180 min The current user defined threshold value is: THRESHOLD_AP = 111 The last 2 hour extreme values are: 2H_MAX_B = ? nT 2H_MIN_Bz = ? nT 2H_MAX_V = ? km/s 2H_MIN_VxBz = ? km/s nT 2H_MAX_EST_AP = ? Current alert (0: no alert; 1 alert): ALERT = 0 Alert duration since incidence: DURATION = - Alert occurence: ALERT_START = - Alert occurence in unix time: ALERT_UNIX_START = - " > $thisFilePath"/"$statusFile fi if [ `stat --printf="%s" $thisFilePath"/"$statusFile` -lt 10 ]; then echo "Alert status: ? DATE = $dateFull FILE = $thisFile The current user defined minimal alert interval: MIN_INTERVAL = 180 min The current user defined threshold value is: THRESHOLD_AP = 111 The last 2 hour extreme values are: 2H_MAX_B = ? nT 2H_MIN_Bz = ? nT 2H_MAX_V = ? km/s 2H_MIN_VxBz = ? km/s nT 2H_MAX_EST_AP = ? Current alert (0: no alert; 1 alert): ALERT = 0 Alert duration since incidence: DURATION = - Alert occurence: ALERT_START = - Alert occurence in unix time: ALERT_UNIX_START = - " > $thisFilePath"/"$statusFile fi #test if 'alert_archive' folder exists, if not create it: if [ ! -d $thisFilePath"/"$archiveDir ]; then mkdir -p $thisFilePath"/"$archiveDir; fi #test if alerts archive exists, if not create empty file: if [ ! -f "$thisFilePath/$archiveDir/$archiveFile" ]; then echo "" >> "$thisFilePath/$archiveDir/$archiveFile"; fi #get values from status file: minInterval=`awk '/MIN_INTERVAL / {print $3}' $statusFile` apthres=`awk '/THRESHOLD_AP / {print $3}' $statusFile` echo $minInterval $apthres oldAlertStatus=`awk '/ALERT / {print $3}' $statusFile` echo $oldAlertStatus alertStart=`awk '/ALERT_START / {print $3}' $statusFile` echo $alertStart #load ACE files: wget ftp://ftp.swpc.noaa.gov/pub/lists/ace/ace_mag_1m.txt -q -N wget ftp://ftp.swpc.noaa.gov/pub/lists/ace/ace_swepam_1m.txt -q -N #create combined mag+swepam data files: awk '!/#/ && !/:/ {print}' ace_mag_1m.txt > ace_mag_1m_temp.txt awk '!/#/ && !/:/ {print}' ace_swepam_1m.txt > ace_swepam_1m_temp.txt paste ace_mag_1m_temp.txt ace_swepam_1m_temp.txt > ace_magswepam_1m.txt #get last 2 hour extreme values from data: Bmax=`awk 'BEGIN{max=0} !/#/ && !/:/ {if (max < $11 && $11 != -999.9) {max = $11}} END{print max}' ace_mag_1m.txt` Bzmin=`awk 'BEGIN{min=999} !/#/ && !/:/ {if (min > $10 && $10 != -999.9) {min = $10}} END{print min}' ace_mag_1m.txt` Vmax=`awk 'BEGIN{max=0} !/#/ && !/:/ {if (max < $9 && $9 != -999.9) {max = $9}} END{print max}' ace_swepam_1m.txt` VxBzmin=`awk 'BEGIN{min=9999999} !/#/ && !/:/ {if (min > $10*$22 && ($10 != -999.9 && $22 != -9999.9)) {min = $10*$22}} END{if (min==9999999) {min=0}; print min}' ace_magswepam_1m.txt` echo $Bmax $Bzmin $Vmax $VxBzmin #VxBzmin=-45004.45 ################################## #read conversion table: vBz=$(awk 'BEGIN { printf "%.0f\n", '$VxBzmin' }') cfile=( $( < $apConversionTableFile ) ) columns=15; k=0 for i in ${cfile[*]}; do # if [ $(($k % $columns)) -eq 0 ]; then counts[$(($k / $columns))]=$i; fi # if [ $(($k % $columns)) -eq 1 ]; then xBinPos[$(($k / $columns))]=$i; fi if [ $(($k % $columns)) -eq 2 ]; then xBin[$(($k / $columns))]=$i; fi if [ $(($k % $columns)) -eq 5 ]; then apMixed[$(($k / $columns))]=$i; fi if [ $(($k % $columns)) -eq 9 ]; then ap1sigmaMinMix[$(($k / $columns))]=$i; fi if [ $(($k % $columns)) -eq 10 ]; then ap1sigmaMaxMix[$(($k / $columns))]=$i; fi if [ $(($k % $columns)) -eq 11 ]; then ap2sigmaMinMix[$(($k / $columns))]=$i; fi if [ $(($k % $columns)) -eq 12 ]; then ap2sigmaMaxMix[$(($k / $columns))]=$i; fi # if [ $(($k % $columns)) -eq 13 ]; then ap3sigmaMinMix[$(($k / $columns))]=$i; fi # if [ $(($k % $columns)) -eq 14 ]; then ap3sigmaMaxMix[$(($k / $columns))]=$i; fi k=$(($k+1)) done #convert vBz to ap: for (( i=0; i<${#xBin[*]}-1; i++ )); do if [ ${xBin[$i]} -le $vBz ] && [ $vBz -lt ${xBin[$i+1]} ]; then ap=${apMixed[$i]}; ap1sigmaMin=${ap1sigmaMinMix[$i]}; ap1sigmaMax=${ap1sigmaMaxMix[$i]}; ap2sigmaMin=${ap2sigmaMinMix[$i]}; ap2sigmaMax=${ap2sigmaMaxMix[$i]}; # ap3sigmaMin=${ap3sigmaMinMix[$i]}; # ap3sigmaMax=${ap3sigmaMaxMix[$i]}; fi done if [ ${xBin[${#xBin[*]}-1]} -le $vBz ]; then ap=${apMixed[${#xBin[*]}-1]}; ap1sigmaMin=${ap1sigmaMinMix[${#xBin[*]}-1]}; ap1sigmaMax=${ap1sigmaMaxMix[${#xBin[*]}-1]}; ap2sigmaMin=${ap2sigmaMinMix[${#xBin[*]}-1]}; ap2sigmaMax=${ap2sigmaMaxMix[${#xBin[*]}-1]}; # ap3sigmaMin=${ap3sigmaMinMix[${#xBin[*]}-1]}; # ap3sigmaMax=${ap3sigmaMaxMix[${#xBin[*]}-1]}; fi #round ap to integer: ap=$(awk 'BEGIN { printf "%.0f\n", '$ap' }') echo $vBz $ap $ap1sigmaMin $ap1sigmaMax $ap2sigmaMin $ap2sigmaMax # $ap3sigmaMin $ap3sigmaMax #set ap&Kp arrays: declare -a apArray=(0 2 3 4 5 6 7 9 12 15 18 22 27 32 39 48 56 67 80 94 111 132 154 179 207 236 300 400) declare -a kpArray=(0 0+ 1- 1 1+ 2- 2 2+ 3- 3 3+ 4- 4 4+ 5- 5 5+ 6- 6 6+ 7- 7 7+ 8- 8 8+ 9- 9) declare -a kp3Array=(0 0.3 0.7 1 1.3 1.7 2 2.3 2.7 3 3.3 3.7 4 4.3 4.7 5 5.3 5.7 6 6.3 6.7 7 7.3 7.7 8 8.3 8.7 9) #convert apthres to Kpthres: for i in {0..26}; do if [ ${apArray[$i]} -le $apthres ] && [ $apthres -lt ${apArray[$i+1]} ]; then kpthres=${kpArray[$i]}; fi done if [ $apthres -gt 400 ]; then kpthres=9; fi #convert ap to Kp and kp3: for i in {0..26}; do if [ ${apArray[$i]} -le $ap ] && [ $ap -lt ${apArray[$i+1]} ]; then kp=${kpArray[$i]}; kp3=${kp3Array[$i]}; fi done if [ $ap -ge 400 ]; then kp=9; kp3=9; fi #round kp3 to integer: kpInt=$(awk 'BEGIN { printf "%.0f\n", '$kp3' }') echo $ap $kp $kpInt $kp3 ############################## #test ap threshold and set new alert: newAlertStatus=$(echo $ap $apthres | awk '{if ($1 > $2) {print 1} else {print 0}}') echo $newAlertStatus #set DATE in status file: echo "`sed "s/\(DATE = \).*/\1$dateFull/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile #set 2HMAX values in status file: echo "`sed "s/\(2H_MAX_B = \).*\( nT\)/\1$Bmax\2/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile echo "`sed "s/\(2H_MIN_Bz = \).*\( nT\)/\1$Bzmin\2/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile echo "`sed "s/\(2H_MAX_V = \).*\( km\/s\)/\1$Vmax\2/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile echo "`sed "s/\(2H_MIN_VxBz = \).*\( km\/s nT\)/\1$VxBzmin\2/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile echo "`sed "s/\(2H_MAX_EST_AP = \).*/\1$ap/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile #set 'ALERT' in status file to 1: echo "`sed "s/\(ALERT = \).*/\1$newAlertStatus/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile #test ap alert conditions: updatePlot=0 ongoingMessage=0 if [ $oldAlertStatus -eq 0 ]; then if [ $newAlertStatus -eq 0 ]; then #0 -> 0: no alert alertStatusName="No alert" else #0 -> 1: new alert alertStatusName="New alert" updatePlot=1 #new plot #set ALERT_START (alert occurence time) and DURATION in status file: echo "`sed "s/\(ALERT_START = \).*/\1$dateStandard/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile echo "`sed "s/\(ALERT_UNIX_START = \).*/\1$unixTime/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile echo "`sed 's/\(DURATION = \).*/\10 min/' $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile fi else if [ $newAlertStatus -eq 0 ]; then #1 -> 0: De-Alert alertStatusName="De-Alert" updatePlot=1 #new plot #set ALERT_START (alert occurence time) and DURATION in status file: echo "`sed "s/\(ALERT_START = \).*/\1-/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile echo "`sed "s/\(ALERT_UNIX_START = \).*/\1-/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile echo "`sed 's/\(DURATION = \).*/\1-/' $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile else #1 -> 1: ongoing alert alertStatusName="Ongoing alert" #updatePlot=2 #overwrite plot #get unix time from status file: unixStartTime=`awk '/ALERT_UNIX_START / {print $3}' "$thisFilePath/$statusFile"` #compute time since last alert: duration=$(expr $(expr $unixTime - $unixStartTime) / 60) echo $duration #set DURATION in status file: echo "`sed "s/\(DURATION = \).*/\1$duration min/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile #test duration: if [ $duration -gt $minInterval ]; then ongoingMessage=1 updatePlot=1 #new plot echo "`sed "s/\(ALERT_UNIX_START = \).*/\1$unixTime/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile fi fi fi #set alert status in status file: echo "`sed "s/\(Alert status: \).*/\1$alertStatusName/" $thisFilePath"/"$statusFile`" > $thisFilePath"/"$statusFile #set alert archive text: archiveAlert="L1 Kp estimate - $alertStatusName $dateFull $thisFile Kp = $kp (Kp > $kpthres) Current alert (0: no alert; 1 alert): ALERT = $newAlertStatus " #define position of rssfeed *.xml-File: pageName="http:\/\/www.affects-fp7.eu" #for RSS item rssfeedDir="rssfeeds\/rssfeed_kp" #for RSS item #set new RSS alert item text: rssitem=""'\n'"\ "'\n'"\ $dateRssTitle L1 Kp estimate - $alertStatusName<\/title>"'\n'"\ <link>$pageName\/$rssfeedDir\/$archiveDir\/$dateStandard.png<\/link>"'\n'"\ <description>Last 2 hour extreme values: Kp = $kp. With current threshold value: kp \> $kpthres.<\/description>"'\n'"\ <pubDate>$dateRssPub<\/pubDate>"'\n'"\ <source url=\"$pageName\">L1 Kp estimate Alert<\/source>"'\n'"\ <guid>$pageName#kp$unixTime<\/guid>"'\n'"\ <\/item>" #write alerts to archive file and RSS file if [ "$alertStatusName" == "New alert" -o "$alertStatusName" == "De-Alert" ]; then #add alert to alerts.txt archive file: echo "$archiveAlert" >> "$thisFilePath/$archiveDir/$archiveFile" #write new RSS alert item: echo "`sed "s/ <!--insert the new item here - do not delete - marker for bash script-->/&$rssitem/" $xmlFile`" > $xmlFile echo "`sed "s/\( <lastBuildDate>\).*\(<\/lastBuildDate>\)/\1$dateRssPub\2/" $xmlFile`" > $xmlFile fi if [ "$alertStatusName" == "Ongoing alert" -a "$ongoingMessage" -eq 1 ]; then #add alert to alerts.txt archive file: echo "$archiveAlert" >> "$thisFilePath/$archiveDir/$archiveFile" #write new RSS alert item: echo "`sed "s/ <!--insert the new item here - do not delete - marker for bash script-->/&$rssitem/" $xmlFile`" > $xmlFile echo "`sed "s/\( <lastBuildDate>\).*\(<\/lastBuildDate>\)/\1$dateRssPub\2/" $xmlFile`" > $xmlFile fi #update pubDate value: echo "`sed "s/\( <pubDate>\).*\(<\/pubDate><!--update pubDate - do not delete - marker for bash script-->\)/\1$dateRssPub\2/" $xmlFile`" > $xmlFile #archive real-time plot: if [ $updatePlot -eq 1 ]; then #archive new plot cp $apPlotFile "$thisFilePath/$archiveDir/$dateStandard.png" fi if [ $updatePlot -eq 2 ]; then #update plot cp $apPlotFile "$thisFilePath/$archiveDir/$alertStart.png" fi date --utc -d 'now' "+%Y-%m-%d %H:%M:%S $thisFileName" #write to log file: #echo "`date --utc -d 'now' '+%Y-%m-%d %H:%M:%S %Z on %A '`$thisFile" >> $thisFilePath"/log.txt"