[Tutorial] Check CPU temperature and send warning mail

This tutorial guides you through the steps to set up a simple script that monitors your Raspberry’s CPU temperature and automatically sends emails as long as the CPU temperature exceeds a threshold defined by you. Of course, after you set up everything, you can use the mailing feature for other mail notifications, too.

To be able to send emails you need a mailing agent on your Raspberry next to a SMTP server.

SMTP server:
I found a nice service provider: MailJet. They offer a SMTP relay service that allows 20 mails a day to be sent for free (as per February 2020). That should suffice for most monitoring purposes. Besides, MailJet is European-based (France) - an advantage over US services because of data protection, and its free account supports TLS (port 465) for transport-level encryption. Of course, you can try to use any other SMTP server like the one you use for your daily personal mails. In this case you have to modify the mail settings below accordingly (step 2 and 3).

In case you like to use MailJet:

  1. Sign up an account.
  2. Log in and register a sender address. This is a real mail address you have access to; they will send an confirmation mail there. The registered sender address will then serve as address for your notification mails - using MailJet’s SMTP server.
  3. As a last step you may like to switch off email tracking as we do not need it.

Please note: your mail account’s login credentials will be stored on your Raspberry in plain text. If your Raspberry is not exposed to the internet (e.g. it is ‘hidden’ behind a router), this is usually of no concern. Besides, by using a SMTP relay service you avoid to use the login credentials of your ‘normal’ mail account.

Mailing client:
Note: This tutorial assumes you are logged in with sudo privileges. If not, add “sudo” in front of commands.

  1. Install dma and BC
    DMA is a small lightweight Mail Transport Agent (MTA) and very easy to configure. It accepts mails locally and delivers the mails either locally or to a remote destination. It is not a fully-featured mail server like Postfix or Sendmail.
    You could also use nullmailer or other MTAs but I found dma easier to set up and quicker to get it working.

Please note, this little tutorial is bespoken to dma; nullmailer uses different config files. You can only install nullmailer XOR dma.
During dma’s installation process you’ll be asked a few questions: just leave them untouched; we will take care of this shortly.
BC is a package used for floating point operations used in the script below. It’s likely pre-installed on your rPi already.

apt update
apt install dma
apt install bc
  1. Edit dma’s config file
nano /etc/dma/dma.conf

