I’ve been fiddling around with Asterisk on a slug box. It’s working pretty well, but since I don’t want to deal with compiling things for the slug, I’m limited to the Asterisk modules that are available as binaries (not many). I’m also using the older Asterisk 1.2. This has led to some interesting hacks to make things happen. The end result of a lot of this hacking is a dialplan-shellscript-sed combo to read out some basic weather forecast info acquired from Yahoo.
First, the dialplan.
-
exten => s,1,Set(defaultWeatherZip=10001)
-
exten => s,n,Playback(please-enter-your&zip-code)
-
exten => s,n,Read(zip||5)
-
exten => s,n,GotoIf($[${LEN(${zip})} = 5]?getweather)
-
exten => s,n,Set(zip=${defaultWeatherZip})
-
exten => s,n(getweather),System(get_weather.sh ${zip} > /tmp/weather-${UNIQUEID}.tmp)
-
exten => s,n,Readfile(weather=/tmp/weather-${UNIQUEID}.tmp,300)
-
exten => s,n,Playback(weather&for&zip-code)
-
exten => s,n,SayDigits(${zip})
-
exten => s,n,Playback(silence/1&${weather}&silence/1)
-
exten => s,n,System(rm /tmp/weather-${UNIQUEID}.tmp)
If you’ve got a text-to-speech engine and can create smoother strings of spoken words than what I’ve strung together here, you’re better off (on my Asterisk box, I’m actually using files I made with Cepstral’s Allison-8k running on my Mac). With my limited command set, there’s no nice way to grab the output of a system command, so I capture it into a temp file, use ReadFile() on the temp file, then delete the temp file.
That dialplan called a shellscript, get_weather.sh:
-
echo -n
-
`curl –silent http://weather.yahooapis.com/forecastrss?p=$1
-
| sed -n -f /opt/var/lib/asterisk/yahoo_weather_to_asterisk.sed
-
| sed -e 'N;s/(.*)n(.*)/1&silence/2&2/'`
This uses curl to get the weather from Yahoo, runs it through a complicated sed program which yields two lines of forecast (as &-joined lists of sound files, suitable for running as an argument to Playback() in Asterisk), then joins the two lines with 2 seconds of silence. The “echo -n `…`” is a trick for stripping the trailing newline from the output of curl/sed (a newline inside the Playback() get interpreted as part of the filename, which it isn’t).
Finally, the sed program that processes the output from Yahoo:
-
/^<yweather :forecast/{
-
# replace days with sound files
-
s/Mon/day-1/
-
s/Tue/day-2/
-
s/Wed/day-3/
-
s/Thu/day-4/
-
s/Fri/day-5/
-
s/Sat/day-6/
-
s/Sun/day-0/
-
-
# replace months with sound files
-
s/Jan/mon-0/
-
s/Feb/mon-1/
-
s/Mar/mon-2/
-
s/Apr/mon-3/
-
s/May/mon-4/
-
s/Jun/mon-5/
-
s/Jul/mon-6/
-
s/Aug/mon-7/
-
s/Sep/mon-8/
-
s/Oct/mon-9/
-
s/Nov/mon-10/
-
s/Dec/mon-11/
-
-
# rearrange forecast lines
-
s/^<yweather:forecast day="(day-[0-6])" date="([0-9]*) (mon-[0-9]*) ([0-9]*)" low="([0-9]*)" high="([0-9]*)" .*/>/digits/1&digits/3&DATE-2&silence/1&high&TEMP-6&silence/1&low&TEMP-5/
-
-
# replace the date with proper ordinal sound files
-
# thirty + one is a special case
-
s/DATE-31/digits/30&digits/h-1/
-
# twenty + [1-9]
-
s/DATE-2([1-9])/digits/20&digits/h-1/
-
# 1-20,30 all have their own files
-
s/DATE-([0-9]*)/digits/h-1/
-
-
# negative temps
-
s/TEMP–/minus&TEMP-/g
-
-
# 100 is a special case
-
s/TEMP-100/digits/1&digits/hundred/g
-
# 10?
-
s/TEMP-10([1-9])/digits/1&digits/hundred&digits/1/g
-
# 11?
-
s/TEMP-11([0-9])/digits/1&digits/hundred&digits/11/g
-
# 1?0
-
s/TEMP-1([2-9])0/digits/1&digits/hundred&digits/10/g
-
# 1??
-
s/TEMP-1([2-9])([1-9])/digits/1&digits/hundred&digits/10&digits/2/g
-
# 1?
-
s/TEMP-1([0-9])/digits/11/g
-
# ?0
-
s/TEMP-([2-9])0/digits/10/g
-
# ??
-
s/TEMP-([2-9])([1-9])/digits/10&digits/2/g
-
# ?
-
s/TEMP-([0-9])/digits/1/g
-
-
p
-
}
The “rearrange” line does most of the work of taking apart the last bits of what Yahoo gave us; the rest of the sed program is dominated by converting months/days/numbers into references to the appropriate Asterisk sound files. [Note: Since I only had today's data with which to work, I made some guesses as to what the shortened forms of most of the months and days would be, as well as how temperatures that weren't two-digit positive numbers would be presented.]