Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
A multi API consuming weather forecasting superstar.

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
bin
lib
spec
.document
.gitignore
LICENSE
README.rdoc
Rakefile
TODO
VERSION.yml
barometer.gemspec

README.rdoc

barometer

A multi API consuming weather forecasting superstar.

Barometer provides a common public API to one or more weather services (APIs) of your choice. Weather services can co-exist to retrieve extensive information, or they can be used in a hierarchical configuration where lower preferred weather services are only used if previous services are unavailable.

version

Version 0.1.0 is the current release of this gem. The gem is available from github (attack-barometer) or rubyforge (barometer). It is fully functional (for three weather service APIs).

status

Currently this project is in development and will only work for a few weather services (wunderground, google, yahoo).

Features to be added next:

  • even more weather service drivers (noaa, weather.com, weatherbug)

dependencies

Google API key

In most cases you will need to have a free google geocode api key. Get one here: code.google.com/apis/maps/signup.html Then put it in the file '~/.barometer' by adding the line: geocode_google: YOUR_KEY_HERE

You will need this for:

  • using the Barometer gem (unless you use queries that are directly supported by the weather source API, ie yahoo will take a zip code directly and doesn't require any geocoding)

  • running the Barometer binary

  • running the Barometer Web Demo

HTTParty

Why? HTTParty was created and designed specifically for consuming web services. I choose to use this over using the Net::HTTP library directly to allow for faster development of this project.

HTTParty is also extended to include configurable Timeout support.

tzinfo

Why? Barometer deals with time information for locations all over the world. This information doesn't mean that much if it can't be converted to times that don't correspond to the applicable timezone. Tzinfo handles this time zone manipulation.

graticule (very soft dependency)

Why? Barometer returns the weather for a given location. Most weather service APIs are somewhat restricted on the query format they receive. To bridge this gap and allow for maximum flexibility on the 'barometer' query format, the query will be geo-coded using the Google geocoding service, if required. Graticule can provide this geocoding interface.

Using Graticule requires a free Google API key for geocoding. It is possible to use barometer without geocoding, though your query format will be limited to that of the weather service API.

ALTERNATE: If you supply a Google API key but don't install the Graticule gem, HTTParty will be used instead to provide the same geocoding. Basically Graticule is only used if it exists.

NOTE: you can force Barometer not to use Graticule, even if you have it installed using the following:

Barometer.skip_graticule = true

usage

You can use barometer right out of the box, as it is configured to use one register-less (no API key required) international weather service (wunderground.com).

For better results, signup for a google-map key and enhance your barometer with geo-coding.

require 'barometer'

Barometer.google_geocode_key = "THE_GOOGLE_API_KEY"
barometer = Barometer.new("Paris")
weather = barometer.measure

puts weather.current.temperture

multiple weather API, with hierarchy

require 'barometer'

Barometer.google_geocode_key = "THE_GOOGLE_API_KEY"
# use yahoo and google, if they both fail, use wunderground
Barometer.selection = { 1 => [:yahoo, :google], 2 => :wunderground }

barometer = Barometer.new("Paris")
weather = barometer.measure

puts weather.current.temperture

command line

You can use barometer from the command line.

# barometer berlin

This will output the weather information for the given query. See the help for more command line information.

# barometer -h

web demo

There is a Sinatra application that demos the functionality of Barometer, and provides Barometer information. Start this local demo with:

# barometer -w

NOTE: This requires the gems “sinatra” and “vegas”.

fail

What would cause a weather service to fail? The most obvious is that the particular weather service in currently unavailable or not reachable. Other possible reasons would include not having the API (or a valid API key for the particular weather service, if required), not providing a valid query, or providing a query for a location not supported by the weather service.

For example, if you look at the example above, the query of “Paris” refers to a city in France. Yahoo weather services only supports weather results for USA (at least at the time of writing). Therefore, Barometer would not use Yahoo, just Google and failover to use Wunderground (if needed).

bootstrapping

You can use weather service drivers directly. Below is an example to use Wunderground, but since the driver interface is abstracted it will be the same for all supported services.

require 'barometer'
Barometer.google_geocode_key = "THE_GOOGLE_API_KEY"

query = Barometer::Query.new("Paris")
weather = Barometer::Service.source(:wunderground).measure(query)

puts weather.current.temperture

# OR, even more raw

measurement = Barometer::Measurement.new
weather = Barometer::Wunderground.measure_all(measurement, "Paris")

puts weather.current.temperture

NOTE: The disadvantage to using the drivers directly is that you lose the advantage of redundancy/failover added by the Module as a whole.

NOTE: You still must create the Barometer::Query object with your query string instead of directly feeding the query string to the service (as in bootstrap example #1). The Barometer::Query object has behavior required by the service that a regular String doesn't have. Using a driver directly WILL accept a String (as in bootstrap example #2).

searching

After you have measured the data, Barometer provides several methods to help you get the data you are after. All examples assume you already have measured the data as shown in the above examples.

by preference (default service)

weather.default         # returns measurement for default source
weather.current         # returns current_measurement for default
weather.now             # returns current_measurement for default
weather.forecast        # returns all forecast_measurements for default
weather.today           # returns forecast_measurement for default today
weather.tomorrow        # returns forecast_measurement for default tomorrow

puts weather.now.temperature.c
puts weather.tomorrow.high.c

by source

weather.source(:wunderground)   # returns measurement for specified source
weather.sources                 # lists all successful sources

puts weather.source(:wunderground).current.temperature.c

by date

# note, the date is the date of the locations weather, not the date of the
# user measuring the weather
date = Date.parse("01-01-2009")
weather.for(date)       # returns forecast_measurement for default on date 
weather.source(:wunderground).for(date)   # same as above but specific source

puts weather.source(:wunderground).for(date).high.c

by time

# note, the time is the time of the locations weather, not the time of the
# user measuring the weather
time = Time.parse("13:00 01-01-2009")
weather.for(time)       # returns forecast_measurement for default at time 
weather.source(:wunderground).for(time)   # same as above but specific source

puts weather.source(:wunderground).for(time).low.f

averages

If you consume more then one weather service, Barometer can provide averages for the values (currently only for the 'current' values and not the forecasted values).

require 'barometer'

Barometer.google_geocode_key = "THE_GOOGLE_API_KEY"
# use yahoo and wunderground
Barometer.selection = { 1 => [:yahoo, :wunderground] }

barometer = Barometer.new("90210")
weather = barometer.measure

puts weather.temperture

This will calculate the average temperature as given by :yahoo and :wunderground

simple answers

After you have measured the data, Barometer provides several “simple answer” methods to help you get answers to some basic questions. All examples assume you already have measured the data as shown in the above examples.

All of these questions are ultimately specific to the weather source(s) you are configured to use. All sources that have successfully measured data will be asked, but if there is no data that can answer the question then there will be no answer.

is it windy?

# 1st parameter is the threshold wind speed for being windy
# 2nd parameter is the utc_time for which you want to know the answer,
#   this defaults to the current time
# NOTE: in my example the values are metric, so the threshold is 10 kph

weather.windy?(10)

is it wet?

# 1st parameter is the threshold pop (%) for being wet
# 2nd parameter is the utc_time for which you want to know the answer,
#   this defaults to the current time
# NOTE: in my example the threshold is 50 %

weather.wet?(50)

is it sunny?

# 1st parameter is the utc_time for which you want to know the answer,
#   this defaults to the current time

weather.sunny?

is it day?

# 1st parameter is the utc_time for which you want to know the answer,
#   this defaults to the current time

weather.day?

is it night?

# 1st parameter is the utc_time for which you want to know the answer,
#   this defaults to the current time

weather.night?

design

  • create a Barometer instance

  • supply a query, there are very little restrictions on the format:

    • city, country, specific address (basically anything Google will geocode)

    • US zip code (skips geocoding if weather service accepts this directly)

    • postal code (skips geocoding if weather service accepts this directly)

    • latitude and longitude (skips geocoding if weather service accepts this directly)

    • TODO: international airport code (skips geocoding if weather service accepts this directly)

  • if geocoding required, geocode the query

  • determine which weather services will be queried (one or multiple)

  • query the weather services

  • save the data

  • repeat weather service queries as needed

extending

Barometer attempts to be a common API to any weather service API. I have included several weather service 'drivers', but I know there are many more available. Please use the provided ones as examples to create more.

copyright

Copyright © 2009 Mark G. See LICENSE for details.

Something went wrong with that request. Please try again.