Play It Cool: Incorporating Reporting Mechanisms from Physical Devices

Wednesday Aug 23rd 2006 by Steve Schafer
Share:

Learn how to collect external data then pass it on to other programs, systems, and users.

Thermal problems have been a major bane of computers since the very first computer was plugged into AC power. Despite server rooms with raised white flooring and high-end Leibert air conditioners, and over-clocked gaming rigs with water-cooling on the chipsets, heat continues to be a problem that computer administrators and technicians can't ignore.

In the first article of this series, Play It Cool: Remote Monitoring of Equipment Room Temps, a solution was presented for connecting a temperature gauge to your computer and then programmatically accessing it with a number of scripts. In this article, you'll explores how to monitor and report on this information. More importantly, you'll learn how to create a script to audibly announce the current temperature.

Note: This series of articles uses Linux as the operating system of choice, with scripts written for the shell (Bash) and in Perl. For the tasks outlined within this series, I found Linux to be ideal. If you are using a different programming platform, or if you are unable to replicate these methods on Linux, then you should still gain value from these articles. Where possible I will point out analogous possibilities in Windows and other operating systems.

Reporting Methods

At this point, I had a working sensor and script. Using a variety of methods, I could easily keep myself apprised of the current temperature of my office. The following sections discuss some of the possible reporting solutions.

Maintaining a Textual Log

At bare minimum, I wanted to keep a plain old text log of the temperature. The script shown in Listing 1 accomplishes this goal, with log entries similar to the following:

2006-07-26      15:30      73.7

Listing 1: Appending the current temperature reading to a log file

#!/bin/sh

logfile="/var/log/officetemp.log"

# Get the current date and time
date=‘date -I’
time=‘date +%H:%M‘

# Get the temperature
temp=’./get_temp.sh’

# Append data to log
echo -e "$datet$timet$temp" >>$logfile

With minimal effort, the same data could be stored in a MySQL database, thanks to the capabilities of the MySQL console application. The code snippet in Listing 2 shows the basics for inserting the data in a database by using the console-this snippet would be appended to the script in Listing 1.

Listing 2: Adding the data to a MySQL database

db="officetemp"
table="readings"
user="tempuser"
pass="goat"

cat <<QUERY >./query.tmp
USE $db;
INSERT INTO $db.$table VALUES ($date, $time,$temp);

QUERY

mysql -u $user -p $pass <./query.tmp
rm -rf ./query.tmp

Email Readings

The output from the reading script can easily be piped into a mailer. This allows the current temperature to be sent to any off-site address-including my cell phone. For example, consider the script shown in Listing 3.

Listing 3: Piping the temperature reading to an emailer (mail_temp.sh)

#!/bin/sh

# Email address to send to (my Sprint phone)
mailaddr="3035551212@messaging.sprintpcs.com"

# Get the temperature
temp=‘./get_temp.sh‘

# Build the message
cat <<MSG  >./message.tmp
The current office
temperature is:  $temp

MSG

# Send message and clean up
mail -s "Current Office Temp" $mailaddr <./message.tmp
rm -rf ./message.tmp

With a little extra coding only temperature readings over a certain threshold would be emailed. For example, the following if() clause could be used to decide whether a message should or should not be sent:

threshold="77"
result=`echo "$temp >= $threshold" | bc‘
if [ "result" = "1" ] ; then
  # Email temperature
else
  # Do not email temperature
fi

Place Temperature Reading on Web Page

The output could also be redirected to a Web page, where I could monitor it from any terminal with an Internet-connected browser. Listing 4 shows a script to accomplish this task.

Listing 4: Placing the temperature reading on a Web page (web_temp.sh)

#!/bin/sh

# Get the current date and time
date=‘date -I‘
time=`date +%H:%M`

# Get the temperature
temp=‘./get_temp.sh‘

# Place temp on an HTML page
cat <<HTML >./officetemp.tmp
<html>
  <body>
    

$date $time - $temp

</body> </html> HTML mv ./officetemp.tmp /var/www/officetemp.html

This script creates a simple Web page with the data in a format similar to the following example:

2006-07-28  15:25 - 73.4

The Same Old Problem

As these examples have shown, the structure for the temperature reading is very flexible-the data can be sent easily to numerous places. However, therein lies the problem-I still had to be physically located at or have access to the places where the data was sent, and had to actively monitor the temperature. What I needed was a way to monitor the temperature passively. The solution hit me while listening to a grandfather clock.

"The Current Core Temperature Is…"

I decided to create an audible temperature notification. That is, at preset intervals the computer would speak the temperature-loud enough to be heard in and around the office, but not loud enough (or often enough) to be an annoyance. Then, just like the grandfather clock chimes, I could be aware of the temperature of my office without actively having to seek it out.

The first thing I needed was a voice. Being a geek and a science fiction fan, I settled on a female computer voice. I asked my wife to record the following sound files, which I converted to standard WAV format:

core.wav
"The current core temperature is"

degrees.wav
"degrees"

60.wav, 70.wav, 80.wav
"sixty," "seventy," "eighty"

1.wav, 2.wav, 3.wav, 4.wav, 5.wav, 6.wav, 7.wav, 8.wav, 9.wav
"one," "two," "three," "four," "five," "six," "seven," "eight," "nine"

point.wav
"point"
Note: I could afford to be fairly selective in my recording, as I didn't expect the temperature to fall below 60 degrees or exceed 89.9 degrees.

Now I needed a script to break down the temperature reading into bits that could be mapped to the appropriate sound files, and a command-line WAV player to play the files in sequence.

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:

  1. Read the temperature.
  2. Play the intro bit ("The current core…").
  3. Get the first digit (tens).
  4. Append a zero (to match the appropriate sound file).
  5. Play the tens file.
  6. Get the next digit (ones).
  7. Play the ones file.
  8. Play the "point" file.
  9. Get the last digit (decimal).
  10. Play the ones file corresponding to the decimal digit.
  11. Play the "degrees" file.

For example, suppose the temperature reading was 72.8 degrees. The process just described would then give me this result:

  1. Read the temperature (72.8).
  2. Play core.wav ("The current core temperature is…").
  3. Get the first digit (7).
  4. Append a zero (70).
  5. Play the tens file (70.wav).
  6. Get the next digit (2).
  7. Play the ones file (2.wav).
  8. Play point.wav.
  9. Get the last digit (8).
  10. Play the ones file corresponding to the decimal digit (8.wav).
  11. 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.

Share:
Home
Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved