Situatie
Solutie
Getting the CPU Temperature on a Raspberry Pi
The first step in the process is to obtain the CPU temperature of the Raspberry Pi. Actually, you could use the messaging techniques described here to alert you if any important characteristic of your Raspberry Pi is drifting out of acceptable tolerances.
The command to get the CPU temperature on a Raspberry Pi is:
vcgencmd measure_temp
If this doesn’t work, try using the full directory path to the command. On my Raspberry Pi running the Oct. 10, 2023 release of the Raspberry Pi OS, the command is located in the “/usr/bin/” directory. This makes the longhand version of the command:
/usr/bin/vcgencmd measure_temp
There are three things to notice about the output from the command.
Firstly, it includes “temp=” and “’C”, which is more than we want. We want to have the temperature as a number that we can compare to a threshold. If the temperature rises above the threshold it’ll trigger sending a message. The second point is, the temperature is in degrees Celsius. Finally, it’s a floating point number. We’ll convert that to an integer value in our script.
To extract the temperature value on its own, we can use awk. We’re using the -F (field delimiters) option to tell awk to treat equals signs “=” and apostrophes “’” as flags that mark the start and end of a field. We then ask it to print the second field which, in our string, is the CPU temperature reading.
vcgencmd measure_temp | awk -F "[=']" '{print($2)}'
This isolates the numerical value, and allows us to assign it to a variable.
pi_temp=$(vcgencmd measure_temp | awk -F "[=']" '{print($2)}')
echo $pi_temp
If you’re happier working in Fahrenheit, we can add some math to convert the value for us.
pi_temp=$(vcgencmd measure_temp | awk -F "[=']" '{print($2 * 1.8)+32}')
echo $pi_temp
In order to set a threshold, we need to know what the operational range of the Raspberry Pi is. I checked the Raspberry Pi datasheet for the Raspberry Pi 4, Model B I was testing with.
In the section titled “Temperature Range and Thermals” it states that “The recommended ambient operating temperature range is 0 to 50 degrees Celsius.” That equates to a temperature range of 32-122 degrees Fahrenheit. This is the temperature that the entire board is happy with, and the CPU temperature could be safely higher. However, the value from the datasheet is a very safe value for us to use because we’re erring on the cooler side, not the hotter side.
Setting Up Discord to Accept Messages
Enabling messaging into Discord requires something called a webhook, which is straightforward to set up. We’ll create a new server to receive our notifications, then activate a webhook we can call from a script on our Raspberry Pi.
- In Discord, click the green “+” button to create a new server.
- In the “Create a Server” dialog, click “Create My Own.
- In the “Tell Us More About Your Server” dialog, click “For me and My Friends.”
- Provide a name for your new server in the “Customise Your Server” dialog. Ours is called “PiNotifications.”
- We also clicked on the camera icon and uploaded a “warning bell” icon. (Once you’ve uploaded an icon, it obscures the camera icon.)
- Click the blue “Create” button when you’re ready to proceed. Our new server now appears in our list of servers.
- Select your new server, then click the arrow alongside its name.
- Click the “Server Settings” option.
- On the “Settings” page, click the “Integrations” option in the sidebar. Click the “Create Webhook” button. A new webhook is created and named for you.
- Click the arrow “>” button to edit your webhook.
We renamed our webhook to “Pi Alerts”, and left it pointing at the “#general” channel of our server. We’re going to need the URL of the webhook, so click the “Copy Webhook URL” button, and paste the URL into an editor, and save the file. You’ll need easy access to the URL later.
- When you’re ready to proceed, click the green “Save Changes” button at the bottom of the page.
- Pressing the “Esc” key will take you back into the normal Discord desktop view.
Creating Our Script to Send an Alert to Discord
Our script starts by obtaining the CPU temperature. If you want the temperature in Fahrenheit, delete or comment out the Celsius line and uncomment the Fahrenheit line.
We then use awk to extract the integer element of the temperature value (the part that comes before the floating point “.”) because naked Bash only supports integer arithmetic. We then obtain the hostname, and assign it to a variable called “this_pi”. We’ll send the hostname as part of our alerting message, so that we can tell which Raspberry Pi is sending the alert.
You need to set the “discord_pi_webhook” variable to the URL that you copied and saved earlier. When you paste it into your script, make sure you keep the quotation marks. We test the CPU temperature against the threshold value in an “if” statement. If the CPU temperature is higher than our trigger threshold, we use curl to send the message to the webhook URL. The alert then appears in our Discord server.
So that we can test our script, we’ve set the threshold value to 15. This means the “if” loop will definitely be executed. Once you’re happy that the script works, you can raise this value to a real-world value. In Celsius, that’d be about 44 degrees for my Raspberry Pi 4.
#!/bin/bash
# get CPU temperature in Celsius
pi_temp=$(vcgencmd measure_temp | awk -F "[=']" '{print($2)}')
# for Fahrenheit temperatures, use this line instead
# pi_temp=$(vcgencmd measure_temp | awk -F "[=']" '{print($2 * 1.8)+32}')
# round down to an integer value
pi_temp=$(echo $pi_temp | awk -F "[.]" '{print($1)}')
# get the hostname, so we know which Pi is sending the alert
this_pi=$(hostname)
discord_pi_webhook="Paste your webhook URL here"
if [[ "$pi_temp" -ge 15 ]]; then
curl -H "Content-Type: application/json" -X POST -d '{"content":"'"Pi ${this_pi} CPU temp is: ${pi_temp}"'"}' $discord_pi_webhook
fi
Copy the script into an editor, paste in your webhook URL, save it as “cpu_temp.sh”, and close your editor. We’ll need to make our script executable.
chmod +x cpu_temp.sh
To test our script, we’ll call it from the command line.
./cpu_temp.sh
A moment later, our message appears in Discord.
Our Raspberry Pi is called “htg-pi-server”, and its CPU temperature is 33 degrees Celsius. Once you’ve tested your script, remember to edit the threshold value in the “if” statement to a real world value.
Setting Up a Webhook on Slack
We’ve got a detailed run-through on how to set up a webhook on Slack. The process is very similar to the steps you need to take with Discord. You’ll need to copy the webhook URL and a secret key.
#!/bin/bash
# get CPU temperature in Celsius
pi_temp=$(vcgencmd measure_temp | awk -F "[=']" '{print($2)}')
# for Fahrenheit temperatures, use this line instead
# pi_temp=$(vcgencmd measure_temp | awk -F "[=']" '{print($2 * 1.8)+32}')
# round down to an integer value
pi_temp=$(echo $pi_temp | awk -F "[.]" '{print($1)}')
# get the hostname, so we know which Pi is sending the alert
this_pi=$(hostname)
slack_pi_webhook="https://hooks.slack.com/services/paste-your-key-here"
if [[ "$pi_temp" -ge 15 ]]; then
curl -X POST --data-urlencode "payload={'channel': '#support', 'text': 'Pi ${this_pi} CPU temp is: ${pi_temp}'}" $slack_pi_webhook
fi
Paste your secret key in the script where it reads “paste-your-key-here.” Making sure there are quotation marks around the entire URL.
Other than that, there are very few changes required to make the script work with Slack instead of Discord.
We’ve renamed the “discord_pi_webhook” variable to “slack_pi_webhook” and changed the “curl” command for one that works with Slack. It’s set to post to a channel called “#support”, but you can change that to the name of the channel you’re using on your Slack server.
Messages from your Raspberry Pi pop up in your nominated Slack channel.
Automating the Temperature Checks
To make the “cpu_temp.sh” script run periodically, you can turn it into a systemd timer. Running the script every 15 minutes or so is a good start point. You can always adjust that later if you think you need more frequent or less frequent checks.
Leave A Comment?