#!/usr/bin/env python3 from qnapdisplay import QnapDisplay import time Lcd = QnapDisplay() import datetime import subprocess import re import sys from pathlib import Path def current_datetime(): return datetime.datetime.now().strftime("%Y-%m-%d %H:%M") def uptime_days(): # read /proc/uptime: first number is seconds since boot try: with open("/proc/uptime", "r") as f: secs = float(f.readline().split()[0]) return secs / 86400.0 except Exception as e: raise RuntimeError(f"could not read uptime: {e}") def ip_address(ifacename: str) -> str: """ Return ": " or ": None" if no IPv4 address. """ try: out = subprocess.check_output( ["ip", "-4", "-brief", "addr", "show", ifacename], stderr=subprocess.DEVNULL, text=True, ).strip() except subprocess.CalledProcessError: return f"{ifacename}: None" # sample output: "enp2s0 UP 192.0.2.5/24" m = re.search(r"(\d{1,3}(?:\.\d{1,3}){3})/\d{1,2}", out) ip = m.group(1) if m else None return f"{ip or 'None'}" def df_dev(path): # call: df -h /dev/md0 or df -h /mountpoint try: out = subprocess.check_output(["df", "-h", path], text=True).strip().splitlines() if len(out) < 2: return None hdr = out[0].split() vals = out[1].split() # map header->value; if headers differ, fall back to known positions if len(hdr) == len(vals): info = dict(zip(hdr, vals)) else: # usual df columns: Filesystem Size Used Avail Use% Mounted keys = ["Filesystem","Size","Used","Avail","Use%","Mounted"] info = dict(zip(keys, vals)) return info except subprocess.CalledProcessError: return None if Lcd.Init: Lcd.Enable() while 1: print(current_datetime()) print(f"uptime_days:{uptime_days():.4f}") Lcd.Write(0, current_datetime()) Lcd.Write(1, (f"uptime_days: {uptime_days():.4f}")) time.sleep(2) enp2s0 = ip_address("enp2s0") enp3s0 = ip_address("enp3s0") print(f"enp2s0 {enp2s0}") print(f"enp3s0 {enp3s0}") Lcd.Write(0, f"enp2s0:"); Lcd.Write(1, f"{enp3s0}"); time.sleep(2) Lcd.Write(0, f"enp2s0:"); Lcd.Write(1, f"{enp3s0}"); time.sleep(2) dev = "/dev/md0" info = df_dev(dev) print(info) if info: # ensure we print the Use% specifically for /dev/md0 use = info.get("Use%") or info.get("Use") or info.get("Use%") size = info.get("Size") or info.get("1K-blocks") or info.get("SIZE") used = info.get("Used") avail = info.get("Avail") or info.get("Available") mounted = info.get("Mounted") or info.get("Mounted on") print(f"df {dev}: Size={size or 'N/A'} Used={used or 'N/A'} Avail={avail or 'N/A'} Use%={use or 'N/A'} Mounted={mounted or 'N/A'}") else: print(f"df {dev}: not found or error", file=sys.stderr) Lcd.Write(0, f"md0size: {size}") Lcd.Write(1, f"md0use: {use}") time.sleep(2) else: print('Oops something went wrong here')