Intro: Raspberry Pi Controlled Room Temperature Monitoring With Gnuplot Image Output and Email Alert Ability
Where I work, there is a very important room which houses lots of computers. The ambient temperature of this room has to be very cool to optimize performance of these systems.
I was asked to come up with a monitoring system which has the ability to send some form of alert to a few people that will notify them that something is wrong with the air conditioning in that room.
The hardware for this build, I used Raspberry pi and a USB temperature and humidity sensor.
For monitoring, I used Gnuplot to plot three temperature graphs and create image of those graphs. I then created a dedicated HTML page that will be hosted on the Raspberry pi so the present conditions, those gnuplot output images, can be monitored from a web page within our network.
For alerting I opted to go with Gmail. I had found some example code in a Linux User magazine. (Of course you can use any mail server once you know the necesary port assignments. )
For that I created a dedicated Gmail email account for these alerts. Also as an added feature, when an alert has been triggered, I attach one graph to the email so the person receiving the email can get an idea of how drastic an increase it was that has caused the alert.
Step 1: The Hardware Setup
There isn't much to setting up the hardware. The Raspberry pi is running Raspian and the USB temperature sensor simply plugs directly into one of the USB ports.
The power consumption of this sensor is minimal and as a result I powered it directly from the Raspberry pi. However, for USB powered devices with a bit more power consumption, I would recommend powering them through a powered USB hub and not directly from the Raspberry pi's USB port.
Once the temperature sensor is powered, it provides a serial string which contains the temperature and humidity readings of the current conditions.
temperature=20.9°C humidity=62.7% dewpoint=13.0°C
A python script parses this string and stores the temperature and humidity values into three text files every five minutes; a daily, 24 hours and 48 hours text files (The differences will be discussed later in the HTML section). From these files, Gnuplot will generate the graphs and subsequently the images of the data set in each file.
Before I discuss the python script I will talk about preparing the Raspberry pi.
Since the monitoring is to be done online, a web server needs to be installed. I've tried a few of them in my time on the Raspberry pi but although it's a bit big I prefer Apache. To install Apache on your Raspberry pi you simply type:
sudo apt-get install apache2
It will give you a prompt before it installs, press "y" for yes and
and Apache will be installed a few minutes depending on your Raspberry pi.
Once that is done, you have to install two python plug-ins: python-serial and the python-gnuplot plug. (Although I have realised that recent Raspian builds has the python-serial plug-in standard but just to be safe.)
To install those you type:
sudo apt-get install python-serial python-gnuplot
Once again after acknowledging the prompts, these plug-ins will be installed.
And with that the hardware setup is complete.
Step 2: Software Setup - Email Setup and Recipients
create email address
Before we get too far into the software now would be a good time to create a Gmail account to send your email alerts from. (This example uses GMail but any mail server can be used once our know the smtp port settings)
The python code is pretty straight forward but the imports needed are critical. Without them nothing would work.
from time import *
Finally, the mailing list. Of course we have to add the recipients of the email. Each email address is saved in a variable.
from_address = 'email@example.com'
to_address1 = 'recipient1.mail.com'
to_address2 = 'recipient2.mail.com'
username = 'firstname.lastname@example.org'
password = 'custom_email_password'
Step 3: Software Setup - Serial Setup and Parsing
Next we look at the serial setup.
It's just a matter of setting up parameters that matches the serial output from the sensor. The sensor outputs a serial string at 9600 8 N 1 which is a standard format.
After the string has been received there are several ways of parsing this string in python and quite possibly more reliably. The way I do it is to look for the "temp" characters in the serial string. Once located it is simply a matter of reading the next 46 serial characters into a string.
The collected string can now be addressed like elements in an array. The desired data is parsed out from the string and saved to the three files along with its corresponding time stamp.
timestamp = strftime("%d%b%Y %H:%M:%S ",localtime())
Step 4: Software Setup - Gnuplot
Gnuplot is a command line graphical tool. Once you have figured out the basics it can be a pretty powerful tool for graphical display of data sets.
Gnuplot can plot directly from a formatted text file and we just so happen to have one from the parsing step before.
Once we indicate to gnuplot where in the file the data is located we can plot the desired values. I am going to use time on the X axis and our temperature on the Y axis.
Plotting time from my experience is the most difficult as you have to get the time format in gnuplot to match the format of the text file.
After all the graphing options are complete and to your preference, Gnuplot can then create an image of this graph. This will be the image that we will use on our Web page later. I opted to go with a .png image and since I want to replace the old image on the Web page, each image has the same name so this line of code doesn't have to change.
Image size setting is linked to html page optimization. I first played around with standard sizes then experimented to make the image fit my screen. For this project, I am not storing old images so the physical sized of the file in storage is not a major factor on precious Raspberry pi storage.
Here is a code snippet to create and store the daily.png graph image.
g = Gnuplot.Gnuplot(debug=debug)
g('cd "' + path + '"' )
g('set xdata time')
g('set timefmt "%d%b%Y %H:%M:%S"')
g('set format x "%H:%M\\n%d%b"')
g('set title " Daily Current Temperature Display"')
g('set key off')
g('set grid') g('set xlabel "Time\\nDate"')
g('set yrange [15.0:35.0]')
g('set ylabel " Temperature "')
g('set datafile missing "NaN"')
g('set terminal png size 800,400')
g('set output "daily.png"')
g('plot "daily.dat" using 1:($3) with lines')
NOTE: The line that reads g('set datafile missing "NaN"'), the purpose of this line is to plot a blank space in the plot. The "NaN" variable is written to the file if the python script detects anything weird for a given reading or a serial transmission.
As you can see from the three graphs above, the daily.png gives you a current time display of the data whereas the 24_hour.png has the same information displayed on a 24 hour scale. The 48_hour.png graph shows your the last 48 hours worth of data from the sensor.
Step 5: Software Setup - Threshold Setting and Emailing
The threshold for the alerting has to be done by trial and error for your setup. the room which houses the systems has no windows so once the air conditioning stops it can get very hot very fast. Initially I looked at the data set for a few days and watched the variations in temperature before I decided upon the alert value of 30 degrees C. This is set as a variable within the python scipt. This might not seem very high but once the alert has been triggered you still want to give yourself time to rectify the problem before it becomes critical.
For simplicity, I am sending individual emails to the mailing list. Since the mailing list is short I never bothered with sending one email to several recipients.
One thing to note here, Since I am running this script as a cron job every 5 minutes, you don't want to be sending emails every 5 minutes once the threshold has been triggered. To get around this, I write the date and time of the alert to a file and check this file before sending any emails to see if the system is already in an alert state. Once in an alert state, it will only resend an email every hour after the first trigger for as long as the system is in and alert state. That way Gmail doesn't block your email from sending too many emails in a short period of time.
Step 6: Software Setup - HTML
The monitoring of the entire system is done via a web page and a very basic html script is needed for this. The images that Gnuplot created I just simply use back the same dimensions of the image. I believe I went through about 3 sizes for these images which gave the best fit on my screen.
Before we create the html script let's create a folder for it. By default the web hosting folder is located at /var/www/. Although this Raspberry pi ' only purpose is to monitor this room and issue email alerts, for good house keeping I created a separate folder in the /var/www/ folder. Since this folder belongs to the root user you have to use sudo to create a folder is this location.
sudo mkdir /var/www/temperature
In this example I used temperature as the name of the folder but you can use any name here but remember as this will have to be entered into the address bar to view this page. This path is stored in a variable within the python script. In the even that the hosting location has to be changed or the script has to be modified for another system, it can be just changed from this one location.
Now we can create our html script in this folder remembering to use sudo infront any commands you want to execute in here. I would recommend you naming the html script "index.html" as this would simplify this when trying to find this page.
The critical thing is to make sure that the image sizing is the same as the image size from Gnuplot.
To view this page, you simply have to enter the IP address of the Raspberry Pi followed by /temperature (or what ever you named your folder)
I have several systems at work monitoring different things and they all produce some graphical output of their results. So I created a page that has links to all of these pages so I don't have to worry about entering the address every time I want to access these pages.
Step 7: I'm Alive....
I've used this to monitor the temperature in a computer room but this could have been pretty much data from any source.
Once it can be stored in a text file and you know it's format Gnuplot can do the rest.
One thing I added recently to this project is to send a "heartbeat" email of sorts. That is on the first of the month at 9am I have a script that runs that emails the mailing list to let them know they the system is running as it should and all is well in the room.
Using the cronjob listing as:
0 9 1 * * /home/pi/Location/To/Script/monthly_email.py
Marvin works at the Caribbean Institute for Meteorology and Hydrology where he works as a Technical Officer (I) in the Instruments Section. He is also a member of the Research and Development team at the Institute.