Recently I’ve had problems with my Raspberry Pi 3 overheating though I use a heat sink for the processor and have a very modest load on the machine. When the RPi is in this state, it shows a thermometer warning icon and it is not possible to login. As I can not access the machine, it is hard to investigate the cause of the heat problem (if a process has gone totally wild e.g.). The only way to resolve this is to do a hard reboot (then the temperature goes down again).
To investigate this further, I want to monitor the CPU temperature without accessing the RPi via ssh or a direct login. My idea is to let the RPi gather board temperature values regularly and then publish these via MQTT. An MQTT subscriber will see to that the measurements are propagated to a cloud service so that I can monitor the values in an external application. With IFTTT I can add alerts on the measurements (e.g. when the CPU temperature goes over 60 C, an e-mail should be sent to me). This way I will be notified before the temperature/load gets too high and I will hopefully be able to intercept the problem by logging in to the machine before it locks up.
I will add a Python script that is scheduled with cron to start every ten minutes. The script checks the CPU temperature, formats the data and publishes the value via a local MQTT broker (mosquitto). I use an existing Python service (developed in A self-hosted MQTT environment for Internet of Things – Part 3) as an MQTT subscriber that forwards the data to a cloud service (Adafruit IO).
The data can then be monitored via the Adafruit IO web dashboard or via a mobile app (I use DataFeeds on iOS which works fine for my purposes).
I have setup an rule in IFTTT (IF This Then That), that sends me an iOS notification when the measurement value exceeds a certain limit.
Getting the CPU temperature from a Raspberry Pi
The vcgencmd command can be used for getting Raspberry Pi-specific properties. To get the broadcom chip temperature, the measure_temp argument is used:
This will return a string like Temp=42.4’C.
Setting up the measurement Python script
As I want to publish the temperature, I use a Python script to execute the vcgencmd and then format it. This tutorial shows how it can be done:
As in the tutorial, I use subprocess.check_output() to execute the command and then a regular expression to extract the actual value from the returned string.
After the temperature value is fetched, I connect to my local MQTT broker and publish a message on the Home/RPI3/Temp topic.
The script is setup to run once every 10 minutes with cron:
(add a row like this one):
*/10 * * * * /home/myuser/mypath/measurecputemp.py
Note that the py-file needs to start with a Python shebang (#!/usr/bin/env python3) and the file needs to have execution rights set (use chmod ugo+x measurecputemp.py).
Routing the data to Adafruit IO
The temperature is published as a message to my local MQTT broker. I have a subscriber that acts as proxy for forwarding the data to Adafruit IO. I use this subscriber for most of the messages that I publish from my MQTT devices at home. I have described this subscriber in more detail in a previous post:
This Python script is setup to run as a service as described in:
The data can then be monitored on the Adafruit IO dashboard:
Monitoring the data with a mobile app
I use the free and excellent DataFeeds app by MonoHelix Labs for viewing my Adafruit IO feeds on iOS. You can get it from here:
Setting up an applet/rule with IFTTT
With an account on IFTTT, it is possible to connect to your Adafruit IO account and act on changes in the feed data. I have setup an applet that gives me notifications on my mobile phone when the RPi-temperature is greater or equal to 60 C.
Adding additional measurements
While at it, I add measurements for disk-, memory and CPU-usage as well. These measurements can be fetched with the psutil library. I have made a new Python script that gets these values (and the CPU temp) and transforms them to MQTT messages. The script takes one argument that can be specified as the name of the computer that is measured, e.g. RPI3, RPI2. This way I can easily use the script on all my Raspberry Pi:s.
To use this script with cron, set execution rights on the file and specify the schedule with crontab:
*/10 * * * * /home/myuser/mypath/systemmonitor.py RPI3