• Login
  • login to access premium content (it's free).

Current or Historical Weather

Have you ever wanted to show current or historical weather reports on your HTML/OS based web pages? If the answer is "Yes" you should continue reading because this post will show you how to access the Weather Underground API and display the XML formatted weather results in your page.

Before you begin coding you'll need to sign up for a free account and obtain your own API identity string:

http://www.wunderground.com/weather/api/

In the sample code below I am going to replace my identity string with a random value, but this will need to be changed to your own identity in order for it to work.

I have found it convenient to encode this feature as a FUNCTION that takes two parameters, date and zip code, as follows:

FUNCTION WeatherBox( d, z ) LOCALS h, wid, df, os, wux, flag DO
   #  Parameters:
      d = The current date as MM/DD/YYYY
      z = Zip Code as #####
   /#

   # Header value used for NETWEB command /#
   h = 'Accept: text/html, application/xhtml+xml, */*
        Accept-Language: en-US
        User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; EIE10;ENUSWOL
        Connection: close
        Accept-Encoding: identity'
   flag = 'OK'
   wid = '12345ABCDE67890F1'   # Change this to your IDENTITY STRING /#

   IF LENGTH( z ) !=5 OR ISINTEGER( z ) = 'FALSE' THEN
      flag = 'Weather N/A - Invalid Zip Code: "' + z + '"'
   ELIF LENGTH( d ) !=10 OR ISDATE( d ) = 'FALSE' THEN
      flag = 'Weather N/A - Invalid Date: "' + d + '"'
   ELSE
      # Date Formatted for how Weather Underground wants it /#
      df = CONCAT( CONCAT( RIGHT( d, 4 ), LEFT( d, 2 )), MIDDLE( d, 4, 5 ))

      # If you use the Clear Image Library, replace line above with:
        df = MOMENT( d, 'YYYYMMDD' )
      /#

      wux = NETWEB(
             'http://api.wunderground.com/api/' + wid + '/history_' +
             df + '/pws:0/q/' + z + '.xml', '50000', '10', 'GET', '', h )
      IF LOCATE( wux, '<error>' ) OR wux = '' THEN
         flag = XMLGETVALUE( wux, '<response><error><description>' )
      ELSE
         # Truncate returned XML to only the <summary> area, speeds string
           processing and simplifies further references below
         /#
         wux = XMLGET( wux, '<response><history><dailysummary><summary>' )
      /IF
   /IF

   IF flag !='OK' THEN # Something went wrong, so send back the error /#
      os = '<p>Error Message: ' + flag + '</p>'
   ELSE
      w_mint  = XMLGETVALUE( wux, '<summary><mintempi>' )
      w_meant = XMLGETVALUE( wux, '<summary><meantempi>' )
      w_maxt  = XMLGETVALUE( wux, '<summary><maxtempi>' )

      w_minw  = XMLGETVALUE( wux, '<summary><minwspdi>' )
      IF w_minw='' THEN w_minw  = 'n/a' /IF
      w_meanw = XMLGETVALUE( wux, '<summary><meanwindspdi>' )
      IF w_meanw='' THEN w_meanw = 'n/a' /IF
      w_maxw  = XMLGETVALUE( wux, '<summary><maxwspdi>' )
      IF w_maxw='' THEN w_maxw  = 'n/a' /IF

      w_minv  = XMLGETVALUE( wux, '<summary><minvisi>' )
      w_meanv = XMLGETVALUE( wux, '<summary><meanvisi>' )
      w_maxv  = XMLGETVALUE( wux, '<summary><maxvisi>' )

      w_fog = XMLGETVALUE( wux, '<summary><fog>' )
      IF w_fog = 0 OR w_fog  = '' THEN w_fog  = 'No' ELSE w_fog  = 'Yes' /IF
      w_rain = XMLGETVALUE( wux, '<summary><rain>' )
      IF w_rain = 0 OR w_rain = '' THEN w_rain = 'No' ELSE w_rain = 'Yes' /IF
      w_snow = XMLGETVALUE( wux, '<summary><snow>' )
      IF w_snow = 0 OR w_snow = '' THEN w_snow = 'No' ELSE w_snow = 'Yes' /IF

      os = '<dl id="col1">
               <dt>Min Temp:</dt><dd>' + w_mint + ' &deg;F</dd>
               <dt>Avg Temp:</dt><dd>' + w_meant + ' &deg;F</dd>
               <dt>Max Temp:</dt><dd>' + w_maxt + ' &deg;F</dd>
            </dl>
            <dl id="col2">
               <dt>Min Wind:</dt><dd>' + w_minw + ' MPH</dd>
               <dt>Avg Wind:</dt><dd>' + w_meanw + ' MPH</dd>
               <dt>Max Wind:</dt><dd>' + w_maxw + ' MPH</dd>
            </dl>
            <dl id="col1">
               <dt>Min Vis:</dt><dd>' + w_minv + ' Mi</dd>
               <dt>Avg Vis:</dt><dd>' + w_meanv + ' Mi</dd>
               <dt>Max Vis:</dt><dd>' + w_maxv + ' Mi</dd>
            </dl>
            <dl id="col2">
               <dt>Rain:</dt><dd>' + w_rain + '</dd>
               <dt>Snow:</dt><dd>' + w_snow + '</dd>
               <dt>Fog:</dt><dd>' + w_fog + '</dd>
            </dl>'
   /IF
   RETURN os /RETURN
/FUNCTION

The last piece of code where the value "os" is being set up as a formatted string with <dl> tags should be adjusted to give you back the values however you'd like to display them, such as a definition list (shown), table or a formatted sentence.

Note also that you really should declare the various w_* variables as LOCALS in the FUNCTION declaration, as I have omitted this for the sake of readability.

So in summary, let's say I wanted to get the weather on the current date in the middle of Las Vegas, I would make a call like this:

<<
   DISPLAY WeatherBox( GETDATE(NOW,"NORMAL"), '89101' ) /DISPLAY
>>