Commit 0c81e0c8 authored by Philipp's avatar Philipp

initial import

parents
# IPWEGET
Script for reading data from ELVs IPWE WeatherStation and posting them on
WeatherUnderground, a generic URL or write them to a WeatherOffice
compatible SQL database
CREATE TABLE IF NOT EXISTS `sensor0` (
`stamp` int(11) NOT NULL,
`sensoraddress` int(11) NOT NULL,
`sensortype` varchar(16) NOT NULL,
`sensordesc` varchar(255) NOT NULL,
`sensortemp` double NOT NULL,
`sensorhum` double NOT NULL,
`sensorwind` double NOT NULL,
`sensorrain` double NOT NULL,
PRIMARY KEY (`stamp`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `sensor1` (
`stamp` int(11) NOT NULL,
`sensoraddress` int(11) NOT NULL,
`sensortype` varchar(16) NOT NULL,
`sensordesc` varchar(255) NOT NULL,
`sensortemp` double NOT NULL,
`sensorhum` double NOT NULL,
`sensorwind` double NOT NULL,
`sensorrain` double NOT NULL,
PRIMARY KEY (`stamp`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `sensor2` (
`stamp` int(11) NOT NULL,
`sensoraddress` int(11) NOT NULL,
`sensortype` varchar(16) NOT NULL,
`sensordesc` varchar(255) NOT NULL,
`sensortemp` double NOT NULL,
`sensorhum` double NOT NULL,
`sensorwind` double NOT NULL,
`sensorrain` double NOT NULL,
PRIMARY KEY (`stamp`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `sensor3` (
`stamp` int(11) NOT NULL,
`sensoraddress` int(11) NOT NULL,
`sensortype` varchar(16) NOT NULL,
`sensordesc` varchar(255) NOT NULL,
`sensortemp` double NOT NULL,
`sensorhum` double NOT NULL,
`sensorwind` double NOT NULL,
`sensorrain` double NOT NULL,
PRIMARY KEY (`stamp`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `sensor4` (
`stamp` int(11) NOT NULL,
`sensoraddress` int(11) NOT NULL,
`sensortype` varchar(16) NOT NULL,
`sensordesc` varchar(255) NOT NULL,
`sensortemp` double NOT NULL,
`sensorhum` double NOT NULL,
`sensorwind` double NOT NULL,
`sensorrain` double NOT NULL,
PRIMARY KEY (`stamp`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `sensor5` (
`stamp` int(11) NOT NULL,
`sensoraddress` int(11) NOT NULL,
`sensortype` varchar(16) NOT NULL,
`sensordesc` varchar(255) NOT NULL,
`sensortemp` double NOT NULL,
`sensorhum` double NOT NULL,
`sensorwind` double NOT NULL,
`sensorrain` double NOT NULL,
PRIMARY KEY (`stamp`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `sensor6` (
`stamp` int(11) NOT NULL,
`sensoraddress` int(11) NOT NULL,
`sensortype` varchar(16) NOT NULL,
`sensordesc` varchar(255) NOT NULL,
`sensortemp` double NOT NULL,
`sensorhum` double NOT NULL,
`sensorwind` double NOT NULL,
`sensorrain` double NOT NULL,
PRIMARY KEY (`stamp`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `sensor7` (
`stamp` int(11) NOT NULL,
`sensoraddress` int(11) NOT NULL,
`sensortype` varchar(16) NOT NULL,
`sensordesc` varchar(255) NOT NULL,
`sensortemp` double NOT NULL,
`sensorhum` double NOT NULL,
`sensorwind` double NOT NULL,
`sensorrain` double NOT NULL,
PRIMARY KEY (`stamp`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `sensor8` (
`stamp` int(11) NOT NULL,
`sensoraddress` int(11) NOT NULL,
`sensortype` varchar(16) NOT NULL,
`sensordesc` varchar(255) NOT NULL,
`sensortemp` double NOT NULL,
`sensorhum` double NOT NULL,
`sensorwind` double NOT NULL,
`sensorrain` double NOT NULL,
PRIMARY KEY (`stamp`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
#!/usr/bin/perl
our $VERSION = "0.1";
use strict;
use warnings;
use utf8;
use POSIX qw(strftime);
use Getopt::Long;
use XML::Simple;
use Data::Dumper;
use HTML::TableExtract;
use Math::Round qw(nearest);
use DBI;
use URI::Escape;
use LWP::UserAgent;
use HTTP::Request::Common;
use Digest::MD5;
sub trim {
my ( $res ) = @_;
$res =~ s/^\s+|\s+$//gx;
return $res;
}
sub strip {
my ( $res ) = @_;
$res =~ s/^([^\ ]+) .*$/$1/gx;
return $res;
}
sub weget {
my ( $dest ) = @_;
my $agent = LWP::UserAgent->new(env_proxy => 1,keep_alive => 1, timeout => 60, agent => 'ipwe2xml' );
my $response = $agent->get( "$dest" );
if ( $response->is_success ) {
return $response->decoded_content;
} else {
return $response->status_line;
}
}
sub we2arr {
my ( $html ) = @_;
my $te;
my $name;
my %sensors;
$te = HTML::TableExtract->new( headers => [qw(Sensortyp Adresse Beschreibung Temperatur Luftfeuchtigkeit Windgeschwindigkeit Regenmenge)] );
$te->parse( $html );
foreach my $ts ($te->tables) {
foreach my $row ( $ts->rows ) {
if ( trim( @$row[0] ) ) {
if ( strip( trim( @$row[1] ) ) eq '' ) { @$row[1] = 8; }
$name = trim( @$row[2] );
$sensors{"$name"}{'address'} = strip( trim( @$row[1] ) );
$sensors{"$name"}{'type'} = strip( trim( @$row[0] ) );
if ( trim( @$row[3] ) ) { $sensors{"$name"}{'temp'} = strip( trim( @$row[3] ) ); }
if ( trim( @$row[4] ) ) { $sensors{"$name"}{'hum'} = strip( trim( @$row[4] ) ); }
if ( trim( @$row[5] ) ) { $sensors{"$name"}{'wind'} = nearest( '0.1', strip( trim( @$row[5] ) )*1000/3600 ); }
if ( trim( @$row[6] ) ) { $sensors{"$name"}{'rain'} = strip( trim( @$row[6] ) ); }
}
}
}
return %sensors;
}
sub arr2wunder {
my ( $id, $pass, $wunder_temp, $wunder_hum, $wunder_wind, $wunder_rain, $wunder_tempin, $wunder_humin, $wunder_temp2, $wunder_temp3, $wunder_temp4, %arr ) = @_;
my $agent;
my $response;
my $url = "http://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?ID=$id&PASSWORD=$pass";
$url .= "&dateutc=". strftime("%Y-%m-%d+%H:%M:%S", gmtime);
if ( defined( $wunder_wind ) ) {
if ( $arr{$wunder_wind}{'wind'} ) { $url .= "&windspeedmph=". nearest( '0.01', $arr{$wunder_wind}{'wind'}*0.621371192 ); }
}
if ( defined( $wunder_hum ) ) {
if ( $arr{$wunder_hum}{'hum'} ) { $url .= "&humidity=". $arr{$wunder_hum}{'hum'}; }
}
if ( defined( $wunder_temp2 ) ) {
if ( $arr{$wunder_temp2}{'temp'} ) { $url .= "&temp2f=". nearest( '0.01', (($arr{$wunder_temp2}{'temp'}*9)/5)+32 ); }
}
if ( defined( $wunder_temp ) ) {
if ( $arr{$wunder_temp}{'temp'} ) { $url .= "&tempf=". nearest( '0.01', (($arr{$wunder_temp}{'temp'}*9)/5)+32 ); }
}
if ( defined( $wunder_rain ) ) {
if ( $arr{$wunder_rain}{'rain'} ) { $url .= "&dailyrainin=". nearest( '0.01', $arr{$wunder_rain}{'rain'}*0.0393700787 ); }
}
if ( defined( $wunder_tempin ) ) {
if ( $arr{$wunder_tempin}{'temp'} ) { $url .= "&indoortempf=". nearest( '0.01', (($arr{$wunder_tempin}{'temp'}*9)/5)+32 ); }
}
if ( defined( $wunder_humin ) ) {
if ( $arr{$wunder_humin}{'hum'} ) { $url .= "&indoorhumidity=". $arr{$wunder_humin}{'hum'}; }
}
$url .= "&softwaretype=ipweget%20$VERSION";
$url .= "&action=updateraw";
$agent = LWP::UserAgent->new(env_proxy => 1,keep_alive => 1, timeout => 60, agent => "ipweget/$VERSION" );
$response = $agent->get( "$url" );
if ( $response->is_success ) {
return 1;
} else {
print STDERR "Weather Underground Error: ";
print STDERR "$response->status_line\n";
return 0;
}
}
sub arr2sql {
my ( $host, $db, $user, $pass, %arr ) = @_;
my $dsn = "DBI:mysql:database=$db;host=$host";
my $mysql = DBI->connect($dsn, "$user", "$pass");
my $query;
foreach my $k ( keys %arr ) {
$query = "INSERT INTO sensor$arr{$k}{'address'} ( stamp, sensoraddress, sensortype, sensordesc";
if ( $arr{$k}{'temp'} ) { $query .= ", sensortemp"; }
if ( $arr{$k}{'hum'} ) { $query .= ", sensorhum"; }
if ( $arr{$k}{'wind'} ) { $query .= ", sensorwind"; }
if ( $arr{$k}{'rain'} ) { $query .= ", sensorrain"; }
$query .= " ) VALUES ( '". time() ."', '". $arr{$k}{'address'} ."', '". $arr{$k}{'type'} ."', '". $k ."'";
if ( $arr{$k}{'temp'} ) { $query .= ", '". $arr{$k}{'temp'} ."'"; }
if ( $arr{$k}{'hum'} ) { $query .= ", '". $arr{$k}{'hum'} ."'"; }
if ( $arr{$k}{'wind'} ) { $query .= ", '". $arr{$k}{'wind'} ."'"; }
if ( $arr{$k}{'rain'} ) { $query .= ", '". $arr{$k}{'rain'} ."'"; }
$query .= " );";
$mysql->do($query) or print STDERR "MySQL Error: $mysql->errstr\n";
}
$mysql->disconnect();
return 1;
}
sub arr2http {
my ( $url, $pass, %arr ) = @_;
my %data;
my $agent;
my $response;
my $md5 = Digest::MD5->new;
$md5->add("$pass");
$data{"stamp"} = time();
$data{"pass"} = $md5->hexdigest;
foreach my $k ( keys %arr ) {
$data{"s$arr{$k}{'address'}address"} = uri_escape($arr{$k}{'address'});
$data{"s$arr{$k}{'address'}type"} = uri_escape($arr{$k}{'type'});
$data{"s$arr{$k}{'address'}desc"} = uri_escape($k);
if ( $arr{$k}{'temp'} ) { $data{"s$arr{$k}{'address'}temp"} = uri_escape($arr{$k}{'temp'}); }
if ( $arr{$k}{'hum'} ) { $data {"s$arr{$k}{'address'}hum"} = uri_escape($arr{$k}{'hum'}); }
if ( $arr{$k}{'wind'} ) { $data{"s$arr{$k}{'address'}wind"} = uri_escape($arr{$k}{'wind'}); }
if ( $arr{$k}{'rain'} ) { $data{"s$arr{$k}{'address'}rain"} = uri_escape($arr{$k}{'rain'}); }
}
$agent = LWP::UserAgent->new(env_proxy => 1,keep_alive => 1, timeout => 60, agent => "ipweget/$VERSION" );
$response = $agent->post( "$url", Content_Type => 'form-data', Content => \%data );
if ( $response->is_success ) {
return 1;
} else {
print STDERR "HTTP POST Error: ";
print STDERR "$response->status_line\n";
return 0;
}
}
sub helptext {
print "ipweget v$VERSION parses IPWE weatherstation websites and generates several outputs\n";
print "(C)opyright 2011 by P. Giebel (stimpyrama.org)\n";
print "\n";
print "Usage: $0 [options] <IP-ADRESS-OF-YOUR-IPWE>\n";
print "Options: -l | --long - one element per attribute\n";
print " -h | --help - this help text\n";
print " -q | --quiet - be quiet - no xml output\n";
print " --mysql-host <ip> - mysql hostname or ip\n";
print " --mysql-db <db> - mysql database\n";
print " --mysql-user <user> - mysql username\n";
print " --mysql-pass <pass> - mysql password\n";
print " --http <url> - http post url\n\n";
print "Examples: $0 192.168.1.10\n";
print " $0 --http http://example.com/post.php 192.168.1.10\n";
print " $0 --mysel-host localhost --mysql-db weather \\\n";
print " --mysql-user weather --mysql-pass secret 192.168.1.10\n";
print " $0 -q --http http://example.com/post.php 192.168.1.10\n";
print " --mysel-host localhost --mysql-db weather \\\n";
print " --mysql-user weather --mysql-pass secret 192.168.1.10\n";
print "\n";
return 0;
}
my $long = 0;
my $help = 0;
my $mysql_host;
my $mysql_db;
my $mysql_user;
my $mysql_pass;
my $wunder_id;
my $wunder_pass;
my $wunder_temp;
my $wunder_hum;
my $wunder_wind;
my $wunder_rain;
my $wunder_tempin;
my $wunder_humin;
my $wunder_temp2;
my $wunder_temp3;
my $wunder_temp4;
my $http;
my $http_pass;
my $quiet;
my $xmllong;
my %sensors;
my $xml;
if ( !$ARGV[0] ) {
helptext();
exit 2;
}
Getopt::Long::Configure('bundling','no_getopt_compat');
GetOptions( 'mysql-host=s' => \$mysql_host,
'mysql-db=s' => \$mysql_db,
'mysql-user=s' => \$mysql_user,
'mysql-pass=s' => \$mysql_pass,
'wunder-id=s' => \$wunder_id,
'wunder-pass=s' => \$wunder_pass,
'wunder-temp=s' => \$wunder_temp,
'wunder-hum=s' => \$wunder_hum,
'wunder-wind=s' => \$wunder_wind,
'wunder-rain=s' => \$wunder_rain,
'wunder-tempin=s' => \$wunder_tempin,
'wunder-humin=s' => \$wunder_humin,
'wunder-temp2=s' => \$wunder_temp2,
'wunder-temp3=s' => \$wunder_temp3,
'wunder-temp4=s' => \$wunder_temp4,
'http=s' => \$http,
'http-pass=s' => \$http_pass,
'q|quiet' => \$quiet,
'l|long' => \$xmllong,
'h|help' => \$help, );
if ( $help == 1 ) {
helptext();
exit 1;
}
%sensors = we2arr( weget( "http://$ARGV[0]/ipwe.cgi" ) );
if ( ( defined( $mysql_host ) ) && ( defined( $mysql_db ) ) && ( defined( $mysql_user ) ) && ( defined( $mysql_pass ) ) ) {
arr2sql( $mysql_host, $mysql_db, $mysql_user, $mysql_pass, %sensors );
}
if ( defined( $http ) ) {
arr2http( $http, $http_pass, %sensors );
}
if ( ( defined( $wunder_id ) ) && ( defined( $wunder_pass ) ) && ( ( defined( $wunder_temp ) ) || ( defined( $wunder_hum ) ) || ( defined( $wunder_wind ) ) || ( defined( $wunder_rain ) ) ) ) {
arr2wunder( $wunder_id, $wunder_pass, $wunder_temp, $wunder_hum, $wunder_wind, $wunder_rain, $wunder_tempin, $wunder_humin, $wunder_temp2, $wunder_temp3, $wunder_temp4, %sensors );
}
if ( !defined( $quiet ) ) {
$xml = XML::Simple->new(RootName => 'sensors', KeyAttr => { item => 'name' }, NoAttr => $xmllong);
print $xml->XMLout(\%sensors);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment