Class: YrWeather

Inherits:
Object
  • Object
show all
Defined in:
lib/yr_weather.rb

Defined Under Namespace

Classes: Configuration, FileCache, RedisCache

Constant Summary collapse

YR_NO =
'https://api.met.no/weatherapi/locationforecast/2.0/complete'
COMPASS_BEARINGS =
%w(N NE E SE S SW W NW)
ARC =
360.0/COMPASS_BEARINGS.length.to_f

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(latitude:, longitude:, utc_offset: nil) ⇒ YrWeather

YrWeather.get(latitude: -33.9531096408383, longitude: 18.4806353422955) def self.get(sitename:, latitude:, longitude:, utc_offset: ‘+00:00’, limit_to: nil)

YrWeather.new(latitude: latitude, longitude: longitude, utc_offset: utc_offset).process(limit_to)

end



104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/yr_weather.rb', line 104

def initialize(latitude:, longitude:, utc_offset: nil)
  @latitude     = latitude.round(4)   # yr developer page requests four decimals.
  @longitude    = longitude.round(4)
  @utc_offset   = utc_offset || YrWeather.configuration.utc_offset || '+00:00'
  @now          = Time.now.localtime(@utc_offset)
  @start_of_day = Time.local(@now.year, @now.month, @now.day)
  @start_of_day = @start_of_day + 24*60*60  if @now.hour >= 20
  raise 'yr.no reqiure a sitename and email. See readme for details'  unless YrWeather.configuration.sitename=~/@/
  params        = { latitude: @latitude,  longitude: @longitude, redis: YrWeather.configuration.redis }
  @cacher       = (YrWeather.configuration.redis ? YrWeather::RedisCache.new(params) : YrWeather::FileCache.new(params))
  @data         = load_forecast
end

Class Attribute Details

.configurationObject

Returns the value of attribute configuration.



10
11
12
# File 'lib/yr_weather.rb', line 10

def configuration
  @configuration
end

Class Method Details

.config {|configuration| ... } ⇒ Object

Yields:



13
14
15
16
# File 'lib/yr_weather.rb', line 13

def self.config
  self.configuration ||= YrWeather::Configuration.new
  yield(configuration)
end

Instance Method Details

#arraysObject



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/yr_weather.rb', line 202

def arrays
  nodes  = @data.dig(:properties, :timeseries)
  points = nodes.map do |node|
    {
      at:            node[:time],
      temperature:   node.dig(:data, :instant, :details, :air_temperature),
      wind_speed:    node.dig(:data, :instant, :details, :wind_speed),
      precipitation: node.dig(:data, :next_1_hours, :details, :precipitation_amount) || node.dig(:data, :next_6_hours, :details, :precipitation_amount),
      hours:         ( node.dig(:data, :next_1_hours, :details, :precipitation_amount) ? 1 : 6),
    }
  end
  results = {
    from:             [],
    to:               [],
    temperature:      [],
    wind_speed:       [],
    wind_speed_knots: [],
    precipitation:    [],
    hours:            [],
  }
  points.each do |point|
    point[:hours].times do |i|
      results[:from]             << point[:at] + i*60*60
      results[:to]               << point[:at] + (i+1)*60*60
      results[:temperature]      << point[:temperature]
      results[:wind_speed]       << point[:wind_speed]
      results[:wind_speed_knots] << to_knots(point[:wind_speed])
      results[:precipitation]    << ((point[:precipitation].to_f) / (point[:hours].to_f)).round(1)
    end
  end
  results
end

#currentObject



138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/yr_weather.rb', line 138

def current
  time = @data.dig(:properties, :timeseries).map { |e| e[:time] }.reject { |e| e>@now }.sort.last
  node = @data.dig(:properties, :timeseries).select { |e| e[:time]==time }.first
  node.dig(:data, :instant, :details).merge({
    at:                   time,
    symbol_code:          node.dig(:data, :next_1_hours, :summary, :symbol_code),
    precipitation_amount: node.dig(:data, :next_1_hours, :details, :precipitation_amount),
    wind_direction:       degrees_to_bearing(node.dig(:data, :instant, :details, :wind_from_direction)),
    wind_description:     wind_description(node.dig(:data, :instant, :details, :wind_speed)),
    wind_speed_knots:     to_knots(node.dig(:data, :instant, :details, :wind_speed)),
  })
end

#dailyObject



194
195
196
197
198
199
200
# File 'lib/yr_weather.rb', line 194

def daily
  8.times.map do |day|
    start = @start_of_day + day*24*60*60
    range = start..(start + 24*60*60)
    forecast(range).merge(from: start, to: start + 24*60*60)
  end
end

#initialised?Boolean

Returns:

  • (Boolean)


117
118
119
# File 'lib/yr_weather.rb', line 117

def initialised?
  !@data.nil?
end

#metadataObject



125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/yr_weather.rb', line 125

def 
  {
    forecast_updated_at: @data.dig(:properties, :meta, :updated_at),
    downloaded_at:       @data[:downloaded_at],
    expires_at:          @data[:expires],
    start_of_day:        @start_of_day,
    latitude:            @data.dig(:geometry, :coordinates)[1],
    longitude:           @data.dig(:geometry, :coordinates)[0],
    msl:                 @data.dig(:geometry, :coordinates)[2],
    units:               @data.dig(:properties, :meta, :units),
  }
end

#next_12_hoursObject



151
152
153
154
# File 'lib/yr_weather.rb', line 151

def next_12_hours
  range = @now..(@now + 12*60*60)
  forecast(range).merge(symbol: symbol_code_hourly(range))
end

#rawObject



121
122
123
# File 'lib/yr_weather.rb', line 121

def raw
  @data
end

#six_hourlyObject



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/yr_weather.rb', line 166

def six_hourly
  t = @start_of_day
  loop do
    if (t + 6*60*60) > Time.now
      break
    else
      t = t + 6*60*60
    end
  end
  nodes = @data.dig(:properties, :timeseries).select { |e| e.dig(:data, :next_6_hours) }.map { |e| [e[:time], e] }.to_h
  nodes = 20.times.map do |i|
    nodes[t + i*6*60*60]
  end.compact.map do |node|
    {
      from:                 node.dig(:time),
      to:                   node.dig(:time) + 6*60*60,
      temperature_maximum:  node.dig(:data, :next_6_hours, :details, :air_temperature_max),
      temperature_minimum:  node.dig(:data, :next_6_hours, :details, :air_temperature_min),
      wind_speed_max:       node.dig(:data, :instant, :details, :wind_speed),
      wind_speed_max_knots: to_knots(node.dig(:data, :instant, :details, :wind_speed)),
      wind_direction:       degrees_to_bearing(node.dig(:data, :instant, :details, :wind_from_direction)),
      wind_description:     wind_description(node.dig(:data, :instant, :details, :wind_speed)),
      precipitation:        node.dig(:data, :next_6_hours, :details, :precipitation_amount),
      symbol_code:          node.dig(:data, :next_6_hours, :summary, :symbol_code),
    }
  end
end

#three_daysObject



156
157
158
159
# File 'lib/yr_weather.rb', line 156

def three_days
  range = @now..(@now + 3*24*60*60)
  forecast(range).tap { |hs| hs.delete(:wind_description) }
end

#weekObject



161
162
163
164
# File 'lib/yr_weather.rb', line 161

def week
  range = @now..(@now + 7*24*60*60)
  forecast(range).tap { |hs| hs.delete(:wind_description) }
end