81 lines
5.4 KiB
Markdown
81 lines
5.4 KiB
Markdown
# linuxSmartie
|
|
Alphanumeric LCD controller software for Linux (kind of LCDSmartie for Windows but no GUI, no config file, no plugins, no Windows).
|
|
|
|
- Hardcoded to work with 4x40 character display because that's what I have. Uses Matrix Orbital protocol over serial. Should work with most other display sizes by modifying `src/lcd.c`. If you're trying to make it work with anything else, good luck.
|
|
- Big ol rewrite in C, like God intended because GOOD LORD C++ IS A MESS. Originally written with C23, then ported to C99 because it's a bigger numer. Idk maybe I'll port it to C23 again since it's supported since GCC 9 and default since GCC 15. It's pretty trivial to port it.
|
|
- -It is at feature parity with C++- It used to be at feature parity with C++ version, I added AIO and removed Home Assistant support.
|
|
- Vaguely inspired by suckless software philosophy, as in:
|
|
|
|
## The config is the source code
|
|
Same as plugins. Just write in more features scrub, learn some C, damn
|
|
|
|
## TODOs
|
|
- **think about feature creep**, do you REALLY need to set AIO pump mode **and** light based on temperature?
|
|
- set AIO fan curve too? default quiet is fine though tbh
|
|
- GPU power is jumpy, average? Use accumulator instead?
|
|
- Extra screens support perhaps? just halt sensors monitoring thread and print another struct on display if needed, have a semaphore or sth
|
|
- Maybe not even screens, keep the 1st line and change lines 2-4
|
|
- Media playback screen (use mpris, get playback info with mpris)
|
|
- In the lcd lib, reimplement all the features I have in picoSmartie + maybe finally add keypad support for both so I can toggle backlight (?) or change screens if I want any
|
|
- Screens could be automatic tbh, like if it detects media playing it switches to media screen, if in media screen and GPU power > 80W it switches to main (hwmon) screen
|
|
|
|
## LCD layout (on Windows)
|
|
|
|
It looks something like this
|
|
```
|
|
****************************************
|
|
0.4 0 ||09:30:36| 124fps
|
|
53/40/35C 4.53GB 544MB 32/40C
|
|
26W 424R 65.9W 0R 7/244W 11W
|
|
1,200V 1186MHz 3150 2/9MHz 0,112V
|
|
****************************************
|
|
```
|
|
|
|
### Ok but what does it all mean
|
|
In general left side is CPU/system stuff, right side is GPU stuff
|
|
```
|
|
{act core cnt} {whea} {time} {bar/1cpu%}{bar/AllCPU%}{TIME}{gpu%} {xbat} {fps}
|
|
|
|
{dieAvg}/{cache}/{iod}C {ram}GB {vram}GB {edge}/{junction}C
|
|
|
|
{cpuPpt}W {cpufan}R {wallPow}W {gpufan}R {gpuPpt}/{cap}W {gpuBoard}W
|
|
|
|
{cpuV}V {avgCpuFreq}MHz {gpuCoreClkCap} {gpuCoreClk}/{gpuMemClk}MHz {gpuV}V
|
|
```
|
|
|
|
Not all of this will be possible ofc but it's a start
|
|
|
|
Raw LCD Smartie lines below:
|
|
```
|
|
Text01="$dll(hwinfo,1,Average Active Core Count,1)$Fill(9)$dll(hwinfo,1,Total Errors,0)$Fill(14)$dll(tinybar2,8,$dll(hwinfo,1,Max CPU/Thread Usage,),1)$Fill(5)$dll(tinybar2,7,$dll(hwinfo,1,Total CPU Usage,),1)$Time(hh:mm:ss)$dll(tinybar2,6,$dll(hwinfo,1,GPU Utilization,),1)$dll(xbat,1,i,1)$Fill(33)$Right($dll(hwinfo,1,Framerate (Presented),0),$4%)fps"
|
|
Text02="$dll(hwinfo,1,1|CPU Die (average),0|a)/$dll(hwinfo,1,1|L3 Cache (CCD1),0)/$dll(hwinfo,1,1|CPU IOD Hotspot,0)$Chr(176)$Fill(10)$dll(format,2,$dll(hwinfo,1,1|8|4,0),0##B)B$Fill(24)$Right($dll(format,2,$dll(hwinfo,1,GPU D3D Memory Dedicated,0),0##B),$6%)B$Fill(34)$Right($dll(hwinfo,1,GPU|1|1,)/$dll(hwinfo,1,GPU|1|4,)$Chr(176),$7%)"
|
|
Text03="$dll(hwinfo,1,5|1,0)W$Fill(5)$dll(hwinfo,1,3|2,)R$Fill(14)$Right($dll(tasmopwr,1,tasmota-plug-pc.lan,)W,$6%)$Fill(21)$Right($dll(hwinfo,1,GPU|3|1,)R,$5%)$Fill(27)$Right($dll(hwinfo,1,GPU|5|9,0)/$dll(hwinfo,1,GPU|5|10,0)W,$8%)$Fill(36)$Right($dll(hwinfo,1,GPU|5|7,0)W,$4%)"
|
|
Text04="$dll(hwinfo,1,Vcore,3)V $Right($dll(hwinfo,1,Average Effective Clock,a)MHz,$7%)$Fill(16)$dll(hwinfo,1,GPU Shader Clock Frequency Limit,)$Fill(21)$Right($dll(hwinfo,1,GPU|6|2,)/$dll(hwinfo,1,GPU|6|4,)MHz,$12%)$Fill(34)$dll(hwinfo,1,GPU|2|1,3)V$CustomChar(1,16,6,9,8,8,9,6,0)"
|
|
```
|
|
|
|
### So what's still missing
|
|
- Per-core CPU load, doable but annoying
|
|
- FPS counter, maybe possible? Not really on wayland, by design
|
|
- Active core count, probably impossible but loadAvg is better
|
|
- GPU board power, probably impossible, it was estimated on windows anyway
|
|
- CPU cache/iod, likely impossible, zenpower doesnt show it
|
|
- GPU clock limit, probably impossible, gpu_metrics doesnt show it?
|
|
|
|
### Shit needed to compile on Debian 13
|
|
V simple:
|
|
```bash
|
|
sudo apt install build-essential cmake libusb-1.0-0-dev pkgconf
|
|
make configure
|
|
make build
|
|
```
|
|
You're probably on some meme immutable distro so use Debian 13 on distrobox. Any distro with GCC and cmake should work tbh.
|
|
|
|
### Additional notes
|
|
|
|
- To read motherboard sensors on ASUS ROG STRIX B550-A GAMING, as of Linux 6.16 (and up) you need to boot with kernel parameter of `acpi_enforce_resources=lax` and load the `nct6775` module.
|
|
- On Fedora Workstation it can be added by appending it to `/etc/kernel/cmdline`.
|
|
- On atomic desktops (Silverblue/Kinoite), `rpm-ostree kargs --append-if-missing=acpi_enforce_resources=lax`
|
|
- You need to be able to read RAPL as user. Create in `/etc/tmpfiles.d/intelrapl.conf` with content `z- /sys/class/powercap/intel-rapl:0/energy_uj 0440 root uucp - -`. Adjust uucp to whatever group applicable, like `dialout`.
|
|
- ModemManager might steal the port sometimes. Either disable the service or setup an udev rule: `SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000a", ENV{ID_MM_DEVICE_IGNORE}="1"`
|
|
- `compile_commands.json` is so clang understands this project, so we can edit it with helix/neovim. Generated with `bear -- make`, make sure to run `make nuke` beforehand.
|