Skip to content

Commit

Permalink
[#3] Added support for the hourly forecast in the pro 2.5 API
Browse files Browse the repository at this point in the history
  • Loading branch information
troya2 committed Jul 2, 2024
1 parent 6a044fc commit a6638ec
Show file tree
Hide file tree
Showing 13 changed files with 204 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* [#25](https://github.com/dblock/open-weather-ruby-client/pull/25): Exposed the national weather alerts response in the One Call API - [@troya2](https://github.com/troya2).
* [#38](https://github.com/dblock/open-weather-ruby-client/pull/38): Migrated to One Call 3.0 API - [@jeanmartin](https://github.com/jeanmartin).
* [#39](https://github.com/dblock/open-weather-ruby-client/pull/39): Added support for the hourly forecast in the pro 2.5 API[@troya2](https://github.com/troya2).
* Your contribution here.

### 0.4.0 (2023/08/13)
Expand Down
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Unlike other clients, including [open-weather](https://github.com/coderhs/ruby_o
- [One Call](#one-call)
- [Current and Forecast Weather](#current-and-forecast-weather)
- [Historical Weather](#historical-weather)
- [Hourly Forecast (Pro)](#hourly-forecast-pro)
- [Stations](#stations)
- [Register a Station](#register-a-station)
- [List Stations](#list-stations)
Expand Down Expand Up @@ -186,6 +187,7 @@ See [OpenWeather::Models::OneCall](lib/open_weather/models/one_call) for all ava

```ruby
data = client.one_call(lat: 33.441792, lon: -94.037689) # => OpenWeather::Models::OneCall::Weather

data.lat # => 33.44
data.lon # => -94.04
data.timezone # => 'America/Chicago'
Expand All @@ -206,13 +208,36 @@ client.one_call(lat: 33.441792, lon: -94.037689, exclude: ['minutely', 'hourly']

```ruby
data = client.one_call(lat: 33.441792, lon: -94.037689, dt: Time.now - 24 * 60 * 60) # => OpenWeather::Models::OneCall::Weather

data.lat # => 33.44
data.lon # => -94.04
data.timezone # => 'America/Chicago'
data.current # => OpenWeather::Models::OneCall::CurrentWeather
data.hourly # => Array[OpenWeather::Models::OneCall::HourlyWeather]
```

### Hourly Forecast (Pro)

The [Hourly Forecast API](https://openweathermap.org/api/hourly-forecast) provides hourly weather forecast for 4 days. Note: This API requires a piad api-key from [OpenWeather.org](https://openweathermap.org/full-price#current).

```ruby
data = client.client.hourly(lat: 33.5312, lon: -111.9426) # => OpenWeather::Models::Forecast::Hourly

data.cnt # => 96 (number of entries)
data.list.first # => OpenWeather::Models::Forecast::Forecast
data.list.first.dt # => Time
data.list.first.main # => OpenWeather::Models::Forecast::Main
data.list.first.weather # => Array[OpenWeather::Models::Forecast::Weather]
data.list.first.clouds # => OpenWeather::Models::Forecast::Clouds or nil
data.list.first.wind # => OpenWeather::Models::Forecast::Wind or nil
data.list.first.visibility # => 10000
data.list.first.pop # => 0.1 (probability of precipitation from 0.0 to 1.0 (0% to 100%))
data.list.first.rain # => OpenWeather::Models::Forecast::Rain or nil
data.list.first.snow # => OpenWeather::Models::Forecast::Snow or nil
data.list.first.sys # => OpenWeather::Models::Forecast::Sys or nil
data.list.first.dt_txt # => String (Time of data forecasted, ISO, UTC)
```

### Stations

The [Stations API](https://openweathermap.org/stations) lets your manage personal weather stations and measurements.
Expand Down
1 change: 1 addition & 0 deletions lib/open_weather/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class Client
include Connection
include Request
include Endpoints::Current
include Endpoints::Hourly
include Endpoints::OneCall
include Endpoints::Stations

Expand Down
2 changes: 2 additions & 0 deletions lib/open_weather/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module Config

ATTRIBUTES = %i[
endpoint
pro_endpoint
api_key
proxy
user_agent
Expand All @@ -22,6 +23,7 @@ module Config

def reset
self.endpoint = 'https://api.openweathermap.org/data'
self.pro_endpoint = 'https://pro.openweathermap.org/data'
self.api_key = nil
self.user_agent = "OpenWeather Ruby Client/#{OpenWeather::VERSION}"
self.ca_path = nil
Expand Down
1 change: 1 addition & 0 deletions lib/open_weather/endpoints.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
require_relative 'endpoints/current'
require_relative 'endpoints/one_call'
require_relative 'endpoints/stations'
require_relative 'endpoints/hourly'
16 changes: 16 additions & 0 deletions lib/open_weather/endpoints/hourly.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

module OpenWeather
module Endpoints
module Hourly
def hourly(lat, lon = nil, options = {})
# default to the pro endpoint if not specified
endpoint = options.delete(:endpoint) || pro_endpoint
options = options.merge(endpoint:)

options = lat.is_a?(Hash) ? options.merge(lat) : options.merge(lat:, lon:)
OpenWeather::Models::Forecast::Hourly.new(get('2.5/forecast/hourly', options), options)
end
end
end
end
1 change: 1 addition & 0 deletions lib/open_weather/models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
require_relative 'models/list'
require_relative 'models/city'
require_relative 'models/one_call'
require_relative 'models/forecast'
require_relative 'models/station'
require_relative 'models/stations/measurement'
require_relative 'models/stations/temp'
Expand Down
5 changes: 5 additions & 0 deletions lib/open_weather/models/forecast.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

require_relative 'forecast/hourly'
require_relative 'forecast/forecast'
require_relative 'forecast/city'
17 changes: 17 additions & 0 deletions lib/open_weather/models/forecast/city.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

module OpenWeather
module Models
module Forecast
class City < Model
property 'id' # City ID
property 'name' # City name
property 'coord', transform_with: ->(v) { OpenWeather::Models::Coord.new(v) } # City geo location
property 'country' # Country code (GB, JP etc.).
property 'timezone' # shift in seconds from UTC
property 'sunrise', transform_with: ->(v) { Time.at(v).utc } # Sunrise time, UTC
property 'sunset', transform_with: ->(v) { Time.at(v).utc } # Sunset time, UTC
end
end
end
end
33 changes: 33 additions & 0 deletions lib/open_weather/models/forecast/forecast.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

module OpenWeather
module Models
module Forecast
class Forecast < Model
property 'dt', transform_with: ->(v) { Time.at(v).utc } # time of data forcasted, UTC
property 'dt_txt' # Time of data forecasted, ISO, UTC
property 'main'
property 'weather'
property 'clouds'
property 'wind'
property 'rain'
property 'snow'
property 'visibility' # Average visibility, metres. The maximum value of the visibility is 10km
property 'pop' # Probability of precipitation. The values of the parameter vary between 0 and 1, where 0 is equal to 0%, 1 is equal to 100%
property 'sys'

def initialize(args = nil, options = {})
super args, options

self.main = OpenWeather::Models::Main.new(main, options) if main
self.weather = weather.map { |w| OpenWeather::Models::Weather.new(w, options) } if weather
self.clouds = OpenWeather::Models::Clouds.new(clouds, options) if clouds
self.wind = OpenWeather::Models::Wind.new(wind, options) if wind
self.rain = OpenWeather::Models::Rain.new(rain, options) if rain
self.snow = OpenWeather::Models::Snow.new(snow, options) if snow
self.sys = OpenWeather::Models::Sys.new(sys, options) if sys
end
end
end
end
end
25 changes: 25 additions & 0 deletions lib/open_weather/models/forecast/hourly.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

module OpenWeather
module Models
module Forecast
class Hourly < Model
include Enumerable

property 'cod'
property 'calctime'
property 'cnt', from: 'count'
property 'list'
property 'message'
property 'city'

def initialize(args = nil, options = {})
super args, options

self.list = list.map { |forecast| OpenWeather::Models::Forecast::Forecast.new(forecast, options) } if list
self.city = OpenWeather::Models::Forecast::City.new(city, options) if city
end
end
end
end
end
45 changes: 45 additions & 0 deletions spec/fixtures/open_weather/forecast/hourly.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions spec/open_weather/forecast/hourly_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'hourly forecast' do
include_context 'API client'

it 'hourly', vcr: { cassette_name: 'forecast/hourly' } do
data = client.hourly(lat: 33.5312, lon: -111.9426)

expect(data).to be_a OpenWeather::Models::Forecast::Hourly
expect(data.cnt).to eq 96
expect(data.city).to be_a OpenWeather::Models::Forecast::City

expect(data.list).to be_a Array
data.list.first.tap do |forecast|
expect(forecast).to be_a OpenWeather::Models::Forecast::Forecast
expect(forecast.dt).to eq Time.at(1661875200)
expect(forecast.main).to be_a OpenWeather::Models::Main
expect(forecast.weather).to be_a Array
expect(forecast.weather.first).to be_a OpenWeather::Models::Weather
expect(forecast.clouds).to be_a OpenWeather::Models::Clouds
expect(forecast.wind).to be_a OpenWeather::Models::Wind
expect(forecast.rain).to be_a OpenWeather::Models::Rain
expect(forecast.snow).to be_nil
expect(forecast.visibility).to eq 10000
expect(forecast.pop).to eq 0.32
expect(forecast.sys).to be_a OpenWeather::Models::Sys
expect(forecast.dt_txt).to eq '2022-08-30 16:00:00'
end
end
end

0 comments on commit a6638ec

Please sign in to comment.