Hi,
I’m trying to make a ST7735 display work on a Raspberry Pi 3B as a system stats display.
It was not easy to make it work, but now I’m having some problems trying to display some system stats like the CPU Usage in %, the CPU Temperature and the network Tx and Rx values.
Here is a photo of what it displays at the moment:
And here is my stats.py file:
import socket
import fcntl
import struct
import os
import sys
import time
import psutil
from PIL import ImageDraw
from PIL import Image
from PIL import ImageFont
from pathlib import Path
from datetime import datetime
from demo_opts import get_device
from luma.core.render import canvas
if os.name != 'posix':
sys.exit('{} platform not supported'.format(os.name))
try:
import psutil
except ImportError:
print("The psutil library was not found. Run 'sudo -H pip install psutil' to install it.")
sys.exit()
def bytes2human(n):
"""
>>> bytes2human(10000)
'9K'
>>> bytes2human(100001221)
'95M'
"""
symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
prefix = {}
for i, s in enumerate(symbols):
prefix[s] = 1 << (i + 1) * 10
for s in reversed(symbols):
if n >= prefix[s]:
value = int(float(n) / prefix[s])
return '%s%s' % (value, s)
return f"{n}B"
# check uptime
def up_time():
uptime = datetime.now() - datetime.fromtimestamp(psutil.boot_time())
return str(uptime).split('.')[0] + ' Hours'
# Examples for usage:
# IP = get_ipv4_from_interface("eth0")
# IP = get_ipv4_from_interface("wlan0")
def get_ipv4_from_interface(interfacename):
res="IP ?"
try:
iface=psutil.net_if_addrs()[interfacename]
for addr in iface:
if addr.family is socket.AddressFamily.AF_INET:
return "{0}".format(addr.address)
except:
return res
return res
# This looks for the first IPv4 address that is not on the
# loopback interface. There is no guarantee on the order of
# the interfaces in the enumeration. If you've multiple interfaces
# and want to ensure to get an IPv4 address from a dedicated adapter,
# use the previous method.
def get_ipv4():
ifaces=psutil.net_if_addrs()
for key in ifaces:
if (key!="lo"): # Ignore the loopback interface
# if it's not loopback, we look for the first IPv4 address
iface = ifaces[key]
for addr in iface:
if addr.family is socket.AddressFamily.AF_INET:
return "{0}".format(addr.address)
return "IP ?"
# check the cpu usage
def cpu_usage():
av1, av2, av3 = os.getloadavg()
return "%.1f %.1f %.1f" % (av1, av2, av3)
# check the cpu temp
def cpu_temp():
temperature = ''
os.system("rm -rf temp_data")
os.system("/opt/vc/bin/vcgencmd measure_temp > temp_data")
temp_file = open("temp_data","r")
for line in temp_file:
line = line.rstrip()
temperature = line.split('=')[1]
temp_file.close()
os.system("rm -rf temp_data")
return temperature
# check the ram usage
def ram_usage():
memory = psutil.virtual_memory()
# Divide from Bytes -> KB -> MB
ramused = round(memory.used/1024.0/1024.0,1)
ramtotal = round(memory.total/1024.0/1024.0,1)
return str(ramused) + 'MB of ' + str(ramtotal)+'MB'
# check disk usage
def disk_usage():
disk = psutil.disk_usage('/')
# Divide from Bytes -> KB -> MB -> GB
diskused = round(disk.used/1024.0/1024.0/1024.0,1)
disktotal = round(disk.total/1024.0/1024.0/1024.0,1)
return str(diskused) + 'GB of ' + str(disktotal)+'GB'
# check network
def network(iface):
stat = psutil.net_io_counters(pernic=True)[iface]
return "%s: Tx%s, Rx%s" % (iface, bytes2human(stat.bytes_sent), bytes2human(stat.bytes_recv))
# print everything
def stats(device):
device.show()
# use custom font
font_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'fonts', 'PixelOperator.ttf'))
font2 = ImageFont.truetype(font_path, 16)
#IP = get_ipv4()
IP = get_ipv4_from_interface("eth0") # Alternative
with canvas(device) as draw:
draw.text((0,0), "Uptime: ", font=font2, fill="red")
draw.text((50,0), up_time(), font=font2, fill="white")
draw.text((0,15), "Hostname: ", font=font2, fill="red")
draw.text((67,15), "Q3Server", font=font2, fill="white")
draw.text((0,30), "IP: ", font=font2, fill="red")
draw.text((20,30), IP, font=font2, fill="white")
draw.text((0,45), "CPU Usage: ", font=font2, fill="red")
draw.text((70,45), cpu_usage(), font=font2, fill="white")
draw.text((0,60), "CPU Temp: ", font=font2, fill="red")
draw.text((53,60), cpu_temp(), font=font2, fill="white")
draw.text((0,75), "Ram: ", font=font2, fill="red")
draw.text((35,75), ram_usage(), font=font2, fill="white")
draw.text((0,90), "SD Card: ", font=font2, fill="red")
draw.text((55,90), disk_usage(), font=font2, fill="white")
#draw.text((0, 105), "Network: ", font=font2, fill="red")
draw.text((0, 105), network('eth0'), font=font2, fill="white")
def main():
while True:
stats(device)
time.sleep(1)
if __name__ == "__main__":
try:
device = get_device()
device.clear()
main()
except KeyboardInterrupt:
pass
Can someone please help me make the CPU Usage work in % value and not the Loads and the CPU Temperature to display and the network interface name and Tx and Rx values show properly?
Thanks.