# Metar Weather Grabber

**URL:** <https://www.ruby-forum.com/t/metar-weather-grabber/57778>\
**Category:** Ruby\
**Created:** [April 13, 2006, 11:25pm UTC](https://www.ruby-forum.com/t/metar-weather-grabber/57778 "2006-04-13T23:25:34Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![supasta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ebca7d/32.png) [@supasta](https://www.ruby-forum.com/u/supasta)\
**Post date:** [April 13, 2006, 11:25pm UTC](https://www.ruby-forum.com/t/metar-weather-grabber/57778/1 "2006-04-13T23:25:34Z")

</div>

I don’t want to pay money to get weather feeds from a bunch of different  
countries. So I took my hand at writing my own. It is for an ajax  
service that grabs the XML.

If you use this, expand on it. If you expand on it, post it back on  
here. There are somethings I haven’t gotten to yet. The usage of the  
weather codes needs to get better too.

#!/usr/bin/ruby

require ‘rexml/document’  
require ‘open-uri’  
require ‘pp’

include REXML

class Weather  
attr\_reader :wind, :temperature, :dew\_point, :sky, :sky\_icon

def initialize(metar\_string)  
@metar\_string = metar\_string  
@wind = self.set\_wind()  
@temperature, @dew\_point = self.set\_temperature()  
@sky, @sky\_icon = self.set\_sky()  
end

def set\_wind  
sample\_string = $& if @metar\_string =~  
/(\d{3}|VRB)[G]{0,1}\d{1,4}KT/

```
direction = self.get_cardinal_direction(sample_string[0...3])
speed = 

```

sample\_string[sample\_string.rindex(/\d{1,4}KT/)…sample\_string.length-3].to\_i

```
"#{direction} at #{speed}mph"

```

end

def get\_cardinal\_direction(degrees)  
case degrees.to\_i  
when 0: “Variable”  
when 1…4: “N”  
when 5…35: “NNE”  
when 36…55: “NE”  
when 56…85: “ENE”  
when 86…95: “E”  
when 96…125: “ESE”  
when 126…135: “SE”  
when 136…175: “SSE”  
when 176…185: “S”  
when 185…215: “SSW”  
when 216…225: “W”  
when 226…265: “WSW”  
when 265…275: “W”  
when 275…295: “WNW”  
when 296…305: “NW”  
when 306…346: “NNW”  
when 347…370: “N”  
else “Gusty”  
end  
end

def set\_temperature  
sample\_string = $&.strip if @metar\_string =~ /  
[M]{0,1}\d{2}/[M]{0,1}\d{2} /

```
celcius = sample_string[0..2].to_i
fahrenheit = ( ( celcius.to_i * 9 ) / 5 + 32 )

dew_point_celcius = 

```

sample\_string[3…sample\_string.length-1].to\_i  
dew\_point\_fahrenheit = ( ( dew\_point\_celcius \* 9 ) / 5 + 32)

```
["#{fahrenheit} F (#{celcius} C)", "#{dew_point_fahrenheit} F 

```

(#{dew\_point\_celcius} C)"]  
end

def set\_sky  
sky = $&.strip if @metar\_string =~  
/(SKC|FEW|SCT|BKN|OVC|CLR)[CB]{0,1}/  
sky = $&.strip if @metar\_string =~  
/(RA|DZ|SN|GR|SQ|GS|SG|IC|PE|BR|FG|FU|HZ|VA|DU|SA|SS|DS|FC|MI|BC|DR|BL|SH|TS|FZ)+{1}/

```
weather_codes = {	"SKC"=> ["Scattered Clouds", 30],
		"FEW"=> ["Sunny" , 32],
		"SCT"=> ["Partly Cloudy" , 29],
		"BKN"=> ["Mostly Cloudy" , 28],
		"OVC"=> ["Overcast" , 26],
		"CLR"=> ["Sunny" , 32],
		"RA"=> ["Raining" , 40],
		"DZ"=> ["Drizzle" , 39],
		"SN"=> ["Snow" , 16],
		"GR"=> ["Hail" , 35],
		"SQ"=> ["Squalls" , nil],
		"GS"=> ["Small Hail" , 35],
		"SG"=> ["Snow Grains" , 15],
		"IC"=> ["Diamond Dust" , nil],
		"PE"=> ["Ice Pellets" , nil],
		"BR"=> ["Mist" , nil],
		"FG"=> ["Fog" , 20],
		"FU"=> ["Smoke" , 22],
		"HZ"=> ["Haze" , 21],
		"VA"=> ["Volcanic Ash" , nil],
		"DU"=> ["Widespead dust" , nil],
		"SA"=> ["Sand" , nil],
		"SS"=> ["Sandstorm" , nil],
		"DS"=> ["Duststorm" , nil],
		"FC"=> ["Funnel Cloud" , nil],
		"MI"=> ["Shallow" , nil],
		"BC"=> ["Patches" , nil],
		"DR"=> ["Drifting" , nil],
		"BL"=> ["Blowing" , nil],
		"SH"=> ["Showers" , nil],
		"TS"=> ["Thunderstorm" , 1],
		"FZ"=> ["Supercooled(Freezing)", nil],
		"+" => ["Heavy" , nil],
		"TCU"=> ["Towering Cumulonimbs", nil]
                 }
icon = ''
weather_codes.each do | code, description |
  sky = sky.gsub(code, description[0])
  icon = description[1] if !description[1].nil?
end

[sky, icon]

```

end  
end

# Set up the XML document

xml\_write = REXML::Document.new(’’)  
xml\_write.elements["//method"].text = “updateWeather”

#Array of Cities and Local from the Weather xml information  
cities\_url = {“New York, NY” =\>  
“ftp://weather.noaa.gov/data/observations/metar/stations/KLGA.TXT”,  
“London, UK” =\>  
“ftp://weather.noaa.gov/data/observations/metar/stations/EGLL.TXT”}

cities\_url.each do |location, url|

current\_weather = Element.new()  
current\_weather.add\_element(“CurrentWeather”)  
current\_weather.elements["//CurrentWeather"].add\_attribute(“label”,  
location)

element\_write =  
current\_weather.elements["//CurrentWeather[@label=’"+location+"’]"]

metar = Document.new(open(url))  
weather = Weather.new(metar.to\_s.gsub("\n", " "))

element\_write.add\_element(“DewPoint”).text =  
weather.dew\_point  
element\_write.add\_element(“Temperature”).text =  
weather.temperature  
element\_write.add\_element(“Wind”).text = weather.wind  
element\_write.add\_element(“SkyConditions”).text = weather.sky  
element\_write.add\_element(“SkyConditionsIcon”).text = weather.sky\_icon  
element\_write.add\_element(“RelativeHumidity”).text = metar[0]  
xml\_write.elements["//result"].add\_element(current\_weather.elements["//CurrentWeather"])  
end

xml\_writable = File.new(“public\_html/weather.xml”, “w+”)  
xml\_write.write(xml\_writable, -1, true)

---

<div class="post-metadata">

**Author:** ![supasta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ebca7d/32.png) [@supasta](https://www.ruby-forum.com/u/supasta)\
**Post date:** [April 14, 2006, 12:09am UTC](https://www.ruby-forum.com/t/metar-weather-grabber/57778/2 "2006-04-14T00:09:27Z")

</div>

Chris W. wrote:

> I don’t want to pay money to get weather feeds from a bunch of different  
> countries. So I took my hand at writing my own. It is for an ajax  
> service that grabs the XML.
> 
> If you use this, expand on it. If you expand on it, post it back on  
> here. There are somethings I haven’t gotten to yet. The usage of the  
> weather codes needs to get better too.

Hi Chris,  
is there something wrong with the decoded data?

* * *

require ‘open-uri’

## url = ‘ftp://weather.noaa.gov/data/observations/metar/decoded/KLGA.TXT’ open(url) do |f| weather = f.read.to\_a.map {|line| line.strip.split(’:’)} label = weather.shift.first.split(’,’).first date = weather.shift.first puts %Q[] weather.each do |w| key = w.first.tr(’()’, ’ ‘).delete(’ ') puts %Q[\<#{key}\>#{w[1].strip}\</#{key}\>] end puts ‘’ end

## output:

## from the NW (320 degrees) at 9 MPH (8 KT) 10 mile(s) partly cloudy 75.0 F (23.9 C) 35.1 F (1.7 C) 23% …

cheers

Simon

---

<div class="post-metadata">

**Author:** ![supasta](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ebca7d/32.png) [@supasta](https://www.ruby-forum.com/u/supasta)\
**Post date:** [April 14, 2006, 4:14am UTC](https://www.ruby-forum.com/t/metar-weather-grabber/57778/3 "2006-04-14T04:14:10Z")

</div>

Nope.

I guess I just wanted to learn how to use regular expressions. I wish I  
would have found those a couple of hours ago.

Thanks for the post, that will help a lot.

Simon KrÃ¶ger wrote:

> Chris W. wrote:
> 
> > I don’t want to pay money to get weather feeds from a bunch of different  
> > countries. So I took my hand at writing my own. It is for an ajax  
> > service that grabs the XML.
> > 
> > If you use this, expand on it. If you expand on it, post it back on  
> > here. There are somethings I haven’t gotten to yet. The usage of the  
> > weather codes needs to get better too.
> 
> Hi Chris,  
> is there something wrong with the decoded data?
> 
> * * *
> 
> require ‘open-uri’
> 
> ## url = ‘ftp://weather.noaa.gov/data/observations/metar/decoded/KLGA.TXT’ open(url) do |f| weather = f.read.to\_a.map {|line| line.strip.split(’:’)} label = weather.shift.first.split(’,’).first date = weather.shift.first puts %Q[] weather.each do |w| key = w.first.tr(’()’, ’ ‘).delete(’ ') puts %Q[\<#{key}\>#{w[1].strip}\</#{key}\>] end puts ‘’ end
> 
> ## output:
> 
> ## from the NW (320 degrees) at 9 MPH (8 KT) 10 mile(s) partly cloudy 75.0 F (23.9 C) 35.1 F (1.7 C) 23% …
> 
> cheers
> 
> Simon
