Class: Barometer::WeatherService::Wunderground

Inherits:
WeatherService
  • Object
show all
Defined in:
lib/barometer/weather_services/wunderground.rb

Overview

[DEFAULT PROVIDER]

Weather Underground

www.wunderground.com

  • key required: NO
  • registration required: NO
  • supported countries: ALL

performs geo coding

  • city: YES
  • coordinates: YES NOTE: provides geo data for location and weather station

time info

  • sun rise/set: YES (today only)
  • provides timezone: YES
  • requires TZInfo: YES *NOTE: If accuarcy of times and converting, this service is the top choice. They provide the full timezone name that is needed for the most accurate time conversions.

resources

Possible queries:

where query can be:

  • zipcode (US or Canadian)
  • city state; city, state
  • city
  • state
  • country
  • airport code (3-letter or 4-letter)
  • lat,lon

Wunderground terms of use

Unable to locate.

Class Method Summary collapse

Class Method Details

._accepted_formatsObject



55
56
57
# File 'lib/barometer/weather_services/wunderground.rb', line 55

def self._accepted_formats
  [:zipcode, :postalcode, :icao, :coordinates, :geocode]
end

._build_current(data, metric = true) ⇒ Object

Raises:

  • (ArgumentError)


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/barometer/weather_services/wunderground.rb', line 102

def self._build_current(data, metric=true)
  raise ArgumentError unless data.is_a?(Hash)

  current = Measurement::Result.new
  if data['observation_time'] && data['observation_time'].match(/\d/)
    current.updated_at = Data::LocalDateTime.parse(data['observation_time'])
  end
  current.humidity = data['relative_humidity'].to_i
  current.icon = data['icon'] if data['icon']

  current.temperature = Data::Temperature.new(metric)
  current.temperature << [data['temp_c'], data['temp_f']]

  current.wind = Data::Speed.new(metric)
  current.wind.mph = data['wind_mph'].to_f
  current.wind.degrees = data['wind_degrees'].to_i
  current.wind.direction = data['wind_dir']

  current.pressure = Data::Pressure.new(metric)
  current.pressure << [data['pressure_mb'], data['pressure_in']]

  current.dew_point = Data::Temperature.new(metric)
  current.dew_point << [data['dewpoint_c'], data['dewpoint_f']]

  current.heat_index = Data::Temperature.new(metric)
  current.heat_index << [data['heat_index_c'], data['heat_index_f']]

  current.wind_chill = Data::Temperature.new(metric)
  current.wind_chill << [data['windchill_c'], data['windchill_f']]

  current.visibility = Data::Distance.new(metric)
  current.visibility << [data['visibility_km'], data['visibility_mi']]

  current
end

._build_extra(measurement, result, metric = true) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/barometer/weather_services/wunderground.rb', line 68

def self._build_extra(measurement, result, metric=true)
  #raise ArgumentError unless measurement.is_a?(Data::Measurement)
  #raise ArgumentError unless query.is_a?(Barometer::Query)

  # use todays sun data for all future days
  if measurement.forecast && measurement.current.sun
    measurement.forecast.each do |forecast|
      forecast.sun = measurement.current.sun
    end
  end

  measurement
end

._build_forecast(data, metric = true) ⇒ Object

Raises:

  • (ArgumentError)


138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/barometer/weather_services/wunderground.rb', line 138

def self._build_forecast(data, metric=true)
  raise ArgumentError unless data.is_a?(Hash)
  forecasts = Measurement::ResultArray.new
  # go through each forecast and create an instance
  if data && data['simpleforecast'] &&
     data['simpleforecast']['forecastday']

    data['simpleforecast']['forecastday'].each do |forecast|
      forecast_measurement = Measurement::Result.new
      forecast_measurement.icon = forecast['icon']
      forecast_measurement.date = Date.parse(forecast['date']['pretty'])
      forecast_measurement.pop = forecast['pop'].to_i

      forecast_measurement.high = Data::Temperature.new(metric)
      forecast_measurement.high << [forecast['high']['celsius'],forecast['high']['fahrenheit']]

      forecast_measurement.low = Data::Temperature.new(metric)
      forecast_measurement.low << [forecast['low']['celsius'],forecast['low']['fahrenheit']]

      forecasts << forecast_measurement
    end
  end
  forecasts
end


94
95
96
97
98
99
100
# File 'lib/barometer/weather_services/wunderground.rb', line 94

def self._build_links(data)
  links = {}
  if data["credit"] && data["credit_URL"]
    links[data["credit"]] = data["credit_URL"]
  end
  links
end

._build_location(data, geo = nil) ⇒ Object

Raises:

  • (ArgumentError)


163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/barometer/weather_services/wunderground.rb', line 163

def self._build_location(data, geo=nil)
  raise ArgumentError unless data.is_a?(Hash)
  location = Data::Location.new
  if data['display_location']
    location.name = data['display_location']['full']
    location.city = data['display_location']['city']
    location.state_name = data['display_location']['state_name']
    location.state_code = data['display_location']['state']
    location.country_code = data['display_location']['country']
    location.zip_code = data['display_location']['zip']
    location.latitude = data['display_location']['latitude']
    location.longitude = data['display_location']['longitude']
  end
  location
end

._build_station(data) ⇒ Object

Raises:

  • (ArgumentError)


179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/barometer/weather_services/wunderground.rb', line 179

