I can remember as a kid how fascinating it was to be able to call a local number (611) and listen to the local weather forecast. Never mind, of course, that it was rarely accurate. Some things change and some things never do. Even as lousy as most weather forecasts are, most of us still are fascinated nonetheless which brings us to the topic of the day: An Enhanced Weather Application for Asterisk®. Last week, we finally got a reliable voice synthesizer installed for all the newer versions of Asterisk. So now we're ready to put it to good use with our first of several text-to-speech projects. We took a little different approach in building this weather module when it's compared to the default application which ships with Asterisk@Home. We wanted not only current conditions but also a 7-day forecast. And we wanted the caller to be able to choose the weather location rather than having to hard-code a specific city into the AGI script. Finally there's even a simple feature for those that don't want to listen to a full 7-day forecast: hang up.
How It Works. The design is pretty straightforward. You install the nv-weather.php script in your default Asterisk agi-bin directory and add a simple dialplan to your extensions_custom.conf file. Then you pick up an extension on your Asterisk system and dial 611 or the number you've designated for the new weather reports. You'll be prompted to enter the 3-character airport code of the city for which you want to hear the weather forecast. In a few seconds you'll be listening to the latest information from the National Weather Service using our pdaweather.org conversion tools. And apologies to our foreign friends. Yes, we know you have weather, too. We just don't know of an equivalent organization like the National Weather Service in every country. If you do, then it'll be fairly simple to adjust the code to meet your local needs. Here's a Canadian solution.
Prerequisites. For the Nerd Vittles Weather Application to work, you'll need an Internet connection to access pdaweather.org. We're using our weather site to convert the NWS weather reports to a text-to-speech-friendly format. Then you'll need an Asterisk@Home 2.x server and the new Flite voice synthesizer for Asterisk. Instead of a dedicated Asterisk server, you can use the VMware-version of Asterisk if you just want to experiment a bit. It runs in a window on your Windows XP/2000 desktop. Our Flite tutorial and the Flite application software are available here. And, as usual, everything you'll need for this project is free!
A Word About Airport Codes. Before we get everything installed and working, let's spend a minute discussing airport codes. At least for some U.S. cities, the folks that thought up airport codes did a pretty crappy job of coming up with three-character abbreviations. Take IAD, for example, which is the airport code for Dulles Airport outside of Washington, D.C. We've compounded the problem by trying to uniquely fit those codes into a telephone keypad consisting of 10 numbers which cover the 26 letters of the alphabet. You'll recall that even Ma Bell herself never considered that letters would actually be used for much of anything on telephones. Remember the Q and Z were originally missing. Times change. It happens. --Forrest Gump
The point of all this is to alert you that some airport codes when keyed in on a touchtone phone are not unique. For example, LAX (Los Angeles, CA) and JAX (Jacksonville, FL) both are keyed in as 529. How do it know? Well, it doesn't. So we were a little arbitrary with some of these. 529 is Jacksonville on this system while Los Angeles is LOS (567) or SNA (762). NYC and our made-up MYB share 692 so Myrtle Beach is 692 and JFK (535) and LGA (542) are used for New York (which happen to be the real airport codes and the locations of the weather stations anyway).
You also may find that your favorite airport is missing altogether. Not to worry! Keep reading! We entered a bunch of airport codes, and then we got tired and quit. As folks have requested other cities through our pdaweather.org web site, we've added them. But soon, all of that will be a thing of the past. How will you know if your town is missing? Well, it's easy. You'll get the Atlanta weather report whether you wanted it or not. So, if that happens, just hang in there for Part II ... coming soon! Here's the list of supported airport codes for today.
Dialplan Code. In order to activate extension 611 to answer calls for weather information, you'll need to drop the following code into your dialplan in the [from-internal-custom] context of extensions_custom.conf:
exten => 611,1,Answer
exten => 611,2,Wait(1)
exten => 611,3,DigitTimeout(7)
exten => 611,4,ResponseTimeout(10)
exten => 611,5,Flite("At the beep enter the three character airport code for the weather report you wish to retrieve.")
exten => 611,6,Read(APCODE,beep,3)
exten => 611,7,Flite("Please hold a moment while we contact the National Weather Service for your report.")
exten => 611,8,AGI(nv-weather.php|${APCODE})
exten => 611,9,NoOp(Wave file: ${TMPWAVE})
exten => 611,10,Playback(${TMPWAVE})
exten => 611,11,Hangup
For versions of AAH before 2.8, once you've added this code using AMP->Maintenance->ConfigEdit->extensions_custom.conf, click the Update button to save your changes, and then reload your Asterisk settings: AMP->Setup->IncomingCalls->SubmitChanges and click the Red Bar. If you'd prefer a different extension (rather than 611), just modify the number in each line of the code above. If you're curious how to pass variables back and forth to a PHP/AGI script, here's a good example. In line 8, we're passing the variable ${APCODE} to the PHP/AGI script with the airport code. In lines 9 and 10, the PHP/AGI script is returning the ${TMPWAVE} variable with the file name of the .wav file containing the weather report. Now let's add the PHP/AGI script to your default AGI directory, and we'll be ready to test things out.
Downloading and Installing nv-weather.php. To get the PHP/AGI script installed, you'll need to log into your Asterisk server as root. Then issue the following commands in order:
cd /var/lib/asterisk/agi-bin
wget http://nerdvittles.com/aah2/nv-weather.zip
unzip nv-weather.zip
rm -f nv-weather.zip
chown asterisk:asterisk nv-weather.php
chmod 775 nv-weather.php
amportal stop
amportal start
Taking NV-Weather for a Spin. Now we should be all set. Just pick up an extension on your system and dial 611. You'll be prompted to enter the three-character airport code. Choose one that's in the supported list of codes unless you just like the Atlanta weather report. If you want the rest of the world to be able to use your fancy new weather station, then just sign up for a free incoming line with Stanaphone and, using AMP or freePBX, point your new DID to extension 611 on your local Asterisk system. Piece o' cake! Enjoy!
Housekeeping 101. Temporary files in /tmp get cleaned up by Linux housekeeping automatically. Temporary files stored elsewhere don't. The weather scripts have to store .wav files in the /var/lib/asterisk/sounds path in order to play them from within your dialplan, but it's a good example of how not to design code on busy systems because it places all of the temporary sound files for each reading of these weather reports in /var/lib/asterisk/sounds/tts. So, from time to time, make a mental note to remove all of these files with a command like this:
rm -f /var/lib/asterisk/sounds/tts/*
Following our article last week, there were a few suggestions on how to automate this with a cron job. Here's the one we like the best. Log into your Asterisk server as root and edit the following file: nano -w /etc/crontab. Move to the bottom of the file and insert the following code on a blank line:
3 0 * * * /usr/bin/find /var/lib/asterisk/sounds/tts -type f -mtime +14 | /usr/bin/xargs /bin/rm -f >/dev/null 2>&1
This code will delete all of the files in the tts every two weeks. If you'd prefer a shorter time, change the number 14 accordingly. Now save your changes: Ctrl-X, Y, then Enter.
Coming Attractions. Well, we're down to the wire on the family move to Charleston. Our next column will be coming to you from there. We'll be revving up our text-to-speech series with an article on using Flite to query and retrieve information from a MySQL database on your Asterisk server in our next episode. This will also be Part II of the Weather Application with the Mother of All Weather Apps. In Part II, we'll turn over complete control of the National Weather Service to you (well, almost!). There will be separate options for Current Conditions, Forecast-at-a-Glance, and 7-day Forecasts. The way it works is you'll get a MySQL database with every airport in the United States. There are about 3,500 of them. You can designate up to 1,000 of them for active use from your phones: 000 through 999. We've chosen a thousand, but you can change them in any way you like and as often as you like. After choosing your favorite 1,000 airports, you simply pick up a phone, dial 611 and enter the three-digit airport code. After giving you a quick current conditions summary, you'll be prompted for which detailed weather report you desire. The script will query the MySQL database for the matching code, contact the National Weather Service for the appropriate report, and presto: instant weather. And it'll all be done from Weather Central: Your Very Own Asterisk@Home Server. So think of today's episode as the appetizer. With the next version, you'll get complete control of the airport database and the types of weather forecasts you wish to listen to. We'll also have lots of tips on building MySQL applications with Asterisk and PHP to keep you busy for the rest of the summer dreaming up your own applications. We'll even publish the best ones here for the rest of the world to share.
Farewell to Asterisk@Home. It's also fitting that, as we leave Atlanta, we also bid farewell to Asterisk@Home this week. Version 2.8 marks the end of the line for Asterisk@Home. Why? Because the scope of use of the product now has far outstripped its name, Andrew Gillis has decided to change the name of the magic bundle we all know and love. But there's much more! The new product will have UPGRADE POWER and freePBX 2.1 and ... well, you'll just have to wait and see. Shouldn't be very long. So we'll all be very busy ... after the move. AdiĆ³s Atlanta!
Homework. For those that like to get a head start on things, you can go ahead and download the MySQL Airports IATA database and a web-based script to take a look at everything. You'll need Asterisk@Home 2.7 or earlier to edit the database because these versions include phpMyAdmin as part of the Asterisk Management Portal (AMP->Maintenance->phpMyAdmin). Download the zipped airports file to your desktop and unzip it. This database is licensed pursuant to a GNU General Public License. It was adapted from the AirSort application on SourceForge if you happen to be looking for a MySQL database containing worldwide airport (iata) codes. Now crank up phpMyAdmin and click on the SQL Query Window icon in the top of the left frame. Now click on the Import Files tab, select the airports.sql file on your Desktop, set the Character Set to ASCII, and click the Go button. Once the file is imported, click on the Home icon in the left panel, click on the Databases pull-down, and choose Airports. Then click on the USairports table below it. When the table opens, click on the Browse tab in the right frame to display the file's contents. Nome is the airport name, iata is the airport code, dialcode is the airport code converted to numbers on a touch-tone phone, citta is the city and state of the airport, and main is the field used to designate whether a particular airport can be accessed using a phone. An asterisk means Yes. Anything else means No. Now click on the DialCode column heading to sort the table by dialcode. As you scroll through the database, you'll see that every group of matching dialcodes has one entry with an asterisk in the main column. Remember that dialcodes are not unique while airport codes (iata) are. Because of the layout of the alphabet on touchtone phones, as many as a dozen airport codes may share the identical dialcode which is why we need the main field to pick one. As mentioned above, I've already picked one for each dialcode, but you may have your own ideas about which airports to make active depending upon where you live and what cities you care about. If you change the main entry for a dialcode, remember to also blank out the previous one for that dialcode. Otherwise, the last dialcode entry with an asterisk in the main column will win (i.e. that's the city whose weather report will be played) once the application is finished. So there's your homework. Get your airports database set up in a way that meets your needs so that the dialcodes 000 through 999 select the airport locations of interest to you. Don't mess with the iata codes. Even though the database doesn't enforce it, these are unique and need to stay that way.
In designing this new application for telephone use, it was tempting to support all of the airports in the United States rather than a measily 1,000 of your favorites. To do this, however, would have meant using either zip codes or giving callers a submenu of airport code cities matching a particular dialcode. We ruled out zip codes because nobody can remember more than a handful of them anyway. The dialcode submenu sounded straight-forward enough until we discovered there were some dialcodes with a dozen or more matching airport codes. To force callers to listen to a list of a dozen cities before ever getting to choose a weather report would have been P-A-I-N-F-U-L. So we've opted for the Fab 1,000 thinking that will meet the needs of most folks. As usual, you are free to make changes in the final software to meet your needs. And, if IVR Hell, long phone calls, and 3,500+ airports at the touch of (lots of) buttons are your thing, have at it!
To assist with your exploration of the airport codes and to give you some hints about how we use those to actually obtain weather reports from the National Weather Service, we're also providing our working prototype of a web page that retrieves weather reports. Keep in mind that it is our very rough, working prototype and does no text-to-speech magic at this point. But it'll show you how to build one and give you some great tips and tricks for retrieving, parsing, and manipulating web site data within a PHP script. Since your Asterisk@Home server has Apache running, you can simply drop this script into the web directory and access it using a web browser to call up http://YourServer'sIPaddress/airport.php?code=list or http://YourServer'sIPaddress/airport.php?dialcode=list. The former will display all the airports in the database while the latter displays only those in which the dialcodes are asterisk-enabled. When you click on a link, you should get a weather report or two suitably parsed for use in text-to-speech apps as well as some other options which we haven't yet finished. To install the script, log into your Asterisk server as root and execute the following commands in order:
cd /var/www/html
wget http://nerdvittles.com/wp-content/airport.zip
unzip airport.zip
rm -f airport.zip
chmod 775 airport.php
For Part II of this series, click here.
Hosting Provider Special. Just an FYI that the Nerd Vittles hosting provider, BlueHost, has continued their limited time special on hosting services. For $6.95 a month, you can host up to 6 domains with 15GB of disk storage and 400GB of monthly bandwidth. Free domain registration is included for as long as you have an account. It doesn't get any better than that, and their hosting services are flawless! We oughta know. We've tried the best of them. If you've never tried a web hosting provider, there's never been a better time. Just use this link, and we'll all be happy.
Nerd Vittles Fan Club Map. Thanks for visiting! We hope you'll take a second and add yourself to our Frappr World Map compliments of Google. In making your entry, you can choose an icon: guy, gal, nerd, or geek. For those that don't know the difference in the last two, here's the best definition we've found: "a nerd is very similar to a geek, but with more RAM and a faster modem." We're always looking for the best BBQ joints on the planet. So, if you know of one, add it to the map while you're visiting as well.
Want More Projects? For a complete catalog of all our previous Asterisk projects, click here. For the most recent articles, click here and just scroll down the page.
Headline News for the Busy Executive and the Lazy Loafer. Get your Headline News the easy way: Planet Asterisk, Planet Gadget, Planet Mac, and Planet Daily. Quick read, no fluff.
Got a PDA or Web-Enabled Smartphone? Check out our new PDAweather.org site and get the latest weather updates and forecasts from the National Weather Service perfectly formatted for quick download and display on your favorite web-enabled PDA, cellphone, or Internet Tablet. And, of course, it's all FREE!
What a great project, I can hardly wait for part 2. As always, you rock Ward. Myself, I think it would be be better to use zipcode rather that airport code, just like 1-800-555-tell (Tell-Me). Or an even more interesting idea, have it look up your caller-ID and use the NPA-NXX to give you a weather forecast for your area (of course that is USA only) and a menu to then get one for another area if you wish. I will have much to play with in this one.
[WM: The NPA-NXX idea sounds great. I actually have the database with 142,000+ records so I’ll put that on the TO-DO list … after the move.]
Another Great Hit from Ward Mundy!!! I’ll have to wait to version 2 for this version does not support any airport weather in Puerto Rico. Anyway I am going to start flirting with this code and the V2 Preview given here to see if I can get any more ideas of what to do with Flite TTS. Thanks again Ward!
PS Any ideas on how to integrate a code like this (to get MySQL data and read it) and the Teleyapper (as for to get the teleyapper to read some info from the DB)?
[WM: Sorry but I left Puerto Rico out of the original Airports database although I’ve fixed it now. So either download the zipped file again or add an entry like this to your original copy. The "United States" addition to the city is required because of the parsing algorithm. My apologies.]
nome: Luiz Munoz International Airport
iata: SJU
citta: San Juan, Puerto Rico, United States
dialcode: 758
main: *
Another great article. Do you know if the new-and-improved AAH productline will have A2billing latest version, or another such billing solution in it?
[WM: No clue on that one. Sorry.]
How about using Zip code instead of airport code? No need to do a letter to number conversion of the need to know the airport codes, and data is readily available down at the zip code level. All numeric input is a win too.
Thanks,
Mike
[WM: Let’s get the next one out the door. Then we’ll talk about enhancements.]
Actually, what would be nifty would be to include the latitude and longitude for each airport in the database. It would then be a simple matter to cross-reference the latitude and longitude for a given Zipcode, and find the weather for all airport locations within an arbitrary (prompted) distance. For example, I could enter ‘16066’ and get the weather forecast from both Pittsburgh, PA (30 miles) and Youngstown, OH (60 miles).
[WM: The original database actually had the latitude and longitude data, but it didn’t have the zip codes. If someone can point us to a MySQL database that cross-references the two, then I’ll be glad to put it on the wish list. I just don’t want to spend my days entering zip codes for the entire country.]
Two comments: First, I hope that after you get settled in your new location, you will consider showing us non-geeks how to add or use better voices. The best voices I have heard so far are the Cepstral voices but unfortunately they are not free (although they can be used in a demo mode without registration, but I think something is added to the speech to nag you into registration). Anyway, whether using Festival or Flite, we need better voices, but we also need a step-by-step method to install them under Asterisk@Home.
Now, on a completely different note, you have probably heard that Skype is allowing outgoing calls to the U.S. and Canada for free until the end of the year. Unfortunately Skype uses a proprietary protocol not supported by Asterisk. But I was wondering if it might be possible to use the Skype to SIP Adapter software at http://www.nch.com.au/skypetosip/index.html (perhaps with a SIP softphone of some kind) to create a gateway that Asterisk could use to place free outgoing calls via Skype. I have never personally used Skype (I hate using any type of "softphone" with a passion) but if there was a way to route outgoing calls from Asterisk to Skype for free, especially for home users, that might be of some interest to your readers.
Of course I really wish someone would develop a way to do this natively (within Asterisk itself) but apparently even the existence of a bounty hasn’t yet been sufficient to induce someone to develop that. Supposedly there is a project under development but at this point that is vaporware. But we can always hope!
[WM: Found this recent VoipPhreak article on Cepstral that you may want to take a look at.]
Ward,
You are kickin butt with these great applications! I would like to add something to a "wish list" if possible…and that would be an application where someone could call in and locate the cheapest gas in a given zip code. Maybe open up the database to volunteers so as to keep the gasoline prices and locations updated.
Thanks a ton for the great applications!
Mike C.
Zipcode??? I say use the ICAO code and that way us non-North American viewers can get in on the act. I already have the weather script reading out the observation for my local airport (EGKB) but having that observation decoded sensibly would make life easier on my housemate.
Take a peek at http://www.cfdynamics.com/cfdynamics/zipbase/index.cfm
Quoting from the website:
This database is provided free to anyone who wants it with the request that anyone who benefits from it please drop me a quick email and let me know how you’re using it. Also, if you wish to contribute to this project or improve upon the database that is also welcome…
Database Fields: ZIP, LATITUDE, LONGITUDE, CITY, STATE, COUNTY, ZIP_CLASS
[WM: Thanks, Amy. The file looks almost perfect. I’ll put it on my TO-DO list for Part III. Zip codes will be a good addition.]
I just came across a way to restore access to some of the "missing" Asterisk@Home pages after you’ve upgraded FreePBX to version 2.1.0 – I posted abut it in my blog, here:
http://michigantelephone.mi.org/blog/2006/05/restoring-asteriskhome-modules-lost.html
Just remember, I didn’t write the shell script, so the only thing I can tell you is it worked for me!
I just submitted a comment under Putting Real Names Back in CallerID: 3 Quick Perl Solutions for the Asterisk PBX in which I show how to make the routine work under FreePBX 2.1.0 (in case you have upgraded). In addition I have also modified the calleridname.agi routine itself to do some additional types of lookups (including Canadian numbers, for those who wanted that) and in some cases to work a bit faster.
Hey Ward… How did the move go? Also what happened to the site a couple days ago?
Anyway just writing to ask if you have any plans to port all the great goodies you provide us with to the new Trixbox (http://www.trixbox.org). Thanks again for all your help!
[WM: Move went great. Still knee-deep in boxes. Yes, everything will be ported to TrixBox. As for a couple days ago, I’ll save that for a future column.]
I still can’t get weather for SaaTac (SEA/732). Works for other cities though. Any ideas what the problem might be?
[WM: Yeah. Something is wrong with the NWS site information for Seattle/Tacoma for current conditions. If you’ve loaded the database and test app, you’ll note that the current conditions report returns all NULLs, but the Forecast At A Glance and 7-Day Forecast both work fine. The price we pay for free, I guess.]
Any chance of how to configure the weather for other places in the world besides the states….I know there are a lot of you, but people outside of the good ol’ U.S of A also use asterisk/trixbox you know!
Any chance you could add Spokane, Washington (GEG) to the list?
Thank you!
I think we are all loving these data to voice apps but what about a real challenge?
Voice recognition instead of pressing buttons on the handset?
We use Teleyapper to broadcast to mobiles; problem is it’s almost impossible to detect if the phone was answered or the networks voice systems stepped in but voice recognition could be a way.
On the forums there is some fuzzy voice recognition work but nothing serious or am I looking in the wrong place.
Keep up the good work.
Regards,
Ian
[WM: Great idea. And you’re looking in the right place. We just haven’t found an open source voice recognition system that works reliably yet. But soon, I’m sure.]
Ward,
Could you give a pointer on how to add an airport? I am missing LAX and would like to add it.
[WM: Crank up phpMyAdmin (http://YourServersIPaddress/maint/phpMyAdmin/) and choose the Airports database and the usairports table in the left frame. Click the Search tab in the right frame and enter 529 for the dialcode (Los Angeles is actually in the database along with most of the other U.S. airports). You’ll see that an asterisk is shown in the main field for Jacksonville. Edit that record and delete the asterisk. Then edit the Los Angeles record and insert an asterisk in the main field. Then dial 611 and enter L-A-X (529) for the airport code and voila.]
Damn, Canadian version works like a charm! Cheers!
[WM: Smokin’!]