Play It Cool: Incorporating Reporting Mechanisms from Physical Devices, Page 2
Again, in Linux, my choices were abundant. I settled on the wavp (wav play) utility, part of the Wav-Tools package, for playing the voice samples. As for decoding the temperature setting, the string-handling tools in awk proved more than adequate.
The process for my script would look like this:
- Read the temperature.
- Play the intro bit ("The current core ").
- Get the first digit (tens).
- Append a zero (to match the appropriate sound file).
- Play the tens file.
- Get the next digit (ones).
- Play the ones file.
- Play the "point" file.
- Get the last digit (decimal).
- Play the ones file corresponding to the decimal digit.
- Play the "degrees" file.
For example, suppose the temperature reading was 72.8 degrees. The process just described would then give me this result:
- Read the temperature (72.8).
- Play core.wav ("The current core temperature is ").
- Get the first digit (7).
- Append a zero (70).
- Play the tens file (70.wav).
- Get the next digit (2).
- Play the ones file (2.wav).
- Play point.wav.
- Get the last digit (8).
- Play the ones file corresponding to the decimal digit (8.wav).
- Play degrees.wav.
The net result is the following wav files being played in succession:
core.wav, 70.wav, 2.wav, point.wav, 8.wav, degrees.wav
and the following phrase being heard:
"The current core temperature is seventy two point eight degrees."
Using the substr() function of awk, I could easily step through the temperature reading, character by character. With a little ingenuity, I could map the appropriate sound file to each character and create the phrase I needed. Listing 5 shows the complete script.
Listing 5: Script to "say" the temperature aloud (say_temp.sh)
#!/bin/sh
# Set up vars
DIR="~/officetemp"
date=`date`
# Is script already running?
if [ -f $DIR/saying.lock ]; then
exit
fi
# Lock process to avoid audio overlap
touch $DIR/saying.lock
# Was a temperature passed from command line?
if [ "$1" != "-l" ] && [ "$1" != "" ] ; then
temp=$1
else
# If not, get latest from text log
temp=`tail -n1 $DIR/temp.log | awk '{ print $3; }'‘
fi
# Sometimes wavp hangs around in memory, choking off new
# processes (seldom seen, but maddening when it happens)
# If there's a wavp process hung somewhere, kill it and report
wavproc=`ps -A | grep "wavp" | awk "{ print $1; }"‘
if [ "$wavproc" != "" ] ; then
kill -9 $wavproc
echo -e "$date - WAVP Process Killed!n" >>$DIR/errortemp.log
fi
# Begin with "The current core temperature is"
echo -e "The current core temperature is: "
wavp $DIR/wavs/core.wav >/dev/nul
# If last character is "0", remove it and decimal (period)
# (avoid saying "point zero")
lastchar=`echo "$temp" | awk '{ print substr($1,length($1),1); }'‘
if [ "$lastchar" = "0" ] ; then
temp=`echo "$temp" | awk '{ print substr($1,1,length($1)-2); }'‘
fi
# Get length of temperature string
len=`echo $temp | awk '{ print length($1); }'‘
# Step through the temperature string, character by character
x=1
while [ ! $x -gt $len ]
do
# Get current character
char=`echo "$temp $x" | awk '{ print substr($1,$2,1); }'‘
# On first character (tens), add a zero
if [ $x -eq 1 ] ; then
char=`echo "${char}0"‘
fi
# Is character a decimal ("point")?
if [ "$char" == "." ] ; then
char="point";
fi
# Echo char to console and speak appropriate wav
# (Avoid an extra "zero" after whole numbers, eg. Avoid
# "70" sounding like "seventy-zero")
echo $char
if [ "$char" != "0" ] ; then
wavp $DIR/wavs/${char}.wav >/dev/nul
fi
# Next character
x=`echo "$x + 1" | bc‘
done # End of stepping through string
# End with "degrees"
echo -e "degreesn"
wavp $DIR/wavs/degrees.wav >/dev/nul
echo -e "n"
# Remove lock
rm -f $DIR/saying.lock
Note: Astute readers might have noticed the absence of a 0.wav ("zero") in the list of wav files earlier in this article. Originally an unintentional omission, the mistake ended up being fortunate. It caused me to consider whether "zero" was ever really necessary in this scheme. For example, I'd much rather hear "seventy-five degrees" than hear "seventy-five point zero degrees." It's absence also made it easier to deal with temperatures at 60, 70, and 80 marks, eliminating the potential "70" reading decoding to "seventy-zero." Hence, the additional coding and the continued absence of a "zero" wav file.
The script was set to run every 20 minutes-giving me ample chance to hear it and react if the temperature reached inappropriate levels. Using various tools, I eventually tailored the script scheduling to run a little less often-once an hour-and not at all during the night, as long as the temperature remained below a certain threshold.
Next Time
This article showed how an audible notification was built for the temperature sensor. The next article in the series replaces the aging and somewhat faulty Kermit temperature reading script and adds an "on demand" hardware notification button. The last article in this series will show how the data can be sent to various reporting applications so it can be charted and trended appropriately.
About the Author
Freelance consultant Steve Schafer has written multiple technology
books and articles. In the business world, he most recently worked
in-house as COO/CFO of Progeny Linux Systems in Indianapolis. Serving
as president and CEO in the company's startup years, Steve led
Progeny's business and financial turnaround during the tech crash of
the early 2000s. Prior to joining Progeny, he was a senior title
manager for Macmillan Digital USA, overseeing the operating system
and entertainment software products and tripling Macmillan's Linux
product line revenue. He partnered Macmillan with Mandrake, bringing
Mandrake's Linux distribution to the competitive retail market.
