Files
lcdproc/clients/metar/lcdmetar.pl
T
William Ferrell 6dabd0b8f3 Applied patches supplied by Andre' Breiler:
- bugfixes for display != MatrixOrb LCD
	- changes the meaning of output_state
		+ it's now a bitfield where evry bit corresponds to
		  one output
	- protocol change
		output on|off|value
		where on    = all outputs on
		      off   = all outputs off
		      value = output on for all 1 bits
	- changes the behavior for key presses
	  Keypresses are now deliverd to _all_ clients (not only
	  the one with the active screen)
	reason: I have an client which is only active a few seconds after
                an keypress
	- changes the protocol so that a response is sent for every
	  command
	reason: the client needs to communicate with the server with a
                minimal latency
2001-03-22 22:51:49 +00:00

167 lines
3.9 KiB
Perl
Executable File

#!/usr/bin/perl -w
# $Id$
#
# LICENSE:
# GPL - GNU Public License
#
# Brief Description
# =================
#
# lcdmetar.pl is a program to fetch METAR Weather information (e.g.
# temperature) from a nearby (or not) airport using Geo::METAR and the
# LWP modules.
#
# Given an airport site code on the command line, lcdmetar.pl
# fetches the current temperature, wind and clound information,
# and displays it via lcdproc (http://lcdproc.omnipotent.net)
# For fun, here are some example airports:
#
# LA : KLAX
# Dallas : KDFW
# Detroit: KDTW
# Chicago: KMDW
# Graz/Austria (Thalerhof) : LOWG
#
# no warranty - use at your own risc.
# DO NOT PLAN FLIGHTS ETC ON THIS INFORMATION!!!!
#
use IO::Socket;
use Fcntl;
# Get the site code.
my $site_code = shift @ARGV;
die "Usage: $0 <site_code>\n" unless $site_code;
# Get the modules we need.
use Geo::METAR;
use LWP::UserAgent;
# use strict;
# Connect to the server...
$remote = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => "localhost",
PeerPort => "13666",
)
|| die "Cannot connect to LCDproc port\n";
# Make sure our messages get there right away
$remote->autoflush(1);
sleep 1; # Give server plenty of time to notice us...
print $remote "hello\n";
my $lcdconnect = <$remote>;
print $lcdconnect;
# Turn off blocking mode...
fcntl($remote, F_SETFL, O_NONBLOCK);
# Set up some screen widgets...
print $remote "client_set name {Metar}\n";
print $remote "screen_add metar\n";
print $remote "screen_set metar name {Metar}\n";
print $remote "widget_add metar title title\n";
print $remote "widget_set metar title {Weather $site_code}\n";
print $remote "widget_add metar temp string\n";
print $remote "widget_add metar cloud string\n";
print $remote "widget_add metar wind string\n";
# set metar source
my $ua = new LWP::UserAgent;
my $req = new HTTP::Request GET =>
"http://weather.noaa.gov/cgi-bin/mgetmetar.pl?cccc=$site_code";
# fork data collector from socket handling
$kidpid = fork();
# Parent
if ($kidpid) {
while (1==1) {
# read socket
my $lcdconnect = <$remote>;
}
# child
} else
{
# fetch weather information
while (1==1) {
print "Fetching weather information\n";
my $response = $ua->request($req);
if (!$response->is_success) {
print $response->error_as_HTML;
my $err_msg = $response->error_as_HTML;
warn "$err_msg\n\n";
} else {
# Yep, get the data and find the METAR.
my $m = new Geo::METAR;
my $data;
$data = $response->as_string; # grap response
$data =~ s/\n//go; # remove newlines
$data =~ m/($site_code\s\d+Z.*?)</go; # find the METAR string
my $metar = $1; # keep it
# Sanity check
if (length($metar)<10) {
die "METAR is too short! Something went wrong.";
}
# pass the data to the METAR module.
# print("$metar\n");
$m->metar($metar);
# ask for the temperature(s)
my $c_temp = $m->C_TEMP;
my $metartime = $m->TIME;
my $c_dew = $m->C_DEW;
my $f_temp = $m->F_TEMP;
my $wind_dir_eng = $m->WIND_DIR_DEG;
my $wind_mph = $m->WIND_MPH;
my $sky = $m->SKY;
my $time = localtime(time);
print $remote "widget_set metar title {Weather LOWG " . $metartime . "}\n";
print $remote "widget_set metar temp 1 2 {Temp " .$c_temp. "C (" .$c_dew. "C Dew)}\n";
print $remote "widget_set metar wind 1 3 {Wind " .$wind_dir_eng. "G, " .$wind_mph. "mph}\n";
print $remote "widget_set metar cloud 1 4 {Sky " . join(',', @{$m->{sky}}) . "}\n";
# print "The temperature at $site_code is $c_temp C as of $time.\n";
# print "The wind blows to $wind_dir_eng, speed $wind_mph mph\n";
} # end else
# eat all input from LCDd
while(defined($input = <$remote>)) {
if ( $input =~ /^success$/ ) next;
#print $input;
}
print "Sleeping 15 minutes.\n";
sleep 900;
}
}
close($remote);
exit;
__END__