#!/usr/bin/env ruby ### wxwWU --- Utility collecting and uploading data to WeatherUnderground. ## Copyright 2006 by Dave Pearson ## $Revision: 1.7 $ ## ## wxwWU is free software distributed under the terms of the GNU General ## Public Licence, version 2. For details see the file COPYING. # What we require require 'net/http' ############################################################################ # Constants WU_HOST = "weatherstation.wunderground.com" WU_BASE_URL = "/weatherstation/updateweatherstation.php" SW_ID = "org.davep.wxwWU" ############################################################################ # Support code. def utcnow Time.new().utc.strftime( "%Y-%m-%d%%20%H:%M:%S" ) end def ctof( c ) c * 1.8 + 32 end def mmtoin( mm ) mm * 0.039 end def hPatoin( hPa ) hPa * 0.02953007 end ############################################################################ # Code for generating data from a file. Averages windspeed for all the data # and takes the higest wind speed as the gust for the period. def avg_wind_speed( data ) total = 0 data.each do |line| total += line[ 8 ].to_f end total / data.length end def max_wind_speed( data ) max_speed = 0 data.each do |line| max_speed = [ max_speed, line[ 8 ].to_f ].max() end max_speed end def generate_data( file ) # We'll read the data into an array. cache = Array.new() File.open( file ).each do |line| cache << line.chomp.split( " " ) end # Add the max (used as gust) to the end of the last item in the array. cache[ cache.length - 1 ] << max_wind_speed( cache ) # Set the wind speed to the average for all the data. cache[ cache.length - 1 ][ 8 ] = avg_wind_speed( cache ) # Return the last item in the array. cache[ cache.length - 1 ] end ############################################################################ # Main utility code. # We're going to use long options. require "getoptlong" # Set the default parameters. $params = { :add => false, :addfrom => false, :debug => false, :id => "", :password => "" } # Print the help screen. def printHelp print "wxwWU v#{/(\d+\.\d+)/.match( '$Revision: 1.7 $' )[ 1 ]} Copyright 2006 by Dave Pearson http://www.davep.org/ Supported command line options: -a --add Add this data. -f --add-from Add data from the given file. -d --debug Debug mode. Simply tells you what it would do. -i --id WeatherUnderground account ID. -p --password WeatherUnderground account password. " end # Print the licence. def printLicence print "wxwWU - Collect weather data and upload to WeatherUnderground Copyright (C) 2006 Dave Pearson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. " end # Get the arguments from the command line. begin GetoptLong.new().set_options( [ "--add", "-a", GetoptLong::REQUIRED_ARGUMENT ], [ "--add-from", "-f", GetoptLong::REQUIRED_ARGUMENT ], [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--id", "-i", GetoptLong::REQUIRED_ARGUMENT ], [ "--password", "-p", GetoptLong::REQUIRED_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ] ).each {|name, value| $params[ name.gsub( /-/, "" ).intern ] = value } rescue GetoptLong::Error printHelp() exit 1 end # The need for help overrides everything else if $params[ :help ] printHelp() elsif !$params[ :add ] && !$params[ :addfrom ] printHelp() else # If we're adding data passed on the command line... if $params[ :add ] # ...get the data from the command line data = $params[ :add ].split( " " ) else # ...otherwise get the data from the given file. data = generate_data( $params[ :addfrom ] ) end ########################################################################## # usage # action [action=updateraw] # ID [ID as registered by wunderground.com] # PASSWORD [PASSWORD registered with this ID] # dateutc - [YYYY-MM-DD HH:MM:SS (mysql format)] # winddir - [0-360] # windspeedmph - [mph] # windgustmph - [windgustmph ] # humidity - [%] # tempf - [temperature F] # rainin - [rain in] # dailyrainin - [daily rain in accumulated] # baromin - [barom in] # dewptf- [dewpoint F] # weather - [text] -- metar style (+RA) # clouds - [text] -- SKC, FEW, SCT, BKN, OVC # softwaretype - [text] ie: vws or weatherdisplay ########################################################################## # Build up the URL. url = "?action=updateraw" url += "&ID=#{$params[ :id ]}" url += "&PASSWORD=#{$params[ :password ]}" url += "&dateutc=#{utcnow()}" url += "&winddir=#{data[ 9 ]}" url += "&windspeedmph=#{data[ 8 ]}" if data.length > 20 # If we've got "faked" gust data... url += "&windgustmph=#{data[ 20 ]}" end url += "&humidity=#{data[ 7 ]}" url += "&tempf=#{ctof( data[ 4 ].to_f )}" url += "&rainin=#{mmtoin( data[ 12 ].to_f )}" url += "&dailyrainin=#{mmtoin( data[ 13 ].to_f )}" url += "&baromin=#{hPatoin( data[ 17 ].to_f )}" url += "&dewptf=#{ctof( data[ 5 ].to_f )}" # -------------------- url += "&weather=NA" url += "&clouds=NA" url += "&softwaretype=#{SW_ID}" # Does the data look okay? if data[ 17 ].to_f < 10000.0 # If we're in debug mode... if $params[ :debug ] # Just print the URL we'd be using print "http://#{WU_HOST}#{WU_BASE_URL}#{url}\n" else # Otherwise, off we go... wu = Net::HTTP.new( WU_HOST, 80 ) response, data = wu.get( "#{WU_BASE_URL}#{url}", nil ) print "Code = #{response.code}\n" print "Message = #{response.message}\n" print "Data =\"#{data}\"\n" end else print "Bad pressure reading -- ignoring this data.\n" end end # All's well that ends well. exit 0 ### wxwWU ends here