as argument introducers. in 0.4-pre10, these were changed
from foo to -foo and this broke many clients. This change
should fix that and be backward/forward compatible.
+ Added a noop function to the protocol. This is useful for writing
shell script clients of LCDproc.
+ Changed the shared sock_send_string function to NOT send the
ending NUL ('\0') byte with the string. This was confusing
in Perl clients which saw NUL's as the first character of
each reply. WARNING: The LCDPROC client depended on this
behavior, your client may too. Use the newline instead.
See the code in clients/lcdproc/main.c (look for "switch(buf[i])")
to see one way to handle this. This should allow new clients
to connect to old servers and vice-versa.
+ Messed with include structure in .c files. It should no longer
be necessary to specify ../.. to get to shared code headers.
Also, since we are using automake, the global config.h can be
found with just #include "config.h" as it's location is included
in a -I to the compilers. As a result "make distcheck" now works.
148 lines
3.7 KiB
Perl
Executable File
148 lines
3.7 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";
|
|
|
|
# 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_ENG;
|
|
my $wind_mph = int($m->WIND_MPH);
|
|
my $sky = $m->SKY;
|
|
my $time = localtime(time);
|
|
print $remote "widget_set metar title {Weather $site_code $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}, ${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>)) {
|
|
next if ( $input =~ /^success$/ );
|
|
#print $input;
|
|
}
|
|
print "Sleeping 15 minutes.\n";
|
|
sleep 900;
|
|
}
|
|
|
|
close($remote);
|
|
exit;
|
|
|
|
__END__
|
|
|
|
|