Raspberry Pi CPU temperature in Emoncms?

It’s never been an issue as far an I’m aware, but I’ve recently been asked by a user if the RaspberryPi core temperature could be posted to Emoncms to enable an early warning error to trigger if the core starts to get dangerously hot. The RasPi SOC can handle up to 85 degC (throttling starts at 80 degC) so this would only be an issue in extreme environments.

I think the best way to get the core temperature into Emoncms (local & remote) on the emonPi/emonBase would be have have a service script to read the core temperature and post to EmonHub socket interface.

Before I start work on this has anyone done something similar?

Here is an example of using emonHub socket interfacer: emonhub/configuration.md at emon-pi · openenergymonitor/emonhub · GitHub

RasPi core CPU temp can be read using:

/opt/vc/bin/vcgencmd measure_temp

or in deg C:

pi@raspberrypi:~ $ /opt/vc/bin/vcgencmd measure_temp
temp=56.9'C

Is this really necessary?

Is the emonpi worked so hard that it gets anywhere near the limits of 80deg?
Especially as it’s not even a full OS version.
My Pi 3 running emoncms, node-red, 2 websites, media server plus lots more, fitted in a tight fitting pi case measures;

pi@raspberrypi:~ $ vcgencmd measure_temp
temp=52.6'C

How many Pi’s do we have running in hostile environments? In those isolated cases, it may be easier for users to run the command from within node-red with a trigger to a push/email/twitter node if temp > 75deg.
So I would question the value of running yet another script, other than being a novelty to emonpi.

Paul

Probably not, but doesn’t do any harm? It could be useful for debugging, I know it’s already visible in emoncms admin page.

The user who has contacted me has got a large number fun units being deployed in sealed waterproof encloses in hostile environments and wanted a way to keep track of the temperature. I thought it might not be a bad idea to get some sort of ‘official’ service script up and running to do this since I’m sure it could be of interest to other users. It would also serve as an example of who to input data into an emonPi/emonBase unit making use of emonHub to post the data to both local and remote emoncms.

Yes, I include the monitoring of host system stats with all my deployments.

At the very least it includes CPU temperature. Many include WiFi signal, Ethernet speeds, cpu load, ram use, hdd use and /var/log use too.

Temperature alone won’t tell you much but if it’s compared to cpu load and/or ram use, or even spikes in the /var/log size it will tell you if it’s working harder or if there’s a runaway fault (increased log file sizes). Plus ambient temperature will put things in better perspective.

Here’s a graph from one of my early installs

You can see it peaks out at 75°C in June, which you might think is ok, but this monitor is installed in a plantroom/loft that gets extremely hot, this particular monitor I had to fit a PWM controlled fan to the box to keep it as low as possible. the fan is only small and varies between 40% and 100% duty cycle, from about 60°C it is on 100%.

But a fan is of little use when the ambient temperature is so high


see how the Pi’s temp tracks the ambient temp, when the ambient temp is nearly 40°C we can expect the cpu temp to peak at 75°C.

As a side note, the load on this Pi was drastically reduced (and therefore the temp lowered a fair bit) by changing the network settings to block unknown IP’s, by tracking the cpu load and logfile size I determined the Pi was under brute force ssh attacks, once they were blocked, the temp dropped.

I use python scripts that post to an emonhub socket, I don’t yet have a specific script I use for all sites, it has sort of evolved over time and I just add bits and cut away bits as needed. My intention is to eventually create an emonhub interacfer that does this internally. A user can then just configure it how they want by picking values from a list of available data to make up their own payload.

I did bring this up when the admin page was populated with temperature and disc sizes, but there was no interest then. The admin page stats are nice to have, but they offer little more than eye candy for the rare times a user logs in.

For example disc usage, if the disk usage is monitored over time, users could graph the delta to see what space they are consuming per day/week/month/year etc, this could help plan for the future (will I run out of disc space), spot issues (why did i consume twice as much data this week?) and even help evaluate the cost of shared hosting and/or using emoncms.org etc.

Logging the use of var/log could help fine tune ram usage and logrotation etc.

Actually that’s the GPU temperature, CPU temperature can be read with cat /sys/class/thermal/thermal_zone0/temp (it requires dividing by 1000)

pi@emonBase24(ro):~$ cat /sys/class/thermal/thermal_zone0/temp
51540
pi@emonBase24(ro):~$ /opt/vc/bin/vcgencmd measure_temp
temp=52.1'C

Here’s an (early) example script, I have a monitor sat here that was temporarily installed to a
building due to be demolished and it was subsequently removed to be reused elsewhere. Therefore it doesn’t have any disc, ram or cpu load monitoring.

#!/usr/bin/env python

import RPi.GPIO as GPIO
import time
import os
import socket

host = "localhost" #emonbase1"
port = 50012
nodeid = 13
interval = 5

fan_pin = 18
stall_percent=40   # max steps set to 100 set this to the min steps required before the fan stalls
temp_run=40
temp_max=55


# Return CPU temperature as float
def getCPUtemp():
    cTemp = os.popen('cat /sys/class/thermal/thermal_zone0/temp').readline()
    return float(cTemp)/1000

def getCPUtemp2():
  try:
    tFile = open('/sys/class/thermal/thermal_zone0/temp')
    tempC = float(tFile.read())/1000
    tFile.close()
  except:
    tempC = 300
  return tempC

def getWiFiData():
  try:
    tFile = open('/proc/net/wireless').readlines()
    tArray = [float(i) for i in tFile[2].split()[2:4]]
    tFile.close()
  except:
    tArray = [0,0]
  return tArray

# Send the frame of data via a socket
def send(f):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port))
    f = f + '\r\n'
    s.send(f)
    s.close()