def self._build_station(data)
  raise ArgumentError unless data.is_a?(Hash)
  station = Data::Location.new
  station.id = data['station_id']
  if data['observation_location']
    station.name = data['observation_location']['full']
    station.city = data['observation_location']['city']
    station.state_name = data['observation_location']['state_name']
    station.state_code = data['observation_location']['state']
    station.country_code = data['observation_location']['country']
    station.zip_code = data['observation_location']['zip']
    station.latitude = data['observation_location']['latitude']
    station.longitude = data['observation_location']['longitude']
  end
  station
end

._build_sun(data) ⇒ Object

Raises:

  • (ArgumentError)


196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/barometer/weather_services/wunderground.rb', line 196

def self._build_sun(data)
  raise ArgumentError unless data.is_a?(Hash)
  sun = nil
  if data
    if data['moon_phase']
      rise = Data::LocalTime.new(
        data['moon_phase']['sunrise']['hour'].to_i,
        data['moon_phase']['sunrise']['minute'].to_i
      ) if data['moon_phase']['sunrise']
      set = Data::LocalTime.new(
        data['moon_phase']['sunset']['hour'].to_i,
        data['moon_phase']['sunset']['minute'].to_i
      ) if data['moon_phase']['sunset']
      sun = Data::Sun.new(rise,set)
    end
  end
  sun || Data::Sun.new
end

._current_result(data) ⇒ Object

since we have two sets of data, override these calls to choose the right set of data



255
# File 'lib/barometer/weather_services/wunderground.rb', line 255

def self._current_result(data); data[0]; end

._fetch(query, metric = true) ⇒ Object

override default _fetch behavior this service requires TWO seperate http requests (one for current and one for forecasted weather) ... combine the results



219
220
221
222
223
224
# File 'lib/barometer/weather_services/wunderground.rb', line 219

def self._fetch(query, metric=true)
  result = []
  result << _fetch_current(query)
  result << _fetch_forecast(query)
  result
end

._fetch_current(query) ⇒ Object

use HTTParty to get the current weather



228
229
230
231
232
233
234
235
236
237
# File 'lib/barometer/weather_services/wunderground.rb', line 228

def self._fetch_current(query)
  return unless query
  puts "fetch wunderground current: #{query.q}" if Barometer::debug?
  self.get(
   "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml",
   :query => {:query => query.q},
   :format => :xml,
   :timeout => Barometer.timeout
   )['current_observation']
end

._fetch_forecast(query) ⇒ Object

use HTTParty to get the forecasted weather



241
242
243
244
245
246
247
248
249
250
# File 'lib/barometer/weather_services/wunderground.rb', line 241

def self._fetch_forecast(query)
  return unless query
  puts "fetch wunderground forecast: #{query.q}" if Barometer::debug?
  self.get(
    "http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml",
    :query => {:query => query.q},
    :format => :xml,
    :timeout => Barometer.timeout
  )['forecast']
end

._forecast_result(data = nil) ⇒ Object



256
# File 'lib/barometer/weather_services/wunderground.rb', line 256

def self._forecast_result(data=nil); data[1]; end


259
# File 'lib/barometer/weather_services/wunderground.rb', line 259

def self._links_result(data=nil); data[0]; end

._location_result(data = nil) ⇒ Object



257
# File 'lib/barometer/weather_services/wunderground.rb', line 257

def self._location_result(data=nil); data[0]; end

._parse_full_timezone(data) ⇒ Object

Raises:

  • (ArgumentError)


82
83
84
85
86
87
88
89
90
91
92
# File 'lib/barometer/weather_services/wunderground.rb', line 82

def self._parse_full_timezone(data)
  raise ArgumentError unless data.is_a?(Hash)
  if data && data['simpleforecast'] &&
     data['simpleforecast']['forecastday'] &&
     data['simpleforecast']['forecastday'].first &&
     data['simpleforecast']['forecastday'].first['date']
    Data::Zone.new(
      data['simpleforecast']['forecastday'].first['date']['tz_long']
    )
  end
end

._source_nameObject

PRIVATE If class methods could be private, the remaining methods would be.



54
# File 'lib/barometer/weather_services/wunderground.rb', line 54

def self._source_name; :wunderground; end

._station_result(data = nil) ⇒ Object



258
# File 'lib/barometer/weather_services/wunderground.rb', line 258

def self._station_result(data=nil); data[0]; end

._sun_result(data = nil) ⇒ Object



260
# File 'lib/barometer/weather_services/wunderground.rb', line 260

def self._sun_result(data=nil); data[1]; end

._sunny_icon_codesObject

these are the icon codes that indicate "sun", used by sunny? function



64
65
66
# File 'lib/barometer/weather_services/wunderground.rb', line 64

def self._sunny_icon_codes
  %w(clear mostlysunny partlysunny sunny partlycloudy)
end

._timezone_result(data = nil) ⇒ Object



261
# File 'lib/barometer/weather_services/wunderground.rb', line 261

def self._timezone_result(data=nil); data[1]; end

._wet_icon_codesObject

these are the icon codes that indicate "wet", used by wet? function



60
61
62
# File 'lib/barometer/weather_services/wunderground.rb', line 60

def self._wet_icon_codes
  %w(flurries rain sleet snow tstorms nt_flurries nt_rain nt_sleet nt_snow nt_tstorms chancerain chancetstorms)
end