Yet another example, this time I'm playing with the Yahoo Weather service. Unlike the other ones I blogged about - this service doesn't require a appid so you can use it pretty quickly. It also has a pretty intensive result set. Check the API for a full set of what it returns, but my code barely scratches the surface of what is available. (One thing in particular that is kind of nice - the result of a zip code search returns you a longitude and latitude for your zip. That can be useful for completely non-weather related reasons.)
The API lets you specify either a zip or a "Location ID", which is a Yahoo specific ID for your location. You can also specify if you want Fahrenheit or Celsius results. Switching to Celsius will make all the other units also switch to the metric system. But the cool thing about the Yahoo Weather API is that it returns you plain English names for the units. Anyway, enough talking, let me show you the code:
<!--- Your Zip --->
<cfset zip = "70508">
<!--- Base URL for Yahoo's Weather Service --->
<cfset base = "http://xml.weather.yahoo.com/forecastrss?p=">
<!--- Ok, now get it --->
<cfhttp url="#base##zip#" result="response">
<!--- parse the xml --->
<cfset xmlResult = xmlParse(response.fileContent)>
<!--- When the report was built. --->
<cfset lastUpdated = xmlResult.rss.channel.lastBuildDate.xmlText>
<!--- Nice description of the weather. --->
<cfset description = xmlResult.rss.channel.description.xmlText>
<!--- Link for more information. --->
<cfset link = xmlResult.rss.channel.link.xmlText>
<!--- units --->
<cfset speed = xmlResult.rss.channel["yweather:units"].xmlAttributes.speed>
<cfset temp = xmlResult.rss.channel["yweather:units"].xmlAttributes.temperature>
<cfset distance = xmlResult.rss.channel["yweather:units"].xmlAttributes.distance>
<cfset pressure = xmlResult.rss.channel["yweather:units"].xmlAttributes.pressure>
<!--- Wind Stuff --->
<cfset windChill = xmlResult.rss.channel["yweather:wind"].xmlAttributes.chill>
<cfset windDirection = xmlResult.rss.channel["yweather:wind"].xmlAttributes.direction>
<cfset windSpeed = xmlResult.rss.channel["yweather:wind"].xmlAttributes.speed>
<!--- Sunrise/set --->
<cfset sunrise = xmlResult.rss.channel["yweather:astronomy"].xmlAttributes.sunrise>
<cfset sunset = xmlResult.rss.channel["yweather:astronomy"].xmlAttributes.sunset>
<!--- Current Info --->
<cfset temperature = xmlResult.rss.channel.item["yweather:condition"].xmlAttributes.temp>
<cfset condition = xmlResult.rss.channel.item["yweather:condition"].xmlAttributes.text>
<!--- forecast --->
<cfset numForecast = arrayLen(xmlResult.rss.channel.item["yweather:forecast"])>
<cfset forecast = arrayNew(1)>
<cfloop index="x" from="1" to="#numForecast#">
<cfset day = structNew()>
<cfset day.date = xmlResult.rss.channel.item["yweather:forecast"][x].xmlAttributes.date>
<cfset day.dow = xmlResult.rss.channel.item["yweather:forecast"][x].xmlAttributes.day>
<cfset day.high = xmlResult.rss.channel.item["yweather:forecast"][x].xmlAttributes.high>
<cfset day.low = xmlResult.rss.channel.item["yweather:forecast"][x].xmlAttributes.low>
<cfset day.condition = xmlResult.rss.channel.item["yweather:forecast"][x].xmlAttributes.text>
<cfset arrayAppend(forecast, day)>
</cfloop>
<cfoutput>
<h2>#description#</h2>
<p>
Reported at: #lastUpdated#<br />
Currently: #condition# / #temperature# #temp#<br>
Wind Chill: #windChill#<br />
Wind Speed: #windSpeed# #speed#<br />
Sunrise: #sunrise#<br />
Sunset: #sunset#<br />
</p>
<cfloop index="x" from="1" to="#arrayLen(forecast)#">
<p>
Forecast for #forecast[x].dow# #forecast[x].date#<br />
Temperature: #forecast[x].low#/#forecast[x].high# #temp#<br />
Conditions: #forecast[x].condition#<br/>
</p>
</cfloop>
<p>
For more information: <a href="#link#">#link#</a>
</p>
</cfoutput>
I'm actually not going to say a lot about this as 99% of the code is me just taking stuff out of the XML response. One thing you may notice is that this service returns an RSS feed. I'm not quite sure why it does that as the other services I've used have not. But - XML is XML I suppose.
As I mentioned, I'm not using everything returned, but I'm using enough to provide a nice weather report. What is cool about this is the possible integration options. You could - for example - write code to check the forecast every day. If the weather is fair and warm, send out a notice that it may be a good day to play golf. Vampires will be happy to see a handy sunrise/sunset report as well. My point is - while I used a simple report, you could actually do some more complex calculations based on the weather report. (Since we all know weather reports are never wrong. Right?)
By the way - I am planning on wrapping up my code into a Yahoo API. This code will provide you with a nice set of CFCs so you can easily add Yahoo services to your web site. My gut feeling is that this will be done sometime after my vacation.
Enjoy!