diff --git a/i2c.py/status.py b/i2c.py/status.py index 9680003..b892c1b 100644 --- a/i2c.py/status.py +++ b/i2c.py/status.py @@ -1,105 +1,94 @@ -# This example is for use on (Linux) computers that are using CPython with -# Adafruit Blinka to support CircuitPython libraries. CircuitPython does -# not support PIL/pillow (python imaging library)! - -import time +import signal import subprocess +import time -from board import SCL, SDA -import busio -from PIL import Image, ImageDraw, ImageFont import adafruit_ssd1306 +import busio +from board import SCL, SDA +from PIL import Image, ImageDraw, ImageFont +DISPLAY_WIDTH = 128 +DISPLAY_HEIGHT = 64 +SYSTEM_INFO_INTERVAL = 2.0 +DISPLAY_REFRESH_INTERVAL = 0.1 +FONT_PATH = '/usr/share/fonts/truetype/wqy/wqy-microhei.ttc' +FONT_SIZE_SMALL = 11 +FONT_SIZE_DATE = 16 +LINE_HEIGHT = 12 -# Create the I2C interface. i2c = busio.I2C(SCL, SDA) - -# Create the SSD1306 OLED class. -# The first two parameters are the pixel width and pixel height. Change these -# to the right size for your display! -disp = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c) - -# Clear display. +disp = adafruit_ssd1306.SSD1306_I2C(DISPLAY_WIDTH, DISPLAY_HEIGHT, i2c) disp.fill(0) disp.show() -# Create blank image for drawing. -# Make sure to create image with mode '1' for 1-bit color. -width = disp.width -height = disp.height -image = Image.new("1", (width, height)) - -# Get drawing object to draw on image. +image = Image.new("1", (DISPLAY_WIDTH, DISPLAY_HEIGHT)) draw = ImageDraw.Draw(image) -# Draw a black filled box to clear the image. -draw.rectangle((0, 0, width, height), outline=0, fill=0) -# Draw some shapes. -# First define some constants to allow easy resizing of shapes. -padding = -2 -top = padding -bottom = height - padding -# Move left to right keeping track of the current x position for drawing shapes. -x = 0 +def load_font(path: str, size: int): + try: + return ImageFont.truetype(path, size) + except OSError: + return ImageFont.load_default() -# Load default font. -#font = ImageFont.load_default() +font = load_font(FONT_PATH, FONT_SIZE_SMALL) +font_date = load_font(FONT_PATH, FONT_SIZE_DATE) -# Alternatively load a TTF font. Make sure the .ttf font file is in the -# same directory as the python script! -# Some other nice fonts to try: http://www.dafont.com/bitmap.php -font = ImageFont.truetype('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc', 11) -font_clock = ImageFont.truetype('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc', 24) -font_date = ImageFont.truetype('/usr/share/fonts/truetype/wqy/wqy-microhei.ttc', 16) +running = True -# 添加图像切换状态变量 -show_system_info = True -last_switch_time = time.time() -switch_interval = 5 # 5秒切换一次 -while True: - # 检查是否需要切换图像 - # current_time = time.time() - # if current_time - last_switch_time >= switch_interval: - # show_system_info = not show_system_info - # last_switch_time = current_time - - # Draw a black filled box to clear the image. - draw.rectangle((0, 0, width, height), outline=0, fill=0) - - # if show_system_info: - # 显示系统信息 - # Shell scripts for system monitoring from here: - # https://unix.stackexchange.com/questions/119126/command-to-display-memory-usage-disk-usage-and-cpu-load - cmd = "hostname -I | cut -d' ' -f1" - IP = subprocess.check_output(cmd, shell=True).decode("utf-8") - cmd = 'cut -f 1 -d " " /proc/loadavg' - CPU = subprocess.check_output(cmd, shell=True).decode("utf-8") - cmd = "free -m | awk 'NR==2{printf \"Mem: %s/%s MB %.2f%%\", $3,$2,$3*100/$2 }'" - MemUsage = subprocess.check_output(cmd, shell=True).decode("utf-8") - cmd = 'df -h | awk \'$NF=="/data"{printf "Disk: %d/%d GB %s", $3,$2,$5}\'' - Disk = subprocess.check_output(cmd, shell=True).decode("utf-8") - - date_time = time.strftime("%Y-%m-%d, %H:%M:%S") - # Write four lines of text. - - draw.text((x, top + 1), "IP: " + IP, font=font, fill=255) - draw.text((x, top + 13), "CPU: " + CPU, font=font, fill=255) - draw.text((x, top + 23), MemUsage, font=font, fill=255) - draw.text((x, top + 35), Disk, font=font, fill=255) - draw.text((x, top + 47), date_time, font=font_date, fill=255) - # else: - # # 显示时钟信息 - # text = time.strftime("%A") - # draw.text((0, 0), text, font=font_date, fill=255) - # text = time.strftime("%Y-%m-%d") - # draw.text((0, 20), text, font=font_date, fill=255) - # text = time.strftime("%X") - # draw.text((0, 40), text, font=font_clock, fill=255) - - # Display image. +def signal_handler(signum, frame): + global running + running = False + + +signal.signal(signal.SIGINT, signal_handler) +signal.signal(signal.SIGTERM, signal_handler) + + +def run_command(cmd: str) -> str: + try: + result = subprocess.check_output(cmd, shell=True, stderr=subprocess.DEVNULL) + return result.decode("utf-8").strip() + except subprocess.CalledProcessError: + return "N/A" + + +def get_system_info(): + ip = run_command("hostname -I | cut -d' ' -f1") + cpu = run_command('cut -f 1 -d " " /proc/loadavg') + mem = run_command("free -m | awk 'NR==2{printf \"Mem: %s/%s MB %.2f%%\", $3,$2,$3*100/$2 }'") + disk = run_command('df -h | awk \'$NF=="/data"{printf "Disk: %d/%d GB %s", $3,$2,$5}\'') + return ip, cpu, mem, disk + + +def draw_text(line: int, text: str, font_obj=font): + y = line * LINE_HEIGHT + draw.text((0, y), text, font=font_obj, fill=255) + + +ip, cpu, mem, disk = get_system_info() +last_info_time = time.time() + +while running: + current_time = time.time() + + if current_time - last_info_time >= SYSTEM_INFO_INTERVAL: + ip, cpu, mem, disk = get_system_info() + last_info_time = current_time + + draw.rectangle((0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT), outline=0, fill=0) + + draw_text(0, f"IP: {ip}") + draw_text(1, f"CPU: {cpu}") + draw_text(2, mem) + draw_text(3, disk) + draw_text(4, time.strftime("%Y-%m-%d, %H:%M:%S"), font_date) + disp.image(image) disp.show() - time.sleep(0.1) + time.sleep(DISPLAY_REFRESH_INTERVAL) + +disp.fill(0) +disp.show()