# Set the PWM of fan pin
def adjFanSpeed(CPU_temp):
    if  CPU_temp > temp_run:
        FAN_cycle = (((CPU_temp - temp_run)*fan_ratio)+stall_percent)
        FAN_cycle = min(100,max(stall_percent,FAN_cycle))
        p.ChangeDutyCycle(FAN_cycle)
    else:
        p.ChangeDutyCycle(0)
        FAN_cycle=0
    return FAN_cycle

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(fan_pin,GPIO.OUT)
GPIO.setwarnings(False)
p=GPIO.PWM(fan_pin,50)
p.start(75) #instant start
fan_ratio=((100-stall_percent)/(temp_max-temp_run))

lastsend = time.time()//interval*interval
while True:
    t = time.time()//interval*interval
    if t >= (lastsend + interval):
        CPU_temp = getCPUtemp2()
        FAN_cycle = adjFanSpeed(CPU_temp)
        WIFI_data = getWiFiData()
        f = ' '.join(str(val) for val in [int(t), nodeid, int(t), CPU_temp, FAN_cycle, WIFI_data[0], WIFI_data[1]])
        lastsend = t
        print f
        send(f)
    time.sleep(0.10)

GPIO.cleanup()
1 Like

Nice!

This is exactly the kind of thing I had in mind :+1:

That’s really interesting to know. Therefore 40 deg C ambient should be considered the upper operating limit for the RasPi / emonPi.

There or there abouts for a fan ventilated Pi in a box, but that depends on load and other considerations. This is only running emonHub, there is no emoncms, LAMP server, MQTT or node-red etc.

The fan cooled box is well “holed” and about 240 x 180 x 120, so much larger and airier than an emonPi, With a full load and the small metal case, I think an emonPi would run hotter than my monitor.

1 Like

Just for comparison here is my emonPi CPU temp. Data is gathered via Node-RED.

1 Like

I use a php script to measure various stats about my raspberry pi 3 run as a cron job every minute. In the summer mine got up to 62 deg c when it was 31 deg c ambient temperature as shown below. Some of the scipt was borrowed off another forum, i don’t remember where from which is why it’s in php not python (yellow is outside air temperature).

<?php

$nodeid = 0; // change “0” with the node id that will receive data
$apikey=“XXXXXXXXXXXXXX”; // change “XXXXXXXXXXXXXX” with your APIKEY
$target=“localhost/emoncms”;

$mem = preg_split(‘#\s+#’,shell_exec(“free -m | grep Me”));
$GPU_temp=round(0.001shell_exec(“cat /sys/class/thermal/thermal_zone0/temp”));
$CPU_temp=1
shell_exec(‘/opt/vc/bin/vcgencmd measure_temp | cut -d “=” -f2 | cut -d “.” -f1’);
$cmd=‘top -bn1 | grep “Cpu(s)” | sed “s/., ([0-9.])% id.*/\1/” | awk '{print 100 - $1}'’;
$CPU_usage=round(shell_exec($cmd));

$url = ‘http://’.$target.‘/input/post.json?json={mem_used:’.$mem[2].‘,mem_free:’.$mem[3].‘,mem_shared:’.$mem[4].‘,mem_buffers:’.$mem[5].‘,mem_cached:’.$mem[6].‘,GPU_temp:’.$GPU_temp.‘,CPU_temp:’.$CPU_temp.‘,CPU_usage:’.$CPU_usage.‘}&node=’.$nodeid.‘&apikey=’.$apikey ;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$contents = curl_exec ($ch);
curl_close ($ch);

?>

Matt.

1 Like

I just stumbled across this picture in the forum-archives and thought I would post a link here, it demonstrates how logging some stats can be useful.

1 Like

Hello, I have updated the PHP script:

$nodeid = 0; // change “0” with the node id that will receive data
$apikey=“XXXXXXXXXXXXXX”; // change “XXXXXXXXXXXXXX” with your APIKEY
$target=“localhost”;

$mem = preg_split(‘#\s+#’,shell_exec(“free -m | grep Me”));
$GPU_temp=round(shell_exec(“cat /sys/class/thermal/thermal_zone0/temp”)*0.01); #30400 → 304 → convert emonhub 30.4°C
$CPU_temp=round(shell_exec(‘/usr/bin/vcgencmd measure_temp | cut -d “=” -f2 | cut -d “'” -f1’)*10); # 30.5 → 305 → convert emonhub 30.5°C
$cmd=“top -bn1 | grep "Cpu(s)" | sed ‘s/([0-9.]+)\sid/\1/’ | awk ‘{print 100 - $8}’”; #88 → 12 → convert emonhub 12%
$CPU_usage=round(shell_exec($cmd));

$url = ‘http://’.$target.‘/input/post.json?node=’.$nodeid.‘&fulljson={“mem_used”:’.$mem[2].‘,“mem_free”:’.$mem[3].‘,“mem_shared”:’.$mem[4].‘,“mem_buffers”:’.$mem[5].‘,“mem_cached”:’.$mem[6].‘,“GPU_temp”:’.$GPU_temp.‘,“CPU_temp”:’.$CPU_temp.‘,“CPU_usage”:’.$CPU_usage.‘}&apikey=’.$apikey;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$contents = curl_exec ($ch);
#print $url;
curl_close ($ch);

Pay attention to the quotes, the forum replace quotes with formatted quotes.

For future reference, when posting code or output, please put 3 ‘backticks’ (normally found at the top left of the keyboard) on a line of their own before the code, and 3 more backticks also on a line of their own after the code:

```
code
```

If it is something like php you can add a language identifier after the first 3 backticks: ```php or even ```text if you don’t want any language markup applied.

That scares me. Why not read it with php functions?