Skip to content

Instantly share code, notes, and snippets.

@asquelt
Last active July 5, 2020 17:59
Show Gist options
  • Save asquelt/0ea1c64436f24cbdb70e57516d0bc4df to your computer and use it in GitHub Desktop.
Save asquelt/0ea1c64436f24cbdb70e57516d0bc4df to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2014-18 Richard Hull and contributors
# See LICENSE.rst for details.
# PYTHON_ARGCOMPLETE_OK
"""
Display basic system information.
Needs psutil (+ dependencies) installed::
$ sudo apt-get install python-dev
$ sudo -H pip install psutil
"""
import os
import sys
import time
import socket
from datetime import datetime
if os.name != 'posix':
sys.exit('{} platform not supported'.format(os.name))
from demo_opts import get_device
from luma.core.render import canvas
from PIL import ImageFont, Image, ImageSequence
from luma.core.sprite_system import framerate_regulator
try:
import psutil
except ImportError:
print("The psutil library was not found. Run 'sudo -H pip install psutil' to install it.")
sys.exit()
import threading
from collections import deque
def calc_ul_dl(rate, dt=3, interface='lo'):
t0 = time.time()
counter = psutil.net_io_counters(pernic=True)[interface]
tot = (counter.bytes_sent, counter.bytes_recv)
while True:
last_tot = tot
time.sleep(dt)
counter = psutil.net_io_counters(pernic=True)[interface]
t1 = time.time()
tot = (counter.bytes_sent, counter.bytes_recv)
ul, dl = [(now - last) / (t1 - t0) * 10.0
for now, last in zip(tot, last_tot)]
rate.append((ul, dl))
t0 = time.time()
# Create the ul/dl thread and a deque of length 1 to hold the ul/dl- values
transfer_rate_br_lan = deque(maxlen=1)
transfer_rate_eth0 = deque(maxlen=1)
transfer_rate_wwan0 = deque(maxlen=1)
t0 = threading.Thread(target=calc_ul_dl, args=(transfer_rate_br_lan,1,'br-lan'))
t1 = threading.Thread(target=calc_ul_dl, args=(transfer_rate_eth0,1,'eth0'))
t2 = threading.Thread(target=calc_ul_dl, args=(transfer_rate_wwan0,1,'wwan0'))
# The program will exit if there are only daemonic threads left.
t0.daemon = True
t1.daemon = True
t2.daemon = True
t0.start()
t1.start()
t2.start()
# TODO: custom font bitmaps for up/down arrows
# TODO: Load histogram
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)
if n == 0:
return '--'
return "%sB" % n
def sys_uptime():
uptime = datetime.now() - datetime.fromtimestamp(psutil.boot_time())
return "%s Up: %s" \
% (socket.gethostname(), str(uptime).split('.')[0].replace(' days,','d').replace(' day,','d'))
def cpu_usage():
# load average, uptime
#uptime = datetime.now() - datetime.fromtimestamp(psutil.boot_time())
av1, av2, av3 = os.getloadavg()
#return "Ld:%.1f %.1f %.1f Up: %s" \
# % (av1, av2, av3, str(uptime).split('.')[0])
return "%s Ld: %.1f %.1f %.1f" \
% (socket.gethostname(), av1, av2, av3)
def mem_usage():
usage = psutil.virtual_memory()
return "Mem: %s %.0f%%" \
% (bytes2human(usage.used), 100 - usage.percent)
#return "Mem: %.0f%%" \
# % (100 - usage.percent)
def temperature():
temp = psutil.sensors_temperatures()['soc-thermal'][0]
return "Th: %.0f'C" \
% temp.current
def disk_usage(dir):
usage = psutil.disk_usage(dir)
return "SD: %s %.0f%%" \
% (bytes2human(usage.used), usage.percent)
def network(iface,rate,ip=False):
if ip:
if psutil.net_if_stats()[iface].isup:
return "%s" % \
(psutil.net_if_addrs()[iface][0].address)
else:
return "*** %s is DOWN ***" % iface
try:
stat = "UL %5s DL %5s" % \
(bytes2human(int(rate[-1][0])), bytes2human(int(rate[-1][1])))
return stat
except:
stat = psutil.net_io_counters(pernic=True)[iface]
return "Tx %5s Rx %5s" % \
(bytes2human(stat.bytes_sent), bytes2human(stat.bytes_recv))
def stats(device,Flag):
regulator = framerate_regulator(fps=15)
img_path = os.path.abspath(os.path.join(os.path.dirname(__file__),
'images', 'banana.gif'))
banana = Image.open(img_path)
size = [min(*device.size)] * 2
posn = ((device.width - size[0]) // 2, device.height - size[1])
# use custom font
font_path = os.path.abspath(os.path.join(os.path.dirname(__file__),
'fonts', 'C&C Red Alert [INET].ttf'))
font2 = ImageFont.truetype(font_path, 12)
if not Flag:
for loop in range(1,5):
for frame in ImageSequence.Iterator(banana):
with regulator:
background = Image.new("RGB", device.size, "white")
background.paste(frame.resize(size, resample=Image.LANCZOS), posn)
device.display(background.convert(device.mode))
for iter in range(1,8):
with canvas(device) as draw:
draw.rectangle((0, 0, device.width, 12), outline="white", fill="white")
draw.rectangle((0, 0, 1, 1), outline="black", fill="black")
draw.rectangle((0, 11, 1, 12), outline="black", fill="black")
draw.rectangle((device.width-2, 0, device.width, 1), outline="black", fill="black")
draw.rectangle((device.width-2, 11, device.width, 12), outline="black", fill="black")
if Flag:
draw.text((1, 0), cpu_usage(), font=font2, fill="black")
else:
draw.text((1, 0), sys_uptime(), font=font2, fill="black")
if device.height >= 32:
if Flag:
draw.text((0, 14), mem_usage() + ' ' + temperature(), font=font2, fill="white")
else:
draw.text((0, 14), disk_usage('/') + ' ' + temperature(), font=font2, fill="white")
if device.height >= 64:
try:
draw.text((0, 26), 'LAN:', font=font2, fill="white")
draw.text((26, 26), network('br-lan',transfer_rate_br_lan,Flag), font=font2, fill="white")
except KeyError:
# no network enabled/available
draw.text((26, 26), '*** br-lan is UNKNOWN ***', font=font2, fill="white")
try:
draw.text((0, 38), 'WAN:', font=font2, fill="white")
draw.text((26, 38), network('eth0',transfer_rate_eth0,Flag), font=font2, fill="white")
except KeyError:
# no network enabled/available
draw.text((26, 38), '*** eth0 is UNKNOWN ***', font=font2, fill="white")
try:
draw.text((0, 50), 'LTE:', font=font2, fill="white")
draw.text((26, 50), network('wwan0',transfer_rate_wwan0,Flag), font=font2, fill="white")
except KeyError:
# no network enabled/available
draw.text((26, 50), '*** wwan0 is UNKNOWN ***', font=font2, fill="white")
time.sleep(1)
def main():
Flag = False
while True:
stats(device,Flag)
#time.sleep(8)
if Flag:
Flag = False
else:
Flag = True
if __name__ == "__main__":
try:
device = get_device()
main()
except KeyboardInterrupt:
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment