#! /usr/bin/perl use Tk; $os = "Win" if $^O eq "MSWin32"; if( $os eq "Win" ){ require Win32::ODBC; } else { require Pg; } use Math::Trig; use Time::Local; sub Sun { ($lat,$lon,$ctime) = @_; ($year,$month,$day,$hour,$min) = ( $ctime =~ /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/ ); $secs = timegm( 0, $min, $hour, $day, $month-1, $year); @times = gmtime( $secs ); $year = ($secs + 10 * 86400)/ (365.25 * 86400); $day = ($secs % 86400)/ 86400; # print "Year: $year $day\n"; $pi = 3.141592; $drc = $pi/180; $eclip = 23.45 * -cos( $year * 2 * $pi ); $sday = $day + ($lon/360); $sx = -cos( $sday * 2 * $pi ) * cos( $eclip * $drc ); $sy = -sin( $sday * 2 * $pi ) * cos( $eclip * $drc ); $sz = sin( $eclip * $drc ); $ex = cos( $lat * $drc ); $ey = 0; $ez = sin( $lat * $drc ); $tot = $sx * $ex + $sy * $ey + $sz * $ez; $sun = acos( $tot ) / $drc; return 0 if $sun > 90; return 1 if $sun <= 90; } sub exec_select { my ( $sql ) = @_; if( $os eq "Win" ){ $conn->Sql( $sql ); $conn->FetchRow(); return $conn->DataHash(); } else { my $res = $conn->exec( $sql ); my @fields = $res->fetchrow; my $i = 0; undef %output; my %output; foreach ( @fields ){ s/\s+$//; my $name = $res->fname($i); $output{$name} = $_; $i++; } return %output; } } sub Run { # # Get observation # $text->tagConfigure( 'large', -font => '-adobe-times-bold-r-normal-*-*-240-*-*-p-*-iso10646-1' ); $text->tagConfigure( 'medium', -font => '-adobe-times-bold-r-normal-*-*-180-*-*-p-*-iso10646-1' ); $text->tagConfigure( 'small', -font => '-adobe-times-bold-r-normal-*-*-120-*-*-p-*-iso10646-1' ); if( $sitename =~ /\d{5}/ ){ %site = exec_select( "SELECT state,zone,city,sid,lat,lon FROM zip_site WHERE zip = \'$sitename\';" ); } elsif( $sitename =~ /([A-Za-z_.]+),(\w+)/ ){ $site = "$1, $2"; %site = exec_select( "SELECT state,zone,city,sid,lat,lon FROM city_site WHERE city = \'$1\' and state = \'$2\';" ); } else { %site = exec_select( "SELECT state,zone,city,sid,lat,lon FROM city_site WHERE city = \'$sitename\';" ); } if( !$site{sid} ){ $text->delete( "1.0", "end" ); $text->insert( 'end', "Site not found\n", 'medium' ); return; } %obs = exec_select( "SELECT * FROM metar_obs WHERE sid = \'$site{sid}\';" ); $isday = Sun $lat, $lon, $obs{obs_time}; $ctime = substr( $obs{obs_time}, 11, 2 ) . "Z"; $text->delete( "1.0", "end" ); $text->insert( 'end', "Current Conditions\n", 'large' ); $image = $mw->Photo( -file => "$bdir/Sun.gif" ) if $obs{wx_code} eq "SU" && $isday; $image = $mw->Photo( -file => "$bdir/Moon.gif" ) if $obs{wx_code} eq "SU" && ! $isday; $image = $mw->Photo( -file => "$bdir/Rain.gif" ) if $obs{wx_code} eq "RA"; $image = $mw->Photo( -file => "$bdir/Snow.gif" ) if $obs{wx_code} eq "SN"; $image = $mw->Photo( -file => "$bdir/Foggy.gif" ) if $obs{wx_code} eq "FG"; $image = $mw->Photo( -file => "$bdir/Thunder.gif" ) if $obs{wx_code} eq "TS"; $image = $mw->Photo( -file => "$bdir/Clouds.gif" ) if $obs{wx_code} eq "CL"; $image = $mw->Photo( -file => "$bdir/PartlyCloudy.gif" ) if $obs{wx_code} eq "PC" && $isday; $image = $mw->Photo( -file => "$bdir/MoonCloudy.gif" ) if $obs{wx_code} eq "PC" && ! $isday; $imagewin = $text->Label( -image => $image ); $text->windowCreate( 'end', -window => $imagewin ); $text->insert( 'end', " $obs{temp_f} F\n", 'large' ); $text->insert( 'end', "Site: $sitename\nCity: $site{city}, $site{state}\nObservation: $site{sid} at $ctime\n", 'small' ); $text->insert( 'end', "Skies: $obs{skies}\n", 'small' ); $text->insert( 'end', "Weather: $obs{wx_text}\n", 'small' ) if $obs{wx_text}; $text->insert( 'end', "Temperature: $obs{temp_f} F\nDewpoint: $obs{dewpt_f} F\n", 'small' ); $text->insert( 'end', "Wind chill: $obs{wind_chill_f} F\n", 'small' ) if $obs{wind_chill_f} < 30; $text->insert( 'end', "Pressure: $obs{pressure_mb} mb\n", 'small' ); $text->insert( 'end', "Wind dir: $obs{wind_dir} speed: $obs{wind_spd_knt} knt\n", 'small' ); $zone = "$site{state}Z$site{zone}"; %zones = exec_select( "SELECT * FROM zones WHERE id = \'$zone\';" ); $text->insert( 'end', "\nLatest Forecast\n", 'large' ); for( $i = 0; $i < 16; $i++ ){ $key = sprintf "forecast%d", $i; next if $zones{$key} == -1 || $zones{$key} eq ""; %fore = exec_select( "SELECT * FROM zone_forecast WHERE id = \'$zones{$key}\';" ); $image = $mw->Photo( -file => "$bdir/Sun.gif" ) if $fore{weather} eq "SU"; $image = $mw->Photo( -file => "$bdir/Moon.gif" ) if $fore{weather} eq "MO"; $image = $mw->Photo( -file => "$bdir/Rain.gif" ) if $fore{weather} eq "RA"; $image = $mw->Photo( -file => "$bdir/Snow.gif" ) if $fore{weather} eq "SN"; $image = $mw->Photo( -file => "$bdir/Foggy.gif" ) if $fore{weather} eq "FG"; $image = $mw->Photo( -file => "$bdir/Thunder.gif" ) if $fore{weather} eq "TS"; $image = $mw->Photo( -file => "$bdir/Clouds.gif" ) if $fore{weather} eq "CL"; $image = $mw->Photo( -file => "$bdir/PartlyCloudy.gif" ) if $fore{weather} eq "PC"; $image = $mw->Photo( -file => "$bdir/MoonCloudy.gif" ) if $fore{weather} eq "MC"; $imagewin = $text->Label( -image => $image ); $text->windowCreate( 'end', -window => $imagewin ); $text->insert( 'end', "$fore{day} - ", 'medium' ); $text->insert( 'end', "HI: $fore{high_temp} ", 'medium' ) if $fore{high_temp}; $text->insert( 'end', "LO: $fore{low_temp}", 'medium' ) if $fore{low_temp}; $text->insert( 'end', "\n$fore{text}\n", 'small' ); } } ############################ # Main Program ############################ if( $os eq "Win" ){ $bdir = "/wxp/image"; $datasrc = "WxData"; $conn = new Win32::ODBC($datasrc); } else { $bdir = "/home/wxp/image"; $datasrc = "host=penndot dbname=wxdata user=devo password=Edwrt92"; $conn = Pg::connectdb($datasrc); if( $conn->status != PGRES_CONNECTION_OK ){ undef $conn; } } if( !$conn ){ print "Error Connecting to Database\n"; exit( 1 ); } $sitename = "19382"; $mw = MainWindow->new; $mw->title( "ptkForecast (v1.0)" ); $mw->geometry( "+10+10" ); $bar = $mw->Frame->pack( -side => "top", -fill => "x" ); $bar->Button( -text => "Quit", -command => sub { exit } ) ->pack( -side => "right" ); $bar->Button( -text => "Run", -command => \&Run ) ->pack( -side => "right" ); $bar->Label( -text => "Site:" ) ->pack( -side => "left" ); $ent = $bar->Entry( -textvariable => \$sitename, -relief => "sunken", -width => 20 ) ->pack( -side => "left" ); $ent->bind( "", \&Run ); $mainf = $mw->Frame->pack( -side => "top", -fill => "both", -expand => 1 ); $text = $mainf->Scrolled( "Text", -scrollbars => "se", -bg => "white", -width => 80, -height => 25 ) ->pack( -side => "top", -fill => "both", -expand => 1 ); MainLoop;