Source code is available in here – https://github.com/nanomesher/PiMonitor
Introduction
We have a stack of Raspberry Pis where we are using as web server running python , gunicorn, sqlite databases as well as mqtt broker. We would like to have a device where we can monitor the health (free memory and temperature) of these Raspberry Pi. Rather than sparing a monitor for this, we decide to build a simple monitoring solution using the Nanomesher HMI. It will also light up the onboard led as warning if low in memory or disk space
Nanomesher HMI is a wifi touch screen display developed by Nanomesher with a easy to use HTTP and MQTT based API. In this project, Raspberry Pis will update the Nanomesher HMI via the HTTP API.
Architecture
The architecture is very simple. Each of the Raspberry PI runs a python script which regularly fetches health information (CPU utilisation, CPU temperature, Free memory and Free Disk space) and updates the Nanomesher HMI via http.
Display – Nanomesher HMI
Nanomesher HMI is simple to use wireless display with touch screen which combines a Nextion touch screen display and a Wemos D1 mini. Nanomesher provides an open source API which gives easy access to display functionalities such as setting values and colours on the display as well as beeping and blinking on the onboard speakers and LED.
We used the Nextion designer to draw 5 rows of text boxes on the screen. Each Pi will update one row on the display and the information will rotate. The number of rows can be fitted depend on the font and how compact the screen is designed. “iplbl” is used to display the ip address of the screen.
Fetching CPU Temperature
The easiest way to fetch cpu temperature is with below command.
/opt/vc/bin/vcgencmd measure_temp
Python provide Popen command to run linux command and return results. A few string replace has been added to format the output to what we need
def GetTemp():
cmd = "/opt/vc/bin/vcgencmd measure_temp | sed -s 's/=/:/g'"
p = Popen(cmd, shell=True, stdout=PIPE)
output = p.communicate()[0]
return output.replace('\n','').replace('temp:','Temp:').replace("'C","c")
Fetching memory , cpu utilisation and free disk space
This is quite easy with the native platform independent psutil python library.
To install:
sudo pip install psutil
Or
sudo pip3 install psutil
We are interested in displaying CPU utilization , free memory and disk space
The virtual_memory() function return values in bytes. Therefore we need to divide by 1024 twice to get the megabytes value.
def GetFreeMem():
return str(psutil.virtual_memory().free/1024/1024) + "M"
CPU and Free Disk spaces are quite straight forward
def GetCpuPercent():
return str(psutil.cpu_percent()) + "%"
def GetFreeDisk():
return str(psutil.disk_usage('/home/pi').free/1024/1024) + "M"
Note that there is also a cpu_times_percent() if individual cpu % is needed.
IP address
Lastly, the ip address is shown by fetching either from eth0 or wlan0 interface
def GetLANIP():
cmd = "ip addr show eth0 | grep inet | grep -v inet6 | awk '{print $2}' | cut -d '/' -f 1"
p = Popen(cmd, shell=True, stdout=PIPE)
output = p.communicate()[0]
return output
def GetWLANIP():
cmd = "ip addr show wlan0 | grep inet | grep -v inet6 | awk '{print $2}' | cut -d '/' -f 1"
p = Popen(cmd, shell=True, stdout=PIPE)
output = p.communicate()[0]
return output
Update data on Nanomesher HMI
Nanomesher HMI is very easy to integrate with it’s http based api. Below uses simple HTTP get request to set values and colour on the display.
‘p’ – page number
‘n’ – name of the UI component
‘v’ – text to set
‘fc’ – foreground colour (uses 16bit colour code)
def PublishToDisplay(text,label_prefix):
try:
data = {}
data['p'] = '0'
data['n'] = label_prefix + sys.argv[2]
data['v'] = text
data['fc'] = '23555'
url_values = urllib.urlencode(data)
url = "http://" + sys.argv[1] + "/TextSetText?" + url_values
response = urllib2.urlopen(url)
html = response.read()
except:
pass
Data[‘n’] indicates the component name which is passed in as command line argument. The number of rows depends on how you design the layout of the screen. In this example there are 4 rows named, line1 , line2, line3 and line4 respectively.
Warnings
We thought it would be useful to give visual indications of Pi health problems such as low memory or disk space and hence we have added such checks below to show the informaton in red and light up the LED.
freemem = GetFreeMem()
if(freemem > 100):
PublishToDisplay(str(freemem) + "M","mem","23555")
LedOff()
else:
PublishToDisplay(str(freemem) + "M","mem","61455")
LedOn()
freedisk = GetFreeDisk()
if(freedisk > 500):
PublishToDisplay(str(freedisk) + "M","disk","23555")
LedOff()
else:
PublishToDisplay(str(freedisk) + "M","disk","61455")
LedOn()
if(freemem > 100 and freedisk > 500):
LedOff()
else:
LedOn()
Running it
- Download PiMonitor.py from github
- Install pip if haven’t
sudo apt-get install python-pip
- Install psutil
sudo pip install psutil
Or if using python3
sudo pip3 install psutil
4. Run by using
python PiMonitor.py 192.168.11.116 1
Where
- 192.168.11.116 is the IP address of Nanomesher HMI (displayed on the screen)
- 1 indicated which row in the display to update, so different Pi would update different row(1 – 4)