Skip to content
Permalink
Browse files

huginn#2391: Remove support for the Weather Underground API

  • Loading branch information...
blit32
blit32 committed Oct 23, 2018
1 parent efc090d commit f112f67c852fb7d9a2650c7566038b06eac996f3
@@ -34,7 +34,6 @@ end
gem 'twilio-ruby', '~> 3.11.5' # TwilioAgent
gem 'ruby-growl', '~> 4.1.0' # GrowlAgent
gem 'net-ftp-list', '~> 3.2.8' # FtpsiteAgent
gem 'wunderground', '~> 1.2.0' # WeatherAgent
gem 'forecast_io', '~> 2.0.0' # WeatherAgent
gem 'rturk', '~> 2.12.1' # HumanTaskAgent
gem 'erector', github: 'dsander/erector', branch: 'fix-fixnum-warning'
@@ -653,10 +653,6 @@ GEM
websocket-driver (0.7.0)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3)
wunderground (1.2.0)
addressable
httparty (> 0.6.0)
json (> 1.4.0)
xmpp4r (0.5.6)
xpath (3.0.0)
nokogiri (~> 1.8)
@@ -773,11 +769,10 @@ DEPENDENCIES
web-console (>= 3.3.0)
webmock (~> 2.3)
weibo_2!
wunderground (~> 1.2.0)
xmpp4r (~> 0.5.6)

RUBY VERSION
ruby 2.5.1p57

BUNDLED WITH
1.16.3
1.16.6
@@ -5,25 +5,20 @@ module Agents
class WeatherAgent < Agent
cannot_receive_events!

gem_dependency_check { defined?(Wunderground) && defined?(ForecastIO) }
gem_dependency_check { defined?(ForecastIO) }