There are many comments in it. Stripped down you’d end up with something like the following.
If you like to keep the comments, just remove the comment hash (#) in front of the corresponding lines.

  • Leave the STARTTLS commented out as long as you want to use TLS and port 465. STARTTLS requires port 587. More info for example here.
    • The MASQUERADE line ensures that all mails sent by dma appear to come from the specified user.
SMARTHOST in-v3.mailjet.com
PORT 465
AUTHPATH /etc/dma/auth.conf
MASQUERADE sender_address@mymailprovider.net
  1. Edit dma’s auth file
nano /etc/dma/auth.conf

Put a line with your SMTP credentials in it. For MailJet it’ll look like this whereas
1111… = your MailJet’s SMTP user name and
2222… = your MailJet’s SMTP password


Note: the SMTP credentials are different from your MailJet’s login credentials! Log in to MailJet and browse to https://app.mailjet.com/account/setup/ to learn your SMTP credentials; these are needed here.
4. Create a bash script that checks the CPU temperature and composes the notification mail

nano /usr/local/bin/temp_mon

Copy the following code to the file and edit the variables in section ## VARIABLES ## according to your needs.
By the way: I am not a programmer. So the script’s code is for sure not the way a savvy hacker would code - but it works for me. :slight_smile:



# Temperature thresholds (warning and alarm). Use integers.
# Alarm will use another mail subject and mark the mail as important.
# Unit is only descriptive, not used for conversion.

# Other info needed for sending mails
FROM_NAME="My Raspberry Pi"
TO_NAME="John Doe"

## SCRIPT ##

# Saves he current CPU temperature to a variable
# grep checks whether it is a (float) numeric value
tmp_akt=$(vcgencmd measure_temp | cut -f 2 -d "=" | cut -f 1 -d "'" | grep -E '^\-?[0-9]*\.?[0-9]+$')
if [ "$1" == "test" ]
elif [ -z $tmp_akt ]
  echo "${0##*/}: Error at reading the CPU temperature. Unknown command? No numeric value? Aborting script."
  exit 1

# Determines whether the current temperature is above warning and/or alarm threshold

status_warn=$(echo $tmp_akt'>='$tmp_warn | bc -l)
status_alarm=$(echo $tmp_akt'>='$tmp_alarm | bc -l)

# Terminates script if none of both thresholds is reached
if [[ $status_warn -eq 0 && $status_alarm -eq 0 ]]
  exit 0

# Generates the mail text that will be sent
echo "From: \"$FROM_NAME\" <$FROM_ADDRESS>" > $MAIL_FILE
echo "To: \"$TO_NAME\" <$TO_ADDRESS>" >> $MAIL_FILE
if [ $status_alarm -eq 1 ]
  echo "Subject: Temperature ALARM" >> $MAIL_FILE
  echo "X-Priority: 1 (Highest)" >> $MAIL_FILE
  echo "X-MSMail-Priority: High" >> $MAIL_FILE
  echo "Importance: High" >> $MAIL_FILE
elif [ $status_warn -eq 1 ]
  echo "Subject: Temperature warning" >> $MAIL_FILE
echo "Content-type: text/plain; charset=utf-8" >> $MAIL_FILE
echo "Content-Language: en" >> $MAIL_FILE
echo "X-Auto-Response-Suppress: OOF" >> $MAIL_FILE
echo "" >> $MAIL_FILE
echo "CPU temperature is high!" >> $MAIL_FILE
echo "Current temp: $tmp_akt °$tmp_unit" >> $MAIL_FILE
if [ "$1" == "test" ]
  echo "" >> $MAIL_FILE
  echo "Please note:"  >> $MAIL_FILE
  echo "Script was run in *test mode* to check email delivery, this not the real CPU temperature!" >> $MAIL_FILE
echo "" >> $MAIL_FILE
echo "--- " >> $MAIL_FILE
echo "Sent by ${0##*/} script" >> $MAIL_FILE
echo "" >> $MAIL_FILE
  1. Add the following commands to the very end of the script you have just created.
    This takes care of sending the mail. It looks very basic since the needed settings are in the config files you edited earlier.
cat $MAIL_FILE | sendmail -f $FROM_ADDRESS $TO_ADDRESS && logger "${0##*/}: high CPU temperature: $tmp_akt °$tmp_unit, mail sent" 
  1. Make the script executable (only needed once)
chmod +x /usr/local/bin/temp_mon
  1. Run the script manually and check whether it works, i.e. you receive an email. Well, you won’t receive a mail if the CPU temperature is below the configured threshold, so …
bash /usr/local/bin/temp_mon

To test email delivery irrespective of the real CPU temperature simply run the script with parameter ‘test’:

bash /usr/local/bin/temp_mon test

Usually the email will be delivered to your mail account within 3-5 seconds.

For troubleshooting:

  • Check your spam folder.
    • Type “mailq” at command prompt. It answers “mail queue is empty” if it can deliver emails to the configured server. Otherwise it will show entries of mails waiting to be sent. Then probably something is wrong with the mail/SMTP settings. You can purge the queue by deleting the files in /var/spool/dma.
    • Type “journalctl | grep dma” and check the log entries for hints.
    • Check directory /var/spool/dma/ on your Raspberry for further hints. Also check directory /var/mail/root. Usually there isn’t much in these directories if everything is fine.
    • If you try to use MailJet with an email address not registered there, MailJet will send you an email telling you that someone tried to use your MailJet account with an email address not allowed. Register that email address with MailJet.
  1. Only proceed to the next step if email delivery works.
  2. Make your Raspberry run the script automatically every 10 minutes
crontab -e

Insert the following lines somewhere in the crontab file.
(Remember: in order to test cron, add parameter “test” behind the script’s name. Then you should receive an email every 10 minutes - irrespective of the real temperature.)

# Checks CPU temperature every 10 minutes and sends mail if it exceeds a threshold
*/10 * * * * sudo bash /usr/local/bin/temp_mon

As a last step reload the cronjob service to make it use the latest changes

service cron reload
  1. Congrats! You’re finished. Keep your rPi cool. :wink: I hope the script works fine for you.

Please note: you might get spammed by your own Raspberry when you’re not around your Raspberry or cannot connect to it remotely in order to stop it sending warning mails.