[Tutorial] Check CPU temperature and send warning mail

Guides and tutorials for various stuff. Posted by DietPi users.
Post Reply
huidbui25
Posts: 28
Joined: Tue May 07, 2019 6:07 pm
Location: DE

[Tutorial] Check CPU temperature and send warning mail

Post by huidbui25 »

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.

    Code: Select all

    apt update
    apt install dma
    apt install bc
    
  2. Edit dma's config file

    Code: Select all

    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.
    Notes:
    • 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.

    Code: Select all

    SMARTHOST in-v3.mailjet.com
    PORT 465
    AUTHPATH /etc/dma/auth.conf
    SECURETRANSFER
    MASQUERADE [email protected]
    
  3. Edit dma's auth file

    Code: Select all

    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

    Code: Select all

    11111111111111111111111111111111|in-v3.mailjet.com:22222222222222222222222222222222
    
    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

    Code: Select all

    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. :)

    Code: Select all

    #!/bin/bash
    
    
    
    ## VARIABLES ##
    
    # 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.
    tmp_warn="52"
    tmp_alarm="62"
    tmp_unit="C"
    
    # Other info needed for sending mails
    FROM_NAME="My Raspberry Pi"
    FROM_ADDRESS="[email protected]"
    TO_NAME="John Doe"
    TO_ADDRESS="[email protected]"
    MAIL_FILE="/tmp/mail_tmp.txt"
    
    
    
    ## 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" ]
    then
      tmp_akt="333"
    elif [ -z $tmp_akt ]
    then
      echo "${0##*/}: Error at reading the CPU temperature. Unknown command? No numeric value? Aborting script."
      exit 1
    fi
    
    # 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 ]]
    then
      exit 0
    fi
    
    # 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 ]
    then
      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 ]
    then
      echo "Subject: Temperature warning" >> $MAIL_FILE
    fi
    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" ]
    then
      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
    fi
    echo "" >> $MAIL_FILE
    echo "--- " >> $MAIL_FILE
    echo "Sent by ${0##*/} script" >> $MAIL_FILE
    echo "" >> $MAIL_FILE
    
  5. 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.

    Code: Select all

    cat $MAIL_FILE | sendmail -f $FROM_ADDRESS $TO_ADDRESS && logger "${0##*/}: high CPU temperature: $tmp_akt °$tmp_unit, mail sent" 
    rm $MAIL_FILE
    
  6. Make the script executable (only needed once)

    Code: Select all

    chmod +x /usr/local/bin/temp_mon
  7. 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 ...

    Code: Select all

    bash /usr/local/bin/temp_mon
    To test email delivery irrespective of the real CPU temperature simply run the script with parameter 'test':

    Code: Select all

    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.
  8. Only proceed to the next step if email delivery works.
  9. Make your Raspberry run the script automatically every 10 minutes

    Code: Select all

    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.)

    Code: Select all

    # 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

    Code: Select all

    service cron reload
  10. Congrats! You're finished. Keep your rPi cool. ;) 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.
Last edited by huidbui25 on Fri Feb 14, 2020 6:48 pm, edited 1 time in total.

huidbui25
Posts: 28
Joined: Tue May 07, 2019 6:07 pm
Location: DE

Re: Check CPU temperature and send warning mail

Post by huidbui25 »

reserved

Post Reply