After starting various forms last year (from flying), I became very interested in weather data, especially wind information. While many websites offer this, like Jeff Greenbaum’s excellent Wind Conditions Page for Pacifica, they don’t present the data in a way that suits me, and often work poorly on mobile devices.
I believe I can improve on this. The Weather Underground offers well-documented XML APIs, so let’s explore this data.
Using the Smalltalk Shell (stsh), we’ll load the Objective-XML framework:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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
137
138
139
140
141
142
143
144
145
146
147
148
| marcel@spock\[Projects\]stsh
> context loadFramework:'MPWXmlKit'
```Now, let's examine the raw XML from Weather Underground's API.```
\> urlstr:='http://api.wunderground.com/weatherstation/WXCurrentObXML.asp?ID=KCADALYC1'
> url:=NSURL URLWithString: urlstr
> NSString stringWithContentsOfURL:url.
>
```No result. (Weather Underground seems to require a User Agent, which these methods lack). Let's try with curl:```
\>context addExternalCommand:'curl'.
>curl run:'http://api.wunderground.com/weatherstation/WXCurrentObXML.asp?ID=KCADALYC1'
Weather Underground Personal Weather Station
http://wunderground.com/weatherstation/
http://icons.wunderground.com/graphics/bh-wui\_logo.gif
Weather Underground
http://wunderground.com/weatherstation/
Mussel Rock, Daly City, CA
Mussel Rock
Daly City
CA
37.667347
\-122.489342
514 ft
KCADALYC1
Fan-aspirated Davis Vantage Pro 2 Plus
Last Updated on November 7, 1:55 PM PST
Sat, 07 November 2009 21:55:21 GMT
56.9 F (13.8 C)
56.9
13.8
83
From the NW at 15.0 MPH Gusting to 16.0 MPH
NW
313
15.0
16.0
30.07" (1018.2 mb)
1018.2
30.07
51.8 F (11.0 C)
51.8
11.0
483.00
2.5
0.00 in (0.0 mm)
0.00
0.0
0.01 in (0.0 mm)
0.01
0.0
http://www.wunderground.com/weatherstation/WXDailyHistory.asp?ID=KCADALYC1
http://www.wunderground.com/cgi-bin/findweather/getForecast?query=37.667347,-122.489342
```That's better. Let's parse this XML into a Cocoa Property List.```
\> parser := MPWMAXParser parser.
> parser parsedDataFromURL: 'http://api.wunderground.com/weatherstation/WXCurrentObXML.asp?ID=KCADALYC1'
{
UV = "2.5";
credit = "Weather Underground Personal Weather Station";
"credit\_URL" = "http://wunderground.com/weatherstation/";
"dewpoint\_c" = "11.1";
"dewpoint\_f" = "51.9";
"dewpoint\_string" = "51.9 F (11.1 C)";
"heat\_index\_c" = {
};
"heat\_index\_f" = {
};
"heat\_index\_string" = {
};
"history\_url" = "http://www.wunderground.com/weatherstation/WXDailyHistory.asp?ID=KCADALYC1";
image = {
link = "http://wunderground.com/weatherstation/";
title = "Weather Underground";
url = "http://icons.wunderground.com/graphics/bh-wui\_logo.gif";
};
location = {
city = "Daly City";
elevation = "514 ft";
full = "Mussel Rock, Daly City, CA";
latitude = "37.667347";
longitude = "-122.489342";
neighborhood = "Mussel Rock";
state = CA;
zip = {
};
};
"ob\_url" = "http://www.wunderground.com/cgi-bin/findweather/getForecast?query=37.667347,-122.489342";
"observation\_time" = "Last Updated on November 7, 1:55 PM PST";
"observation\_time\_rfc822" = "Sat, 07 November 2009 21:55:51 GMT";
"precip\_1hr\_in" = "0.00";
"precip\_1hr\_metric" = "0.0";
"precip\_1hr\_string" = "0.00 in (0.0 mm)";
"precip\_today\_in" = "0.01";
"precip\_today\_metric" = "0.0";
"precip\_today\_string" = "0.01 in (0.0 mm)";
"pressure\_in" = "30.07";
"pressure\_mb" = "1018.2";
"pressure\_string" = "30.07\\" (1018.2 mb)";
"relative\_humidity" = 83;
"solar\_radiation" = "482.00";
"station\_id" = KCADALYC1;
"station\_type" = "Fan-aspirated Davis Vantage Pro 2 Plus";
"temp\_c" = "13.9";
"temp\_f" = "57.0";
"temperature\_string" = "57.0 F (13.9 C)";
weather = {
};
"wind\_degrees" = 342;
"wind\_dir" = NNW;
"wind\_gust\_mph" = "24.0";
"wind\_mph" = "18.0";
"wind\_string" = "From the NNW at 18.0 MPH Gusting to 24.0 MPH";
"windchill\_c" = {
};
"windchill\_f" = {
};
"windchill\_string" = {
};
}
```This looks good. The wind data, with keys "wind\_degrees" and "wind\_mph", is near the bottom. Let's extract these values:```
\> (parser parsedDataFromURL:'http://api.wunderground.com/weatherstation/WXCurrentObXML.asp?ID=KCADALYC1' ) collect objectForKey: #( wind\_mph wind\_dir wind\_string ) each.
21.0
NW
From the NW at 21.0 MPH Gusting to 24.0 MPH
```We retrieved the wind data, but the direction is a string, not the numerical value. Let's fix that:```
\> (parser parsedDataFromURL: 'http://api.wunderground.com/weatherstation/WXCurrentObXML.asp?ID=KCADALYC1' ) collect objectForKey: #( wind\_mph wind\_degrees wind\_string ) each.
12.0
318
From the NW at 12.0 MPH Gusting to 24.0 MPH
>
```Perfect! We now have the wind speed, numerical direction, and a descriptive string for display.
|