description <<-MD
The Weather Agent creates an event for the day's weather at a given `location`.
#{'## Include `forecast_io` and `wunderground` in your Gemfile to use this Agent!' if dependencies_missing?}
#{'## Include `forecast_io` in your Gemfile to use this Agent!' if dependencies_missing?}
You also must select when you would like to get the weather forecast for using the `which_day` option, where the number 1 represents today, 2 represents tomorrow and so on. Weather forecast inforation is only returned for at most one week at a time.
The weather forecast information can be provided by either Wunderground or Dark Sky. To choose which `service` to use, enter either `darksky` or `wunderground`.
The weather forecast information is provided by Dark Sky.
The `location` should be:
The `location` must be a comma-separated string of map co-ordinates (longitude, latitude). For example, San Francisco would be `37.7771,-122.4196`.
* For Wunderground: A US zipcode, or any location that Wunderground supports. To find one, search [wunderground.com](https://wunderground.com) and copy the location part of the URL. For example, a result for San Francisco gives `https://www.wunderground.com/US/CA/San_Francisco.html` and London, England gives `https://www.wunderground.com/q/zmw:00000.1.03772`. The locations in each are `US/CA/San_Francisco` and `zmw:00000.1.03772`, respectively.
* For Dark Sky: `location` must be a comma-separated string of map co-ordinates (longitude, latitude). For example, San Francisco would be `37.7771,-122.4196`.
You must set up an [API key for Wunderground](https://www.wunderground.com/weather/api/) in order to use this Agent with Wunderground.
You must set up an [API key for Dark Sky](https://darksky.net/dev/) in order to use this Agent with Dark Sky.
You must set up an [API key for Dark Sky](https://darksky.net/dev/) in order to use this Agent.
Set `expected_update_period_in_days` to the maximum amount of time that you'd expect to pass between Events being created by this Agent.
@@ -67,9 +62,8 @@ def key_setup?

def default_options
{
'service' => 'wunderground',
'api_key' => 'your-key',
'location' => '94103',
'location' => '37.779329,-122.41915',
'which_day' => '1',
'language' => 'EN',
'expected_update_period_in_days' => '2'
@@ -78,16 +72,12 @@ def default_options

def check
if key_setup?
create_event :payload => model(weather_provider, which_day).merge('location' => location)
create_event :payload => model(which_day).merge('location' => location)
end
end

private

def weather_provider
interpolated["service"].presence || "wunderground"
end

def which_day
(interpolated["which_day"].presence || 1).to_i
end
@@ -101,22 +91,11 @@ def language
end

def validate_options
errors.add(:base, "service must be set to 'darksky' or 'wunderground'") unless %w[darksky forecastio wunderground].include?(weather_provider)
errors.add(:base, "location is required") unless location.present?
errors.add(:base, "api_key is required") unless interpolated['api_key'].present?
errors.add(:base, "which_day selection is required") unless which_day.present?
end

def wunderground
if key_setup?
forecast = Wunderground.new(interpolated['api_key'], language: language.upcase).forecast_for(location)
merged = {}
forecast['forecast']['simpleforecast']['forecastday'].each { |daily| merged[daily['period']] = daily }
forecast['forecast']['txt_forecast']['forecastday'].each { |daily| (merged[daily['period']] || {}).merge!(daily) }
merged
end
end

def dark_sky
if key_setup?
ForecastIO.api_key = interpolated['api_key']
@@ -125,73 +104,69 @@ def dark_sky
end
end

def model(weather_provider,which_day)
if weather_provider == "wunderground"
wunderground[which_day]
elsif weather_provider == "darksky" || weather_provider == "forecastio"
dark_sky.each do |value|
timestamp = Time.at(value.time)
if (timestamp.to_date - Time.now.to_date).to_i == which_day
day = {
'date' => {
'epoch' => value.time.to_s,
'pretty' => timestamp.strftime("%l:%M %p %Z on %B %d, %Y"),
'day' => timestamp.day,
'month' => timestamp.month,
'year' => timestamp.year,
'yday' => timestamp.yday,
'hour' => timestamp.hour,
'min' => timestamp.strftime("%M"),
'sec' => timestamp.sec,
'isdst' => timestamp.isdst ? 1 : 0 ,
'monthname' => timestamp.strftime("%B"),
'monthname_short' => timestamp.strftime("%b"),
'weekday_short' => timestamp.strftime("%a"),
'weekday' => timestamp.strftime("%A"),
'ampm' => timestamp.strftime("%p"),
'tz_short' => timestamp.zone
},
'period' => which_day.to_i,
'high' => {
'fahrenheit' => value.temperatureMax.round().to_s,
'epoch' => value.temperatureMaxTime.to_s,
'fahrenheit_apparent' => value.apparentTemperatureMax.round().to_s,
'epoch_apparent' => value.apparentTemperatureMaxTime.to_s,
'celsius' => ((5*(Float(value.temperatureMax) - 32))/9).round().to_s
},
'low' => {
'fahrenheit' => value.temperatureMin.round().to_s,
'epoch' => value.temperatureMinTime.to_s,
'fahrenheit_apparent' => value.apparentTemperatureMin.round().to_s,
'epoch_apparent' => value.apparentTemperatureMinTime.to_s,
'celsius' => ((5*(Float(value.temperatureMin) - 32))/9).round().to_s
},
'conditions' => value.summary,
'icon' => value.icon,
'avehumidity' => (value.humidity * 100).to_i,
'sunriseTime' => value.sunriseTime.to_s,
'sunsetTime' => value.sunsetTime.to_s,
'moonPhase' => value.moonPhase.to_s,
'precip' => {
'intensity' => value.precipIntensity.to_s,
'intensity_max' => value.precipIntensityMax.to_s,
'intensity_max_epoch' => value.precipIntensityMaxTime.to_s,
'probability' => value.precipProbability.to_s,
'type' => value.precipType
},
'dewPoint' => value.dewPoint.to_s,
'avewind' => {
'mph' => value.windSpeed.round().to_s,
'kph' => (Float(value.windSpeed) * 1.609344).round().to_s,
'degrees' => value.windBearing.to_s
},
'visibility' => value.visibility.to_s,
'cloudCover' => value.cloudCover.to_s,
'pressure' => value.pressure.to_s,
'ozone' => value.ozone.to_s
}
return day
end
def model(which_day)
dark_sky.each do |value|
timestamp = Time.at(value.time)
if (timestamp.to_date - Time.now.to_date).to_i == which_day
day = {
'date' => {
'epoch' => value.time.to_s,
'pretty' => timestamp.strftime("%l:%M %p %Z on %B %d, %Y"),
'day' => timestamp.day,
'month' => timestamp.month,
'year' => timestamp.year,
'yday' => timestamp.yday,
'hour' => timestamp.hour,
'min' => timestamp.strftime("%M"),
'sec' => timestamp.sec,
'isdst' => timestamp.isdst ? 1 : 0 ,
'monthname' => timestamp.strftime("%B"),
'monthname_short' => timestamp.strftime("%b"),
'weekday_short' => timestamp.strftime("%a"),
'weekday' => timestamp.strftime("%A"),
'ampm' => timestamp.strftime("%p"),
'tz_short' => timestamp.zone
},
'period' => which_day.to_i,
'high' => {
'fahrenheit' => value.temperatureMax.round().to_s,
'epoch' => value.temperatureMaxTime.to_s,
'fahrenheit_apparent' => value.apparentTemperatureMax.round().to_s,
'epoch_apparent' => value.apparentTemperatureMaxTime.to_s,
'celsius' => ((5*(Float(value.temperatureMax) - 32))/9).round().to_s
},
'low' => {
'fahrenheit' => value.temperatureMin.round().to_s,
'epoch' => value.temperatureMinTime.to_s,
'fahrenheit_apparent' => value.apparentTemperatureMin.round().to_s,
'epoch_apparent' => value.apparentTemperatureMinTime.to_s,
'celsius' => ((5*(Float(value.temperatureMin) - 32))/9).round().to_s
},
'conditions' => value.summary,
'icon' => value.icon,
'avehumidity' => (value.humidity * 100).to_i,
'sunriseTime' => value.sunriseTime.to_s,
'sunsetTime' => value.sunsetTime.to_s,
'moonPhase' => value.moonPhase.to_s,
'precip' => {
'intensity' => value.precipIntensity.to_s,
'intensity_max' => value.precipIntensityMax.to_s,
'intensity_max_epoch' => value.precipIntensityMaxTime.to_s,
'probability' => value.precipProbability.to_s,
'type' => value.precipType
},
'dewPoint' => value.dewPoint.to_s,
'avewind' => {
'mph' => value.windSpeed.round().to_s,
'kph' => (Float(value.windSpeed) * 1.609344).round().to_s,
'degrees' => value.windBearing.to_s
},
'visibility' => value.visibility.to_s,
'cloudCover' => value.cloudCover.to_s,
'pressure' => value.pressure.to_s,
'ozone' => value.ozone.to_s
}
return day
end
end
end

Large diffs are not rendered by default.

@@ -58,7 +58,7 @@ bob_weather_agent:
name: "SF Weather"
guid: <%= SecureRandom.hex %>
keep_events_for: <%= 45.days %>
options: <%= { :location => 94102, :lat => 37.779329, :lng => -122.41915, :api_key => 'test' }.to_json.inspect %>
options: <%= { :location => "37.779329,-122.41915", :api_key => 'test' }.to_json.inspect %>

bob_formatting_agent:
type: Agents::EventFormattingAgent
@@ -75,7 +75,7 @@ jane_weather_agent:
name: "SF Weather"
guid: <%= SecureRandom.hex %>
keep_events_for: <%= 30.days %>
options: <%= { :location => 94103, :lat => 37.779329, :lng => -122.41915, :api_key => 'test' }.to_json.inspect %>
options: <%= { :location => "37.779329,-122.41915", :api_key => 'test' }.to_json.inspect %>

jane_rain_notifier_agent:
type: Agents::TriggerAgent
@@ -280,7 +280,7 @@ def receive(events)

describe ".receive!" do
before do
stub_request(:any, /wunderground/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/weather.json")), :status => 200)
stub_request(:any, /darksky/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/weather.json")), :status => 200)
stub.any_instance_of(Agents::WeatherAgent).is_tomorrow?(anything) { true }
end

@@ -910,7 +910,7 @@ def @agent.receive_webhook(params)

describe ".drop_pending_events" do
before do
stub_request(:any, /wunderground/).to_return(body: File.read(Rails.root.join("spec/data_fixtures/weather.json")), status: 200)
stub_request(:any, /darksky/).to_return(body: File.read(Rails.root.join("spec/data_fixtures/weather.json")), status: 200)
stub.any_instance_of(Agents::WeatherAgent).is_tomorrow?(anything) { true }
end

@@ -56,7 +56,7 @@ def get_message_part(mail, content_type)
end

it "can receive complex events and send them on" do
stub_request(:any, /wunderground/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/weather.json")), :status => 200)
stub_request(:any, /darksky/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/weather.json")), :status => 200)
stub.any_instance_of(Agents::WeatherAgent).is_tomorrow?(anything) { true }
@checker.sources << agents(:bob_weather_agent)

@@ -84,7 +84,7 @@ def get_message_part(mail, content_type)
end

it "can receive complex events and send them on" do
stub_request(:any, /wunderground/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/weather.json")), :status => 200)
stub_request(:any, /darksky/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/weather.json")), :status => 200)
stub.any_instance_of(Agents::WeatherAgent).is_tomorrow?(anything) { true }
@checker.sources << agents(:bob_weather_agent)

0 comments on commit f112f67

Please sign in to comment.
You can’t perform that action at this time.