G15Stats - a CPU/Memory/Swap/Network/Battery/Temperature/Fan Speed/CPU Frequencies usage meter for G15Daemon. The G15Stats requires libgtop development packages to be installed before compilation. GPU summary columns: The default --gpu auto collects ALL PCI devices (sorted PCI address) bound to amdgpu or nvidia at startup, including mixed vendors. Use --gpu dddd:bb:ss.f (also -gpu), for example --gpu 0000:01:00.0, to select a particular card. --gpu off restores the original layout and disables collection. An explicit missing/unsupported card shows N/A; auto with no supported card leaves the original layout unchanged. Restart to rediscover cards after hotplug. Intel and the nouveau/radeon drivers are not supported. Missing tools, permissions or individual metrics produce N/A, not 0. With one GPU the 160x43 summary retains its existing 4/5 indicator rows and labels. Graphs end at x=96 instead of 153; TOTAL moves to x=98. A divider at x=105 separates the column at x=108..159. With two or more GPUs the left x=0..50 shows compact CPU percent, R used system RAM, T total system RAM, SWP percent, and (in five-row mode) GPU count. Four-row mode uses y=1,10,19,28; five-row mode uses y=1,8,15,22,29. System RAM uses the same explicit units as VRAM. Two GPU columns at x=54..104 and x=108..159 are visible together, with dividers at x=51 and x=105 (the first column's glyphs end before its right divider). Each GPU has five lines at y=1,8,15,22,29: vendor/index plus PCI bus:slot.function, UTL percent, U used VRAM, T total VRAM, TEM temperature in Celsius (C). For example NV1 01:00.0 and AMD2 11:00.0 identify different cards. Indices are one-based positions in the selected PCI-sorted inventory, not NVIDIA ordinals; startup diagnostics map each index to its full domain:bus:slot.function address. More than two GPUs cycle through consecutive pairs every five seconds from startup (1/2, 3/4, ..., then 1/2); the last odd card occupies the first column. All cards are collected continuously, not just the visible pair. The display refresh interval can delay a page change: each draw advances at most one pair, so slow refresh never skips pairs. Inventory is bounded at 64 cards; overflow/enumeration failure is an explicit startup error, never silent omission. Use explicit PCI selection or off to recover. Hotplug requires restart. The bottom info bar at y=37..42 and all non-summary screens retain their geometry. Used and total are on separate lines so each retains an explicit MiB/GiB unit (TiB/PiB for very large values), rounded to one decimal. Other screens do not change. U/T refer to VRAM, not memory-controller utilization or system RAM; on AMD APUs the driver may report only the reserved VRAM carveout. AMD reads gpu_busy_percent, mem_info_vram_used/total (bytes), and the selected PCI device's hwmon/temp1_input (millidegrees C). NVIDIA optionally executes /usr/bin/nvidia-smi with pci.bus_id,utilization.gpu,memory.used,memory.total,temperature.gpu and --format=csv,noheader,nounits: one query for all NVIDIA cards, matched by PCI identity (including NVIDIA's eight-digit domain form), not response order. No CUDA/NVML SDK or additional build dependency is needed. Run as an ordinary user. Independent AMD workers and one batched NVIDIA worker wait two seconds between queries; drawing uses only a mutex-protected snapshot array. A stalled AMD read does not block another card or NVIDIA. NVIDIA queries share one 750ms monotonic deadline, fixed arguments/environment, no shell, bounded output, and SIGKILL on timeout or parent death. An unreaped child prevents further launches. Samples older than five seconds display N/A per card, including when a sysfs read stalls. Worker shutdown has one shared one-second join/reap budget; a stuck kernel read can outlive that budget in static storage until process exit (no restart after a failed stop). Normal application termination exits the process; no driver waits are added to signal handling. The -r display refresh interval still applies independently. No GPU settings are written. Official interface references: https://docs.kernel.org/gpu/amdgpu/thermal.html https://docs.kernel.org/gpu/amdgpu/driver-misc.html https://docs.nvidia.com/deploy/nvidia-smi/index.html GPU validation: After configuring/building, make check runs compiled parsing, units, missing-data, expiry, selection, subprocess deadline/reaping/parent-death and descriptor checks, plus real libg15render buffer checks. No daemon, input devices or synthetic GPU sysfs fixtures are used. ./gpu-test auto additionally checks every real GPU, its sysfs vendor identity and background cache (requires all four metrics). Explicit PCI arguments still test one card. ./render-test auto output writes real live 160x43 buffers to output-0.pgm and output-1.pgm (five/four rows), plus output (four rows). ./render-test off output renders the original GPU-off layout. For in-memory cases, ./render-test off output COUNT PAGE [large|unknown] selects 1..64 cards and a zero-based pair page. Omit PAGE to export the last pair. The default values exercise LLONG_MAX VRAM and -273C/1000C; large uses 100.0/192.0GiB and 1000C, while unknown uses N/A for all GPU metrics. For example ./render-test off output 2 tests worst-width dual-card values; ./render-test off output 3 1 tests the odd last page. With no arguments, make check retains the worst-width two-card case. These are rendering inputs, not simulated hardware or claims about the installed GPUs. These do not connect to g15daemon and are not physical LCD tests. make check also runs tests/render-layouts.sh for off, single, dual, large, unknown, odd-last and 64-card layouts, each in both summary modes. In addition to isolated-column comparisons, the test compares final GPU text, vertical TOTAL and time-footer cells directly with the installed font's bitmap bits. This independent oracle includes blank cells and checks full glyph bounds; repeating renderString on another canvas alone cannot detect shared clipping. Canvas initialization is tested starting from poisoned storage. Startup regression: make check also runs runtime-test through the full main loop for three frames with real libgtop and bitmap rendering. Only daemon transport is replaced by a private socketpair; no keyboard events are sent. ./runtime-test auto 21 additionally requires valid live GPU samples after twenty seconds. This is not a physical LCD or real daemon integration test. The bitmap-only client initializes its own canvas, avoiding g15r_initCanvas: a TTF-enabled renderer can otherwise write beyond a non-TTF caller's canvas and corrupt malloc metadata at startup, even with --gpu off. Each visual export also writes output-0.bin and output-1.bin: the actual 860 packed framebuffer bytes (one means black). With ImageMagick installed, run sh tests/render-images.sh /absolute/output/directory after generating frames there. It compares packed PBM, PGM and native PNG pixels, generates exact nearest-neighbor 8x images, and checks the 8x-to-native round trip. Per-scenario contact sheets use 4x tiles with labels outside the LCD and one column, avoiding very wide sheets that viewers may downscale. No trim or crop is applied. Inspect the individual native and 8x files as well as the contact sheets. The supplied default small font has only three ink columns plus a blank column per character; its N, M and other shapes can look incomplete when enlarged. Use the bitmap checks to distinguish those font shapes from missing pixels. Features: Summary Screen displays 4 or 5 indicators from CPU/Frequency/Memory/NET/Temperature/Fan Speed/Swap, along with current time. CPU Screen displays graphs of User/System/Nice and Idle time, along with LoadAVG and Uptime. Frequency Screen displays all CPU cores frequency with the total Memory Screen displays Memory Total & Free, and graph of Used vs Buffered+Cached Memory. Swap Screen displays Used, Free and Total swap space, along with the number of pages currently paged in/out. Network Screen displays Total bytes In/Out, history graph, Peak speed. Battery Status Screen displays battery charge data for up to three batteries Temperature Screen displays temperature status for available sensors Fan Speed Screen displays fan current speed for the available sensors Options: -i interface Gather statistics from named interface (ie -i eth0) -d Run in background (daemonise) -nsa Scale network graphs against highest speed recorded. The default is to scale against the highest peak in the current graph. -h Show help -r seconds Set the refresh interval to seconds The seconds must be between 1 and 300. ie -r 15 -u Display unicore graphs only on the CPU screen -t id Force to monitor temperature sensor id on start (ie -t 1) The id should point to sysfs path /sys/class/hwmon/hwmon[id]/device/temp1_input Default the sensor id is auto-detected. -f id Force to monitor fan speed sensor id on start (ie -f 1) The id should point to sysfs path /sys/class/hwmon/hwmon[id]/device/fan1_input Default the sensor id is auto-detected. -gt id Show temperature [id] in place of the maximal one on the Summary Screen with the option -gt id ie -gt 1 The id should point to sysfs path /sys/class/hwmon/hwmon../device/temp[id]_input -df Disable monitoring CPUs frequencies. -ir enable the bottom info bar content rotate cycle over all available sensors -vc The cpu cores will be calculated every time (for systems with the cpu hotplug) Usage: $> g15stats Once running, the separate screens can be switched to as follows: L2: Previous Screen L3: Next Screen L4: Alternative Screen (Doesn't work on Swap, Memory and Battery Screen) L5: Bottom Info bar mode BUGS: none currently known.