<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>VoIP Tech Chat &#187; Perl</title>
	<atom:link href="http://www.voiptechchat.com/tag/perl/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.voiptechchat.com</link>
	<description>Patrick and Fred Chat... sometimes about VoIP</description>
	<lastBuildDate>Fri, 30 Dec 2011 01:34:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Use Asterisk, Cepstral, and Perl to Get Parking and Weather Updates</title>
		<link>http://www.voiptechchat.com/voip/218/use-asterisk-cepstral-and-perl-to-get-parking-and-weather-updates/</link>
		<comments>http://www.voiptechchat.com/voip/218/use-asterisk-cepstral-and-perl-to-get-parking-and-weather-updates/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 23:39:13 +0000</pubDate>
		<dc:creator>Fred</dc:creator>
				<category><![CDATA[VoIP]]></category>
		<category><![CDATA[Adhersion]]></category>
		<category><![CDATA[asterisk]]></category>
		<category><![CDATA[Digium]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[telephone]]></category>

		<guid isPermaLink="false">http://www.voiptechchat.com/?p=218</guid>
		<description><![CDATA[Note: For information on Ann Arbor DDA blocking this application, click here. Patrick and Fred eat, breathe, and live telecommunication. So, when the chance to make fun little phone applications come around, we like to jump on it. Recently, while &#8230; <a href="http://www.voiptechchat.com/voip/218/use-asterisk-cepstral-and-perl-to-get-parking-and-weather-updates/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p class="note"><strong>Note:</strong> For information on Ann Arbor DDA blocking this application, <a href="http://www.voiptechchat.com/voip/255/a2dda-blocks-asterisk-parking-data/">click here</a>.</p>
<div id="attachment_24" class="wp-caption alignright" style="width: 248px"><img class="size-medium wp-image-24" title="VoIP-Information" src="http://www.voiptechchat.com/wp-content/uploads/2008/05/voip-retro-icon-238x300.gif" alt="VoIP is Fun" width="238" height="300" /><p class="wp-caption-text">VoIP is Fun</p></div>
<p>Patrick and Fred eat, breathe, and live telecommunication. So, when the chance to make fun little phone applications come around, we like to jump on it. Recently, while discussing parking issues with Ann Arbor’s <a href="http://vielmetti.typepad.com/" onclick="pageTracker._trackPageview('/outgoing/vielmetti.typepad.com/?referer=');">Edward Vielmetti</a>, and idea came to mind. Mr. Vielmetti is active within the Ann Arbor community and among the many hats he wears, one seeks to provide access to accurate information concerning downtown transportation and parking (wow that was a mouthful). While discussing the lack of accurate bus information in Ann Arbor, the conversation took a tangent (yes, how odd that conversations with Fred or Patrick take tangents) on the area of parking.</p>
<p>The parking garages in Ann Arbor provide nice signs in front displaying in brightly lit numbers, the amount of available spaces remaining. Ann Arbor also posts this information on the web at the <a href="http://www.a2dda.org/parking__transportation/available_parking_spots/" onclick="pageTracker._trackPageview('/outgoing/www.a2dda.org/parking_transportation/available_parking_spots/?referer=');">A2DDA</a> website. An idea came to mind that basically, you can tell the available spots either from the website or right when you reach the garage — but what if you wanted to know while driving to the garage?</p>
<p>So, with that long introduction, we present “using asterisk, cepstral, and perl to get parking and weather updates.” Ok, for the non-techs, don’t panic! We’ll talk about the techie stuff in a little bit. The bottom line is using Asterisk, Cepstral, and Perl, you can check the internet for the spaces available and let the caller know — all in real time. For a working example, call <span style="text-decoration: line-through;">+1 (212) 937-7844 and </span><strong><span style="text-decoration: line-through;"><span style="font-weight: normal;">press 6 </span></span>+1 (<span style="font-weight: normal;"><strong>734) 272-0909 <span style="font-weight: normal;">(this is not a toll-free number)</span><span style="font-weight: normal;"><span style="font-weight: normal;">.</span></span></strong></span></strong></p>
<p><span id="more-218"></span></p>
<p>First, let’s talk about the three major components here: Asterisk, Cepstral, and Perl.</p>
<h4>Asterisk</h4>
<p><a href="http://www.asterisk.org" onclick="pageTracker._trackPageview('/outgoing/www.asterisk.org?referer=');">Asterisk</a> (by <a href="http://www.digium.com" onclick="pageTracker._trackPageview('/outgoing/www.digium.com?referer=');">Digium</a>) is the world’s leading open source telephony engine and tool kit. Asterisk empowers communication with it’s flexibility. Whether working as a simple office telephone system, a robust Call Center platform, or anything in-between, Asterisk provides advanced features at a very low deployment cost.</p>
<p>Asterisk is free, open source software provided under the <a href="http://www.gnu.org/" onclick="pageTracker._trackPageview('/outgoing/www.gnu.org/?referer=');">GNU General Public License</a> (GPL). Asterisk is the most popular open source software available, with the Asterisk Community being the top influencer in VoIP.</p>
<p>Why free? “<a href="http://www.digium.com" onclick="pageTracker._trackPageview('/outgoing/www.digium.com?referer=');">It’s just how Digium rolls.</a>” They really take that GPL open source to heart.</p>
<h4>Cepstral</h4>
<p><a href="http://cepstral.com" onclick="pageTracker._trackPageview('/outgoing/cepstral.com?referer=');">Cepstral</a> provides speech technologies and services for the spoken delivery of information. They build high quality, natural sounding voices for hand-held, desktop, and server applications. Their technology is easy to incorporate and operates in a small memory footprint with low computing resources. Cepstral is not free, however a full user’s license can cost under $30.00 (as of January 2009 at least).</p>
<p>If you are looking for a free alternative to Cepstral, try <a href="http://festvox.org/festival/" onclick="pageTracker._trackPageview('/outgoing/festvox.org/festival/?referer=');">Festival</a>. Festival is free, but sounds very “machine” like. Cepstral is a little more human.</p>
<h4>Perl</h4>
<p><a href="http://www.perl.org/" onclick="pageTracker._trackPageview('/outgoing/www.perl.org/?referer=');">Perl</a> is a stable, cross platform programming language. Perl is open-source and is sometimes called the “duct tape of the internet.” If MacGyver programmed, he would have used Perl.</p>
<p>Ok, with our introductions in hand, let’s get on with the show. First step was to get the information from the A2DDA website using a perl script. the perl code for that was:</p>
<pre>my $ua = LWP::UserAgent-&gt;new( timeout =&gt; 45);
my $URL = 'http://www.a2dda.org/parking.php';
$ua-&gt;agent('AsteriskAGIQuery/1');
my $req = new HTTP::Request GET =&gt; $URL;
my $res = $ua-&gt;request($req);
if ($res-&gt;is_success()) {
 if ($res-&gt;content =~ /4th and Washington&lt;/td&gt;&lt;td&gt;(.*)&lt;/td&gt;&lt;/tr&gt;/) {
  my $spaces = $1;
  if($spaces =~ m/(d+)/) {
			$spaces = $1;
			return $spaces;
		}
 }
}</pre>
<p>Sure, it could be nicer, but it works.</p>
<p>Ok, next was to resign the script so that it would work with the <a href="http://www.voip-info.org/wiki-Asterisk+AGI" onclick="pageTracker._trackPageview('/outgoing/www.voip-info.org/wiki-Asterisk+AGI?referer=');">Asterisk AGI</a> (the gateway interface of Asterisk). We modified the script slightly to read the amount of parking spaces at 4th and Washington and if we’re unable to get a number, report an ERROR.</p>
<pre>#!/usr/bin/perl -w
use strict;
use LWP::UserAgent;
$|=1;
sub trim($);

my %AGI;

while(&lt;STDIN&gt;) {
	chomp;
	last unless length($_);
	if (/^agi_(w+):s+(.*)$/) {
		$AGI{$1} = $2;
	}
}

print qq(VERBOSE "STATUS: checking a2dda.org for spaces available" 2n);

my $spacesavail = "";

if ($spacesavail = &amp;parking_lookup) {
	print qq(VERBOSE "There are $spacesavail spaces at 4th and Washington" 2n);
	print qq(SET VARIABLE SPACESAVAIL "$spacesavail"n);
	exit(0);
	}
else {
	print qq(VERBOSE "STATUS: unable to determine spaces" 2n);
}

print qq(SET VARIABLE SPACESAVAIL "ERROR"n);
exit(0); 

sub parking_lookup {
  my $ua = LWP::UserAgent-&gt;new( timeout =&gt; 45);
  my $URL = 'http://www.a2dda.org/parking.php';
  $ua-&gt;agent('AsteriskAGIQuery/1');
  my $req = new HTTP::Request GET =&gt; $URL;
  my $res = $ua-&gt;request($req);
  if ($res-&gt;is_success()) {
  		if ($res-&gt;content =~ /4th and Washington&lt;/td&gt;&lt;td&gt;(.*)&lt;/td&gt;&lt;/tr&gt;/) {
      my $spaces = $1;
      if($spaces =~ m/(d+)/) {
							$spaces = $1;
							return $spaces;
						}
     }
  }
  return "";
}</pre>
<p>Now, we have a number of available spaces, and integrating it was as easy as:</p>
<pre>exten =&gt; s,1,NoOp(checking parking)
exten =&gt; s,n,playback(/tmp/spaces-greet)
exten =&gt; s,n,AGI(getspaces.pl)
exten =&gt; s,n,GotoIf($["${SPACESAVAIL}" = "ERROR" ]?error)
exten =&gt; s,n,SayNumber(${SPACESAVAIL})
exten =&gt; s,n,playback(/tmp/spaces-avail)</pre>
<p>So why do we need Cepstral?</p>
<p>Good question! During testing of the script, we noticed that the number of spaces was always 130. No matter what we did, we kept getting back 130. Fred was pulling out what little hair he has&#8230; checking the asterisk&#8230; checking the code&#8230; couldn’t figure it out. Then, after checking the website, realized that <strong>Ann Arbor’s garages weren’t updating the spaces available</strong>. Perhaps a glitch, perhaps they don’t care, perhaps the information is being held hostage. No one knows for sure, but as of this moment, it’s pinned at 130.</p>
<p>Anyway, so enter Cepstral. Since the parking spots wouldn’t change, maybe the weather would. So, using another <a href="http://www.voiptechchat.com/voip/208/perl-script-to-put-weather-on-your-polycom-microbrowser/">script to check the weather</a>, you can modify the results and create a sound file using Cepstral (and swift), such as:</p>
<pre>my $hash = "";
$hash .= ('0'..'9', "a".."f")[int(rand(16))] for 1 .. 8;

my $text = qq(Currently &lt;break strength="weak" /&gt; it is $currtempf degrees &lt;break strength="weak" /&gt; in $city &lt;break strength="medium" /&gt; Current conditions &lt;break strength="weak" /&gt; $currcondition &lt;break strength="medium" /&gt; Rest of day predicts &lt;break strength="weak" /&gt; $todaycond &lt;break strength="medium" /&gt;);

my $sounddir = "/tmp";
my $wavefile = "$sounddir/"."tts-$hash.wav";
my $wavefileAst = "$sounddir/"."tts-$hash";
my $t2wp= "/opt/swift/bin/"; 

unless (-f $wavefile) {
       open(fileOUT, "&gt;$sounddir"."/say-text-$hash.txt");
       print fileOUT "$text";
       close(fileOUT);
							my $execf=$t2wp."swift -f $sounddir/say-text-$hash.txt -p audio/channels=1,audio/volume=70,audio/sampling-rate=8000,audio/deadair=2 -o $wavefile";
       system($execf);
       unlink($sounddir."/say-text-$hash.txt");
} 

print qq(SET VARIABLE SWIFTFILE "$wavefileAst"n);</pre>
<p>Yes, again the code could be nicer.. but in this case we create a sound file for the weather conditions and then make a sound file variable. Yes, AGI supports streaming the audio and even playing it back directly from the script&#8230; so why did we chose to exit the script and return to the dialplan? Asterisk is very versatile. We like returning to the dialplan, and that’s how we code. Life is that simple. What works for you best, can sometimes be the best solution.</p>
<p>Ok, bringing that into the asterisk dial plan, you have:</p>
<pre>exten =&gt; s,1,NoOp(checking parking)
exten =&gt; s,n,playback(/tmp/spaces-greet)
exten =&gt; s,n,AGI(testspaces.pl)
exten =&gt; s,n,GotoIf($["${SPACESAVAIL}" = "ERROR" ]?error)
exten =&gt; s,n,SayNumber(${SPACESAVAIL})
exten =&gt; s,n,playback(/tmp/spaces-avail)
exten =&gt; s,n,goto(weather)
exten =&gt; s,n(error),playback(/tmp/spaces-error)
exten =&gt; s,n(weather),AGI(current-weather.pl)
exten =&gt; s,n,GotoIf($["${CITY}" = "ERROR" ]?end)
exten =&gt; s,n,playback(${SWIFTFILE})
exten =&gt; s,n(end),goto(main,s,1)</pre>
<p>Your comments are always welcome!</p>
<h3>UPDATE — 01/10/2009</h3>
<p>Well, the system has been upgraded a little bit&#8230; if you call <strong><span style="text-decoration: line-through;">+1 (212) 937-7844</span></strong><span style="text-decoration: line-through;"> and press option </span><strong><span style="text-decoration: line-through;">6</span> +1 (<span style="font-weight: normal;"><strong>734) 272-0909</strong> you can choose your garage, and then be automatically called back (on the number you called from) when there are fewer than 10 spaces available.</span></strong></p>
<p>Comments&#8230; we love to hear them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.voiptechchat.com/voip/218/use-asterisk-cepstral-and-perl-to-get-parking-and-weather-updates/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Asterisk Script: Caller ID Name CNAM Lookup</title>
		<link>http://www.voiptechchat.com/voip/213/asterisk-script-caller-id-name-cnam-lookup/</link>
		<comments>http://www.voiptechchat.com/voip/213/asterisk-script-caller-id-name-cnam-lookup/#comments</comments>
		<pubDate>Tue, 06 Jan 2009 15:09:21 +0000</pubDate>
		<dc:creator>Fred</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[VoIP]]></category>
		<category><![CDATA[asterisk]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[telephone]]></category>

		<guid isPermaLink="false">http://www.voiptechchat.com/?p=213</guid>
		<description><![CDATA[Note: This is another one of VoIP Tech Chat’s more technical articles. If you’re not a techie (or a trekkie), you may want to skip this one. In fact, we’d love it if you instead read our What is a &#8230; <a href="http://www.voiptechchat.com/voip/213/asterisk-script-caller-id-name-cnam-lookup/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div id="attachment_209" class="wp-caption alignright" style="width: 185px"><img class="size-full wp-image-209" title="voip-geek" src="http://www.voiptechchat.com/wp-content/uploads/2009/01/voip-geek.gif" alt="VoIP Geeks Rock" width="175" height="176" /><p class="wp-caption-text">VoIP Geeks Rock</p></div>
<p><em><strong>Note</strong>: This is another one of VoIP Tech Chat’s more technical articles. If you’re not a techie (or a trekkie), you may want to skip this one. In fact, we’d love it if you instead read our </em><a href="http://www.voiptechchat.com/voip/5/what-is-voip/"><em>What is a VoIP?</em></a><em> article instead.</em></p>
<p>First, let’s discuss CNAM. CNAM is the Calling Name matching a telephone number. So, when you purchase caller ID with name from your telephone service provider, you get a name (or region) sent to your caller id with name enabled phone. Yay. But, if one of the reasons you’re using VoIP is to save money, and / or your telephone provider does not provide this service, then <a href="http://www.asterisk.org" onclick="pageTracker._trackPageview('/outgoing/www.asterisk.org?referer=');">Asterisk</a> and the Internet can help you.</p>
<p><span id="more-213"></span>Using the Asterisk dial plan, you can call a script to take the calling party’s number and do a reverse lookup; attempting to match a name to the number. Many websites offer this service for free, including AnyWho, Google, and 411.com.</p>
<p>In a nutshell, the script checks for a name and if it finds one, changes the Caller ID Name data of the call. If it can’t find the name, it will try the next site down the list. If it fails to find any name, it will set the caller id with name data to be the calling party number.</p>
<p>The perl script can be <a href="http://www.voiptechchat.com/downloads/calleridname.zip"><strong>downloaded here</strong></a>, or code viewed online from Team Forrest’s <a href="http://www.teamforrest.com/voip/89/using-agi-to-get-caller-id-name-cnam/" onclick="pageTracker._trackPageview('/outgoing/www.teamforrest.com/voip/89/using-agi-to-get-caller-id-name-cnam/?referer=');">website</a>. There are many, many types of these scripts available online, and using Google, a VoIP enabled geek can find them very quickly. This script does not use the Asterisk::AGI module, mostly because Fred likes to connect directly. Oh, if you want to look, <a href="http://www.teamforrest.com/voip/89/using-agi-to-get-caller-id-name-cnam/" onclick="pageTracker._trackPageview('/outgoing/www.teamforrest.com/voip/89/using-agi-to-get-caller-id-name-cnam/?referer=');">the Team Forrest article</a> shows an example of how to integrate it into Asterisk.</p>
<p>As always, we love to here from you, let us know what you think!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.voiptechchat.com/voip/213/asterisk-script-caller-id-name-cnam-lookup/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Perl Script to put Weather on your Polycom Microbrowser</title>
		<link>http://www.voiptechchat.com/voip/208/perl-script-to-put-weather-on-your-polycom-microbrowser/</link>
		<comments>http://www.voiptechchat.com/voip/208/perl-script-to-put-weather-on-your-polycom-microbrowser/#comments</comments>
		<pubDate>Tue, 06 Jan 2009 01:50:32 +0000</pubDate>
		<dc:creator>Fred</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[VoIP]]></category>
		<category><![CDATA[asterisk]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[telephone]]></category>

		<guid isPermaLink="false">http://www.voiptechchat.com/?p=208</guid>
		<description><![CDATA[Note: This is one of VoIP Tech Chat’s more technical articles. If you’re not a techie (or a trekkie), you may want to skip this one. In fact, we’d love it if you instead read our What is a VoIP? &#8230; <a href="http://www.voiptechchat.com/voip/208/perl-script-to-put-weather-on-your-polycom-microbrowser/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div id="attachment_209" class="wp-caption alignright" style="width: 185px"><img class="size-full wp-image-209" title="voip-geek" src="http://www.voiptechchat.com/wp-content/uploads/2009/01/voip-geek.gif" alt="VoIP Geeks Rock" width="175" height="176" /><p class="wp-caption-text">VoIP Geeks Rock</p></div>
<p><em><strong>Note</strong>: This is one of VoIP Tech Chat’s more technical articles. If you’re not a techie (or a trekkie), you may want to skip this one. In fact, we’d love it if you instead read our <a href="http://www.voiptechchat.com/voip/5/what-is-voip/">What is a VoIP?</a> article instead.</em></p>
<p>Here’s a quick little perl script to create a static html/xml file that can be displayed on your Polycom’s microbrowser. The script uses the Google weather API to check the weather based on a given zip code. The script, of course, is just an example and can be customized as needed.</p>
<p>For PHP coders, the same script can be modified to PHP and save yourself a step. For those of us that really like Perl, this script will create a static page. Using a cron job, you can easily make the page update every 10 minutes or so, and keep weather information current.</p>
<p>You can download the zipped file (<a href="http://www.voiptechchat.com/downloads/weather.zip">weather.pl</a>), or view the code and geeky discussion below&#8230;<span id="more-208"></span></p>
<p>First, let’s look at an example of the rendered code needed to display “nicely” on a Polycom’s microbrowser. The following would be appropriate for a larger screened phone, such as a SoundPoint IP 650:</p>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "xhtml11.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;Fort Lauderdale, FL&lt;/head&gt;
&lt;body&gt;
It is 70 F (21 C), Clear. High 79, Low 63, Mostly Sunny. Humidity: 87%. Wind: E at 0 mph. Tomorrow: Mostly Sunny.
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>The above will display a bold title of “Fort Lauderdale, FL” and then start with the weather conditions on the following line. For those with a smaller screen (such as the 450) you might want to kill the title and some of the weather info — something like:</p>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "xhtml11.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;&lt;/head&gt;
&lt;body&gt;
It is 70 F (21 C), Clear. High 79, Low 63, Mostly Sunny.
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Now, for the perl script. First, if you don’t have the XML::TreePP module, you’ll need to install it. Which is as easy as:</p>
<pre># perl -MCPAN -e shell
cpan&gt; install XML::TreePP</pre>
<p>That’s it&#8230; the install should be pretty quick. Ok, next for the perl script (<a href="http://www.voiptechchat.com/downloads/weather.zip">weather.pl</a>):</p>
<pre>#!/usr/bin/perl -w
use strict;
use XML::TreePP;

my $ZipCode = $ARGV[0];

if ($ZipCode =~ /^(\d{5})$/) {
	$ZipCode = $1;
	}
else {
	print qq(ERROR: invalid zipcode format\n);
	open (MYFILE, '&gt;/var/www/html/polyweather.html');
	print MYFILE qq(ERROR: invalid zipcode format\n);
	close MYFILE;
	exit(0);
} 

my $url = "http://www.google.com/ig/api?weather=" . $ZipCode ;

my $tpp = XML::TreePP-&gt;new();
my $tree = $tpp-&gt;parsehttp( GET =&gt; $url );

my $city = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{forecast_information}-&gt;{city}-&gt;{"-data"};

if (length($city) &lt; 1) {
	print "Unable to get info -- most likely a bad zip code. \n";
	open (MYFILE, '&gt;/var/www/html/polyweather.html');
	print MYFILE qq(Unable to get info -- most likely a bad zip code.\n);
	close MYFILE;
	exit(0);
}

my $currtempf = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{current_conditions}-&gt;{temp_f}-&gt;{"-data"};
my $currtempc = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{current_conditions}-&gt;{temp_c}-&gt;{"-data"};
my $currhumidity = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{current_conditions}-&gt;{humidity}-&gt;{"-data"};
my $currcondition = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{current_conditions}-&gt;{condition}-&gt;{"-data"};
my $currwind = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{current_conditions}-&gt;{wind_condition}-&gt;{"-data"};
my $todayhigh = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{forecast_conditions}-&gt;[0]-&gt;{high}-&gt;{"-data"};
my $todaylow = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{forecast_conditions}-&gt;[0]-&gt;{low}-&gt;{"-data"};
my $todaycond = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{forecast_conditions}-&gt;[0]-&gt;{condition}-&gt;{"-data"};
my $tomorrowcond = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{forecast_conditions}-&gt;[1]-&gt;{condition}-&gt;{"-data"};

my $polyhtml = qq(&lt;?xml version="1.0" encoding="utf-8"?&gt;\n);
$polyhtml = $polyhtml . qq(&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "xhtml11.dtd"&gt;\n);
$polyhtml = $polyhtml . qq(&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;\n);
$polyhtml = $polyhtml . qq(&lt;head&gt;$city&lt;/head&gt;\n);
$polyhtml = $polyhtml . qq(&lt;body&gt;\n);
$polyhtml = $polyhtml . qq-It is $currtempf F ($currtempc C), $currcondition. High $todayhigh, Low $todaylow, $todaycond. $currhumidity. $currwind. Tomorrow: $tomorrowcond. \n-;
$polyhtml = $polyhtml . qq(&lt;/body&gt;\n);
$polyhtml = $polyhtml . qq(&lt;/html&gt;\n);

open (MYFILE, '&gt;/var/www/html/polyweather.html');
print MYFILE $polyhtml;
close MYFILE;

print $polyhtml;</pre>
<h4>How does it work?</h4>
<p>Google has a nice little weather API which will provide a weather forecast for a given zip code via xml. A sample output looks like:</p>
<pre>&lt;?xml version="1.0"?&gt;
	&lt;xml_api_reply version="1"&gt;
		&lt;weather module_id="0" tab_id="0"&gt;
			&lt;forecast_information&gt;
				&lt;city data="Fort Lauderdale, FL"/&gt;
				&lt;postal_code data="33325"/&gt;
				&lt;latitude_e6 data=""/&gt;
				&lt;longitude_e6 data=""/&gt;
				&lt;forecast_date data="2009-01-05"/&gt;
				&lt;current_date_time data="2009-01-05 20:19:00 +0000"/&gt;
				&lt;unit_system data="US"/&gt;
			&lt;/forecast_information&gt;
			&lt;current_conditions&gt;
				&lt;condition data="Clear"/&gt;
				&lt;temp_f data="77"/&gt;
				&lt;temp_c data="25"/&gt;
				&lt;humidity data="Humidity: 68%"/&gt;
				&lt;icon data="/images/weather/sunny.gif"/&gt;
				&lt;wind_condition data="Wind: E at 5 mph"/&gt;
			&lt;/current_conditions&gt;
		&lt;forecast_conditions&gt;
			&lt;day_of_week data="Today"/&gt;
			&lt;low data="65"/&gt;
			&lt;high data="79"/&gt;
			&lt;icon data="/images/weather/mostly_sunny.gif"/&gt;
			&lt;condition data="Mostly Sunny"/&gt;
		&lt;/forecast_conditions&gt;
		&lt;forecast_conditions&gt;
			&lt;day_of_week data="Tue"/&gt;
			&lt;low data="67"/&gt;
			&lt;high data="81"/&gt;
			&lt;icon data="/images/weather/mostly_sunny.gif"/&gt;
			&lt;condition data="Mostly Sunny"/&gt;
		&lt;/forecast_conditions&gt;
		&lt;forecast_conditions&gt;
			&lt;day_of_week data="Wed"/&gt;
			&lt;low data="56"/&gt;
			&lt;high data="81"/&gt;
			&lt;icon data="/images/weather/chance_of_rain.gif"/&gt;
			&lt;condition data="Chance of Showers"/&gt;
		&lt;/forecast_conditions&gt;&lt;forecast_conditions&gt;
			&lt;day_of_week data="Thu"/&gt;
			&lt;low data="52"/&gt;
			&lt;high data="74"/&gt;
			&lt;icon data="/images/weather/sunny.gif"/&gt;
			&lt;condition data="Clear"/&gt;
		&lt;/forecast_conditions&gt;
	&lt;/weather&gt;
&lt;/xml_api_reply&gt;</pre>
<p>A sample output for a bad zip code looks like:</p>
<pre>&lt;?xml version="1.0"?&gt;
&lt;xml_api_reply version="1"&gt;
	&lt;weather module_id="0" tab_id="0"&gt;
		&lt;problem_cause data=""/&gt;
	&lt;/weather&gt;
&lt;/xml_api_reply&gt;</pre>
<p>The perl script scrolls through the xml, parsing for the requested data and making a little webpage. To call the script, you would run something such as:</p>
<pre>perl weather.pl 90210</pre>
<p>The above would create the web page giving the weather for Brenda, Dylan, and the rest of the Beverly Hills crowd.</p>
<p>Now, for those that love the <a href="http://www.masonhq.com/" onclick="pageTracker._trackPageview('/outgoing/www.masonhq.com/?referer=');">Mason Perl website engine</a> (like Fred), you can code this in one quick dynamic file, this one is called weatherbyzip.html and is optimized for a smaller screen:</p>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "xhtml11.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;&lt;/head&gt;
&lt;body&gt;
&lt;% $message %&gt;
&lt;/body&gt;
&lt;/html&gt;

&lt;%init&gt;
use XML::TreePP;
my $message = "";

if ($ZipCode =~ /^(\d{5})$/) {
	$ZipCode = $1;
	my $url = "http://www.google.com/ig/api?weather=" . $ZipCode ;
	my $tpp = XML::TreePP-&gt;new();
	my $tree = $tpp-&gt;parsehttp( GET =&gt; $url );
	my $city = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{forecast_information}-&gt;{city}-&gt;{"-data"};
	if (length($city) &gt; 0) {
		my $currtempf = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{current_conditions}-&gt;{temp_f}-&gt;{"-data"};
		my $currtempc = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{current_conditions}-&gt;{temp_c}-&gt;{"-data"};
		my $currcondition = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{current_conditions}-&gt;{condition}-&gt;{"-data"};
		my $todayhigh = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{forecast_conditions}-&gt;[0]-&gt;{high}-&gt;{"-data"};
		my $todaylow = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{forecast_conditions}-&gt;[0]-&gt;{low}-&gt;{"-data"};
		my $todaycond = $tree-&gt;{xml_api_reply}-&gt;{weather}-&gt;{forecast_conditions}-&gt;[0]-&gt;{condition}-&gt;{"-data"};
		$message = "It is $currtempf F ($currtempc C), $currcondition. High $todayhigh, Low $todaylow, $todaycond.";
		}
		else {
			$message = "Unable to get info -- most likely a bad zip code.";
		}
	}
else {
	$message = "Invalid Zip Code." ;
} 

&lt;/%init&gt;

&lt;%args&gt;
	$ZipCode =&gt; ''
&lt;/%args&gt;</pre>
<p>You would then call the page with weatherbyzip.html?ZipCode=90210</p>
<p>Ok&#8230; this was one of our more technical posts&#8230; we’ll be back to normal tomorrow. We promise.</p>
<p>Download the files:</p>
<ul>
<li><a href="http://www.voiptechchat.com/downloads/weather.zip">weather.pl</a></li>
<li><a href="http://www.voiptechchat.com/downloads/weatherbyzip.zip">weatherbyzip.html</a></li>
<li><a href="http://www.voiptechchat.com/downloads/google.zip">google.xml</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.voiptechchat.com/voip/208/perl-script-to-put-weather-on-your-polycom-microbrowser/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.362 seconds -->

