#!/usr/bin/perl # # Grabs the latest local weather conditions from the National Weather Service (NWS). # Uses the decoded METAR reports. # # Need to give the 4-character METAR station code on the Command Line. E.g.; # # GrabWeather KLAM # require "ctime.pl"; # # Change to users home directory. We used to dump into /tmp # but using home dir instead avoids multiple users interfering # with one another. (Yeah, we could "unique-ize" the filenames, but # this is easier for now...) # $home = (getpwuid($<))[7]; $ok = chdir() || chdir($home); # # Check to see if .wmWeatherReports exists. # If not, make it and move to it. # if ( !(-e ".wmWeatherReports") ){ mkdir(".wmWeatherReports", 0775); } chdir(".wmWeatherReports"); $StationID = $ARGV[0]; $HTMLFileName = "$StationID.TXT"; $URL = "ftp://weather.noaa.gov/data/observations/metar/decoded/$HTMLFileName"; $DataFileName = "$StationID.dat"; # # I think some of these wget command line options may cause problems # for some people? Dont know why... (Perhaps they have a ~/.wgetrc file # that overrides command line options?). # $GrabCmd = "wget --proxy=off --passive-ftp --tries 0 -q -O $home/.wmWeatherReports/$StationID.TXT $URL"; system "$GrabCmd"; # # Parse HTML File. # $Temp = -999.0; $Chill = -999.0; $DewPnt = -999.0; $Pressure = -999.0; $Hum = -999.0; $Flag = 0; open(TmpFile, "$HTMLFileName"); while (){ chop; if ($Flag == 0) { $StationInfo = $_; }; if ($Flag == 1) { $UpdateTime = $_; }; if ($_ =~ /^Sky conditions:/ ){ $SkyConditions = $_; $SkyConditions =~ s/Sky conditions: (.*)/\1/; } if ($_ =~ /^Temperature:/ ){ $Temp = $_; $Temp =~ s/Temperature:\s*(\-{0,1}[0-9.]{1,}).*/\1/; } if ($_ =~ /^Windchill:/ ){ $Chill = $_; $Chill =~ s/Windchill:\s*(\-{0,1}[0-9.]{1,}).*/\1/; } if ($_ =~ /^Dew Point:/ ){ $DewPnt = $_; $DewPnt =~ s/Dew Point:\s*(\-{0,1}[0-9.]{1,}).*/\1/; } if ($_ =~ /^Pressure \(.*\):/ ){ $Pressure = $_; $Pressure =~ s/Pressure \(.*\):\s*([0-9.]{2,}).*/\1/; } if ($_ =~ /^Relative Humidity:/ ){ $Hum = $_; $Hum =~ s/Relative Humidity:\s*(\d{1,})\%.*/\1/; } if ($_ =~ /^ob: / ){ $CodedMETAR = $_; $CodedMETAR =~ s/ob: (.*)/\1/; } ++$Flag; } close(TmpFile); # # Isolate the Wind groups out of the coded METAR report. # There may be two groups - the normal one and a variability set. # $WindGroup = $CodedMETAR; $WindGroup =~ s/ RMK\s.*$//; $VarWindGroup = $WindGroup; if ($WindGroup =~ /.*\s\w{3}\d{2,3}KT\s\d{3}V\d{3}\s.*/ ) { $VarWindGroup =~ s/.*\s\w{3}\d{2,3}KT\s(\d{3}V\d{3})\s.*/\1/; $VarFlag = 1; } elsif ($WindGroup =~ /.*\s\w{3}\d{2,3}MPS\s\d{3}V\d{3}\s.*/ ) { $VarWindGroup =~ s/.*\s\w{3}\d{2,3}MPS\s(\d{3}V\d{3})\s.*/\1/; $VarFlag = 1; } elsif ($WindGroup =~ /.*\s\w{3}\d{2,3}G\d{2,3}KT\s(\d{2,3}V\d{2,3})\s.*/ ) { $VarWindGroup =~ s/.*\s\w{3}\d{2,3}G\d{2,3}KT\s(\d{2,3}V\d{2,3})\s.*/\1/; $VarFlag = 1; } elsif ($WindGroup =~ /.*\s\w{3}\d{2,3}G\d{2,3}MPS\s(\d{2,3}V\d{2,3})\s.*/ ) { $VarWindGroup =~ s/.*\s\w{3}\d{2,3}G\d{2,3}MPS\s(\d{2,3}V\d{2,3})\s.*/\1/; $VarFlag = 1; } else { $VarWindGroup = ""; $VarFlag = 0; } $Direction1 = $VarWindGroup; $Direction1 =~ s/(\d{3})V\d{3}/\1/; $Direction2 = $VarWindGroup; $Direction2 =~ s/\d{3}V(\d{3})/\1/; $GustFlag = 0; if ($WindGroup =~ /.*\s\w{3}\d{2,3}KT\s.*/ ) { $WindGroup =~ s/.*\s(\w{3}\d{2,3}KT)\s.*/\1/; $Direction = $WindGroup; $Direction =~ s/(\w{3})\d{2,3}KT/\1/; $Speed = $WindGroup; $Speed =~ s/\w{3}(\d{2,3})KT/\1/; } elsif ($WindGroup =~ /.*\s\w{3}\d{2,3}MPS\s.*/ ) { $WindGroup =~ s/.*\s(\w{3}\d{2,3}MPS)\s.*/\1/; $Direction = $WindGroup; $Direction =~ s/(\w{3})\d{2,3}MPS/\1/; $Speed = $WindGroup; $Speed =~ s/\w{3}(\d{2,3})MPS/\1/; $Speed *= 1.942; } elsif ($WindGroup =~ /.*\s\w{3}\d{2,3}G\d{2,3}KT\s.*/ ) { $WindGroup =~ s/.*\s(\w{3}\d{2,3}G\d{2,3}KT)\s.*/\1/; $Direction = $WindGroup; $Direction =~ s/(\w{3})\d{2,3}G\d{2,3}KT/\1/; $Speed1 = $WindGroup; $Speed1 =~ s/\w{3}(\d{2,3})G\d{2,3}KT/\1/; $Speed2 = $WindGroup; $Speed2 =~ s/\w{3}\d{2,3}G(\d{2,3})KT/\1/; $GustFlag = 1; } elsif ($WindGroup =~ /.*\s\w{3}\d{2,3}G\d{2,3}MPS\s.*/ ) { $WindGroup =~ s/.*\s(\w{3}\d{2,3}G\d{2,3}MPS)\s.*/\1/; $Direction = $WindGroup; $Direction =~ s/(\w{3})\d{2,3}G\d{2,3}MPS/\1/; $Speed1 = $WindGroup; $Speed1 =~ s/\w{3}(\d{2,3})G\d{2,3}MPS/\1/; $Speed2 = $WindGroup; $Speed2 =~ s/\w{3}\d{2,3}G(\d{2,3})MPS/\1/; $Speed1 *= 1.942; $Speed2 *= 1.942; $GustFlag = 1; } else { $WindGroup = ""; } # # Get the Time out of the coded Metar Report. # $UniversalTime = $CodedMETAR; if ($UniversalTime =~ /$StationID \d{1,2}\d{2}\d{2}Z/ ){ $UniversalTime =~ s/$StationID (\d{1,2})(\d{2})(\d{2})Z .*/\2:\3/; } else { $UniversalTime = "99:99"; } # # Write out the stuff we need to the Data File. This is the file that will # be read by wmWeather. # if ($Flag > 0){ open(TmpFile, ">$DataFileName"); print TmpFile "$StationInfo\n"; print TmpFile "$UpdateTime\n"; print TmpFile "$SkyConditions\n"; print TmpFile "$UniversalTime\n"; print TmpFile "$Temp\n"; print TmpFile "$DewPnt\n"; print TmpFile "$Chill\n"; print TmpFile "$Pressure\n"; print TmpFile "$Hum\n"; if ($Direction eq "" ){ print TmpFile "-9999\n"; } elsif ($Direction =~ /VRB/ ){ print TmpFile "999\n"; } elsif ($VarFlag) { $Direction += 0; print TmpFile "-$Direction\n"; } else { $Direction += 0; print TmpFile "$Direction\n"; } if ($WindGroup eq "" ) { print TmpFile "-9999\n"; } elsif ($GustFlag) { $AvgSpeed = ($Speed1 + $Speed2)/2.0; $AvgSpeed *= 1.15155; print TmpFile "-$AvgSpeed\n"; } else { $Speed += 0; $Speed *= 1.15155; print TmpFile "$Speed\n"; } close(TmpFile); }