The brain PC · Chapter 25 · Time: 3 hours, plus about 8 GB of downloads · Level: Intermediate · Status: Partly test-built
bigbuddy running Fedora 44 KDE with the NVIDIA driver, staying awake and waking over the network, and serving the google/gemma-4-12b language model on port 1234 to Buddy and to the robot.
bigbuddy is the desktop PC with the RTX 5070 Ti. It runs everything that needs a big GPU: Buddy's speech
recognition, the language model that answers Buddy's questions and the robot's "thoughts", and wake-word training.
The robot never needs bigbuddy to drive (decision 2026-09-30), but without it Buddy cannot hear, think or speak.
Most of this chapter was done by the owner before the robot project started (2026-07-24 to 2026-08-08). Those
steps are reconstructed from bigbuddy's dnf history, its live files, and rpm -q. The steps from 2026-09-28
(power settings, enabling the LM Studio server) are in the command log with their output. How LM Studio itself was
installed and how the model was downloaded is not recorded; those steps are marked.
Why a separate PC for the brain
On 2026-09-28 the owner split the work: the robot does vision, mapping, driving and safety; bigbuddy does the
wake word, speech-to-text, the large language model and text-to-speech (docs/decisions.md2026-09-28,
"Compute split"). On 2026-09-30 a 4-billion-parameter model running on the Jetson starved the robot of memory
and the kernel killed robot processes; since then bigbuddy is the brain and the robot is navigation and vision.
A thought from the 12B model on bigbuddy took 1.37 s, against 5-6 s on the robot.
bigbuddy's login shell is fish, not bash
Every@bigbuddyblock in chapters 25 to 28 is bash. Afterssh bigbuddy, typebashfirst. From your
laptop, send scripts the way the record does:ssh bigbuddy 'bash -s' <<'EOF' ... EOF. fish has no
heredocs and no${VAR:-default}; on 2026-09-28 a bash loop sent straight to fish failed with
fish: Expected a variable name after this $.
sudo asks for a password on bigbuddy
Unlike the robot (chapter 6), bigbuddy has no passwordless sudo. Everysudoline in this chapter is one you
type yourself at the keyboard or in an interactive ssh session.
| Item | Value (live, 2026-10-07) |
|---|---|
| OS | Fedora 44 KDE Plasma 6.7.5 on Wayland, kernel 7.2.5-200.fc44.x86_64 |
| GPU | NVIDIA GeForce RTX 5070 Ti, 16303 MiB, driver 615.71.09 |
| RAM | 32 GB (free -h shows 30Gi) |
| User | burgerbarn, uid 1001 (XDG_RUNTIME_DIR=/run/user/1001) |
| Wired | enp8s0, MAC , 192.168.1.111 (DHCP reservation) |
| Wi-Fi | wlp7s0, 192.168.1.59 |
| System Python | 3.14.7 |
| Firewall | default zone FedoraWorkstation |
Check your uid before you copy any path
bigbuddy'sburgerbarnis uid 1001; the robot's is 1000. Several bigbuddy files written later (the robot mic
pipe in chapter 27) contain/run/user/1001. On 2026-10-06 a PipeWire config with a FIFO under/run/user/1000
made PipeWire exit on start and took all of bigbuddy's audio down (docs/lessons.md2026-10-06). Runid -u
on your install and use that number.
New idea: why the brain needs a GPU
A language model is a long list of numbers (its weights). Producing one word means multiplying your text
through billions of those numbers. A CPU does a handful of multiplications at a time; a GPU does thousands at
once, and it reads its own fast memory (VRAM) far quicker than a CPU reads RAM. The rule of thumb: the model
has to fit in VRAM to be fast. bigbuddy's 16 GB of VRAM holds the language model (9456 MiB loaded), Buddy's
voice process with the Whisper speech model (2174 MiB) and the desktop, with about 4 GB to spare (live
nvidia-smi, 2026-10-07). That spare is why wake-word
training must pause Buddy (chapter 26).
Install the Fedora 44 KDE Plasma edition and create the user burgerbarn. bigbuddy's system came from the
Fedora KDE image (dnf history transactions 1-2, built 2026-04-22); the owner's first changes are dated
2026-07-31.
Not test-built
The install media, partitioning and the order in which users were created are not recorded. bigbuddy's root
is btrfs on a 929 GB disk with snapper snapshots (snapper timers were later switched off by the owner,
docs/hardware.md"bigbuddy screen", 2026-10-01). Whyburgerbarnended up uid 1001 is unknown.
Check
Runcat /etc/fedora-release; uname -r; id -u. On bigbuddy (2026-09-28):Fedora release 44 (Forty Four) 7.2.5-200.fc44.x86_64and
id -uprints1001. Your kernel and uid may differ; note both.
Fedora ships only free software. The NVIDIA driver and the full ffmpeg come from RPM Fusion, a separate package
repository. This is dnf history transaction 8 (2026-07-31):
On bigbuddy:
sudo dnf install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-44.noarch.rpm https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-44.noarch.rpm
Check
rpm -q rpmfusion-free-release rpmfusion-nonfree-releaseprints:rpmfusion-free-release-44-3.noarch rpmfusion-nonfree-release-44-3.noarch
ls /etc/yum.repos.d/ | grep rpmfusionlists, among others,rpmfusion-nonfree-nvidia-driver.repo.
Transaction 9 (2026-07-31):
On bigbuddy:
sudo dnf install akmod-nvidia xorg-x11-drv-nvidia-cuda
akmod-nvidia does not contain a ready kernel module. It contains the driver source and a service (akmods) that
builds a module for whatever kernel you run and installs it as a package. On bigbuddy that build appears as the
very next transaction, 10: a package kmod-nvidia-7.1.5-201.fc44.x86_64-3:610.43.03-1.fc44.x86_64 installed from
@commandline. Every kernel update repeats the build. xorg-x11-drv-nvidia-cuda adds nvidia-smi and the CUDA
driver library that LM Studio and Whisper use.
The driver installed on 2026-07-31 was 610.43.03; later dnf update runs moved it to 615.71.09.
Not test-built
How long the owner waited before rebooting is not recorded. The module has to be built before the reboot that
loads it; ifnvidia-smifails after a reboot, check whether akmod-nvidia-<your kernel>package exists
(rpm -qa 'kmod-nvidia*').
Reboot, then check.
Check
nvidia-smi --query-gpu=name,driver_version,memory.used,memory.total --format=csv,noheaderprints one line.
Live on bigbuddy, with Buddy and the model loaded:NVIDIA GeForce RTX 5070 Ti, 615.71.09, 12279 MiB, 16303 MiBOn a fresh install memory.used is a few hundred MiB.
modinfo -F version nvidiaprints615.71.09, and
lsmodlistsnvidia,nvidia_modeset,nvidia_drmandnvidia_uvm. The live kernel command line contains
rd.driver.blacklist=nouveau,nova_core modprobe.blacklist=nouveau,nova_core, which keeps Fedora's open
drivers off the card.
If it fails
- Secure Boot: bigbuddy has it off (
mokutil --sb-stateprintsSecureBoot disabled). With Secure Boot on,
a self-built module is not trusted by the kernel; that path was never tried on this machine.nvidia-smimissing or "couldn't communicate with the NVIDIA driver" after a kernel update: the akmods
build for the new kernel has not happened yet. Not seen on this machine.
The owner installed it on 2026-07-31 (transaction 11) from NVIDIA's own repository
(/etc/yum.repos.d/nvidia-container-toolkit.repo, baseurl https://nvidia.github.io/libnvidia-container/stable/rpm/$basearch):
On bigbuddy:
sudo dnf install -y nvidia-container-toolkit
Nothing in this project uses the GPU from a container on bigbuddy (the media containers in chapter 28 do not), so
you can skip this step.
Not test-built
The command that addednvidia-container-toolkit.repois not recorded. The repository file exists and the
installed package came from it (dnf info --installed nvidia-container-toolkit:From repository : nvidia-container-toolkit, version 1.20.1).
Check
nvidia-ctk --versionprintsNVIDIA Container Toolkit CLI version 1.20.1. The file
/var/run/cdi/nvidia.yamlis written at every boot (nvidia-cdi-refreshis enabled).
Fedora's ffmpeg-free leaves out patent-encumbered codecs. Swap it for RPM Fusion's full build (transaction 12)
and add mpv (transaction 27, 2026-08-07). Buddy plays music with mpv (chapter 28). podman is part of the base
image.
On bigbuddy:
sudo dnf swap ffmpeg-free ffmpeg --allowerasing
sudo dnf install mpv
Check
rpm -q ffmpeg mpv podmanprints:ffmpeg-8.1.2-3.fc44.x86_64 mpv-0.41.0-5.fc44.x86_64 podman-5.8.7-1.fc44.x86_64
ffmpeg -hide_banner -encoders 2>/dev/null | grep -E " (libx264|h264_nvenc) "showslibx264and
h264_nvenclines.rpm -q ffmpeg-freeprintspackage ffmpeg-free is not installed.
bigbuddy logs burgerbarn into Plasma at boot. Fedora 44 KDE uses the Plasma Login Manager (plasmalogin.service,
not SDDM). The live /etc/plasmalogin.conf is:
On bigbuddy:
[Autologin]
Session=plasma.desktop
User=burgerbarn
Create it with your editor as root (for example sudoedit /etc/plasmalogin.conf), paste those three lines, and
reboot.
Why autologin
The KDE session runs the power manager (powerdevil, step 8) and Buddy's face screen (chapter 28). Buddy's
voice itself does not need a login (linger, below). Anyone at bigbuddy's keyboard gets the desktop without a
password; that is the trade.
Not test-built
The file is dated 2026-07-31 11:20 andrpm -Vreports it modified, so the owner wrote it, but how (editor or
System Settings) is not recorded./etc/plasmalogin.conf.d/is empty.voice/README.md("Boot (2026-10-01)")
says bigbuddy has no autologin; the live file and the journal say it does.
Check
After a reboot,journalctl -b | grep plasmalogin-autologinshows a line like the one from the 2026-10-04
boot:pam_unix(plasmalogin-autologin:session): session opened for user burgerbarn.
New idea: systemd user services and linger
systemd runs two kinds of services: system services (as root, in/etc/systemd/system) and user services
(as you, in~/.config/systemd/user, managed withsystemctl --user). Buddy, LM Studio and the audio
server (PipeWire) are user services. Normally they start when you log in and stop when you log out. "Linger"
tells systemd to start your user services at boot and keep them running with nobody logged in.
On bigbuddy:
sudo loginctl enable-linger burgerbarn
Not test-built
bigbuddy has linger on (/var/lib/systemd/linger/burgerbarnexists), but when and by whom it was enabled is
not recorded;voice/README.mdfirst states "linger=yes" on 2026-10-01. The command above is the standard one.
Check
loginctl show-user burgerbarn -p LingerprintsLinger=yes.
New idea: a local language model
A language model reads text (and, with a vision add-on, images) and writes the most likely continuation.
"Local" means it runs on bigbuddy's GPU, not in the cloud: no account, no per-request cost, and it keeps
working when the internet is down. LM Studio is the program that loads the model onto the GPU and answers on
an OpenAI-compatible web API (POST /v1/chat/completions), so any program that can send JSON over HTTP can
use it. Buddy and the robot's thinker both do exactly that.
New idea: quantization
The model isgoogle/gemma-4-12b: about 12 billion weights. Stored as 16-bit numbers that is about 24 GB,
too big for 16 GB of VRAM. A quantized file stores most weights in 4 bits with a shared scale per small
block. The file Buddy uses isgemma-4-12B-it-Q4_K_M.gguf: Q4 = mostly 4-bit, K_M = the "medium" mix that
keeps some layers at higher precision. It is 7,381,382,944 bytes, about 4.9 bits per weight on average. The
answers are slightly less precise than the full model and the file fits with room for Whisper. The second
file,mmproj-gemma-4-12B-it-BF16.gguf(175 MB), is the vision projector: it turns a camera image into
something the language model can read. The robot's look-arounds and Buddy's "what do you see" use it.
Why LM Studio and why this model
The owner chose LM Studio over Ollama on 2026-09-28 (docs/decisions.md, "LLM runtime"); Ollama is also
installed on bigbuddy (/usr/local/bin/ollama) and is not used by Buddy or the robot. LM Studio returns
native tool calls for gemma-4-12b, which Buddy's tools need (chapter 26), and it loads the model on the first
request and unloads it after an hour idle.
What is on bigbuddy today:
| Part | Path |
|---|---|
lms command-line tool |
~/.lmstudio/bin/lms |
Headless daemon (llmster) |
~/.lmstudio/llmster/0.0.20-1/llmster, started at boot |
| Models | ~/.lmstudio/models/ |
| Settings | ~/.lmstudio/settings.json, ~/.lmstudio/.internal/http-server-config.json |
| Desktop app unit (not enabled) | ~/.config/systemd/user/lmstudio.service, ExecStart=/home/burgerbarn/openwebui-stack/lmstudio/lmstudio.AppImage |
Not test-built: the LM Studio install
How LM Studio was installed is not recorded. The disabledlmstudio.servicepoints at an AppImage in
~/openwebui-stack/lmstudio/, but that directory no longer exists on bigbuddy (checked 2026-10-07; the
survey of the same day still lists it). Thelmsbinary is dated 2026-10-04 21:20, the time of the last boot.
The LM Studio version is not known beyond the daemon directory name0.0.20-1(lms versionprinted only
its banner). Install LM Studio for Linux from its maker by their current instructions, and make sure
~/.lmstudio/bin/lmsexists before you go on.
Not test-built: the model download
The model files are dated 2026-07-24; how they were downloaded is not recorded. You need the
lmstudio-community GGUF of Gemma 4 12B instruct at Q4_K_M plus its BF16 mmproj, in
~/.lmstudio/models/lmstudio-community/gemma-4-12B-it-GGUF/:gemma-4-12B-it-Q4_K_M.gguf 7381382944 bytes mmproj-gemma-4-12B-it-BF16.gguf 175115296 bytes
Check
~/.lmstudio/bin/lms lslists the model. On bigbuddy (2026-09-28) the first lines were:You have 7 models, taking up 44.01 GB of disk space. LLM PARAMS ARCH SIZE DEVICE google/gemma-4-12b (1 variant) 12B gemma4 7.56 GB Local google/gemma-4-12b-qat (1 variant) 12B gemma4 7.15 GBOnly
google/gemma-4-12bis used by this project.
Two settings files decide how the server behaves. These are the live values that matter (other keys omitted; the
files also hold download credentials, which this guide does not print):
~/.lmstudio/settings.json
| Key | Value | Meaning |
|---|---|---|
developer.jitModelTTL.enabled |
true |
unload a model loaded on demand after it sits idle |
developer.jitModelTTL.ttlSeconds |
3600 |
idle time before unload: 1 hour |
developer.unloadPreviousJITModelOnLoad |
true |
loading another model on demand unloads the previous one |
defaultContextLength |
custom, 12192 |
context length for new loads |
~/.lmstudio/.internal/http-server-config.json
| Key | Value | Meaning |
|---|---|---|
autoStartOnLaunch |
true |
the API server starts with LM Studio |
port |
1234 |
API port |
networkInterface |
0.0.0.0 |
answer on every interface, so the robot can reach it |
cors |
true |
allow browser pages from other origins |
justInTimeModelLoading |
true |
load a model when a request names it |
Not test-built
Where these were set (the app's developer settings or by editing the JSON) is not recorded. The live model
reports a context of 12288 tokens while the setting says 12192; why is not known.
The qat variant has a joke preset
~/.lmstudio/.internal/user-concrete-model-default-config/google/gemma-4-12b-qat.jsongives
google/gemma-4-12b-qata system prompt "only answer in olde english". Buddy and the robot ask for
google/gemma-4-12b, which has no preset. If replies come back in Olde English, something asked for the qat
model.
The owner's unit, ~/.config/systemd/user/lmstudio-server.service (written 2026-08-08):
On bigbuddy:
[Unit]
Description=LM Studio headless API server
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/home/burgerbarn/.lmstudio/bin/lms server start --port 1234 --bind 0.0.0.0 --cors
ExecStop=/home/burgerbarn/.lmstudio/bin/lms server stop
[Install]
WantedBy=default.target
lms server start tells the LM Studio daemon to open the API and returns at once, so the unit is a oneshot
that systemd keeps "active" after the command exits (RemainAfterExit=yes). --bind 0.0.0.0 makes it answer on
the LAN. No model is loaded here: the first request loads it.
It was disabled until 2026-09-28; it was enabled then because Buddy's first test failed without it. Enable it:
On bigbuddy:
systemctl --user daemon-reload
systemctl --user enable --now lmstudio-server.service
systemctl --user is-active lmstudio-server.service
~/.lmstudio/bin/lms ps
Check
Output on 2026-09-28:Created symlink '/home/burgerbarn/.config/systemd/user/default.target.wants/lmstudio-server.service' → '/home/burgerbarn/.config/systemd/user/lmstudio-server.service'. active No models are currently loaded.
~/.lmstudio/bin/lms server statusprintsThe server is running on port 1234.
reasoning_effort matters. gemma-4-12b "thinks" before it answers unless told not to, and the thinking counts
against max_tokens. Test both ways, as was done on 2026-09-28:
On bigbuddy:
q(){ curl -s localhost:1234/v1/chat/completions -H "Content-Type: application/json" -d "$1" | python3 -c "import json,sys; r=json.load(sys.stdin); m=r['choices'][0]['message']; print(repr(m.get('content'))[:200]); print('reasoning chars:',len(m.get('reasoning_content') or m.get('reasoning') or ''), r.get('usage',{}).get('completion_tokens_details'))"; }
B='"model":"google/gemma-4-12b","messages":[{"role":"system","content":"You are Buddy, a small home robot. Reply in one short sentence."},{"role":"user","content":"yo buddy, what can you do?"}]'
echo "== max_tokens 600"; time q "{$B,\"max_tokens\":600}"
echo "== reasoning_effort none"; time q "{$B,\"max_tokens\":200,\"reasoning_effort\":\"none\"}"
The first request also loads the model (JIT), so run it twice if the first one is slow.
Check
Output on 2026-09-28 (model already loaded):== max_tokens 600 'I can answer your questions and help make your day a little easier!' reasoning chars: 1350 {'reasoning_tokens': 346} real 0m4.513s == reasoning_effort none 'I can help you with tasks, answer questions, and keep your home running smoothly!' reasoning chars: 0 {'reasoning_tokens': 0} real 0m0.313s0.3 s instead of 4.5 s. Buddy and the robot always send
"reasoning_effort": "none". Thenlms psshows the
loaded model with its unload timer:IDENTIFIER MODEL STATUS SIZE CONTEXT PARALLEL DEVICE TTL google/gemma-4-12b google/gemma-4-12b IDLE 7.56 GB 12288 4 Local 60m / 1h
If it fails
- Empty reply. The first test on 2026-09-28 sent
max_tokens: 60withoutreasoning_effort: the reply
content was empty andcompletion_tokenswas 60, all spent on thinking. Send"reasoning_effort": "none"
(docs/status.md: "reasoning_effort: none or replies come back empty").- Connection refused on localhost:1234. Buddy's first
--asktest on 2026-09-28 failed with
HTTPConnectionPool(host='localhost', port=1234): Max retries exceeded ... Failed to establish a new connectionbecauselmstudio-server.servicewas disabled. Enable it (above).The server is not running.followed byWaking up LM Studio service...fromlms: the daemon was
asleep;lmswakes it. Runlms server startor restart the unit.- HTTP 400 "terminated" under load. LM Studio sometimes answers this when several requests overlap
(docs/capabilities.md). Callers must treat it as "no answer this time"; that is one reason nothing in the
robot's driving path depends on bigbuddy (decision 2026-09-30).
The robot's thinker calls http://192.168.1.111:1234/v1/chat/completions (vision/think.py, BRAIN_URL).
Fedora's default FedoraWorkstation firewall zone already allows ports 1025-65535 TCP and UDP from the LAN; the
owner's apply.sh (step 8) also opens 1234/tcp explicitly.
Check
On bigbuddy,firewall-cmd --get-default-zoneprintsFedoraWorkstation, and
firewall-cmd --zone=FedoraWorkstation --list-portsprints22/tcp 1025-65535/tcp 1025-65535/udp.
ss -ltn | grep :1234showsLISTEN 0 511 0.0.0.0:1234 0.0.0.0:*.
On your laptop:
ssh -o ConnectTimeout=8 rosorin-wifi 'curl -s -m 6 http://192.168.1.111:1234/v1/models | python3 -c "import json,sys; print([m[\"id\"] for m in json.load(sys.stdin).get(\"data\",[])])"'
Check
From the robot on 2026-10-05:['google/gemma-4-12b', 'openai/gpt-oss-20b', 'google/gemma-4-e4b', 'qwen/qwen3.5-9b', 'google/gemma-4-12b-qat', 'nvidia/nemotron-3-nano-4b', 'text-embedding-nomic-embed-text-v1.5']Your list shows the models you downloaded;
google/gemma-4-12bmust be in it.
On 2026-09-28 bigbuddy was asleep when the work started (ssh and ping timed out at 09:35 local), and it suspended
again at 10:15 in the middle of wake-word training. A suspended bigbuddy means a deaf Buddy and a robot with no thoughts. The live setup
has three parts: KDE never suspends on AC power, a guard blocks sleep while the GPU is busy, and Wake-on-LAN can
wake it if it does go down.
~/wol-suspend-setup/The owner wrote three files on 2026-08-08. They are not in the repo; their full text is below. Create the folder
and the guard first.
Create ~/wol-suspend-setup/lmstudio-busy-guard.sh:
On bigbuddy:
#!/usr/bin/env bash
# Holds a systemd sleep-inhibit lock while the GPU is actively generating
# tokens, so idle-suspend never cuts off an in-flight LM Studio response.
THRESHOLD=5
INTERVAL=15
INHIBIT_PID=""
release() {
if [ -n "$INHIBIT_PID" ] && kill -0 "$INHIBIT_PID" 2>/dev/null; then
kill "$INHIBIT_PID" 2>/dev/null
fi
INHIBIT_PID=""
}
trap 'release; exit 0' TERM INT
while true; do
util=$(nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits 2>/dev/null | head -1)
if [ -n "$util" ] && [ "$util" -gt "$THRESHOLD" ] 2>/dev/null; then
if [ -z "$INHIBIT_PID" ] || ! kill -0 "$INHIBIT_PID" 2>/dev/null; then
systemd-inhibit --what=sleep --mode=block \
--who="lmstudio-busy-guard" \
--why="LM Studio is actively generating a response" \
sleep infinity &
INHIBIT_PID=$!
fi
else
release
fi
sleep "$INTERVAL"
done
Every 15 s it reads GPU utilisation. Above 5 % it starts systemd-inhibit ... sleep infinity, which holds a
"no sleep" lock for as long as that process lives. When the GPU goes quiet it kills the process and the lock is
gone. The trap releases the lock when systemd stops the service.
Create ~/.config/systemd/user/lmstudio-busy-guard.service:
On bigbuddy:
[Unit]
Description=Block suspend while LM Studio GPU is busy
[Service]
ExecStart=/home/burgerbarn/wol-suspend-setup/lmstudio-busy-guard.sh
Restart=always
[Install]
WantedBy=default.target
Create ~/wol-suspend-setup/apply.sh:
On bigbuddy:
#!/usr/bin/env bash
set -e
cd "$(dirname "$0")"
echo "== Persisting Wake-on-LAN (magic packet) on enp8s0 =="
sudo nmcli connection modify "Wired connection 1" 802-3-ethernet.wake-on-lan magic
sudo nmcli connection up "Wired connection 1" >/dev/null
echo "== Enabling firewall access to LM Studio's API (port 1234) =="
sudo firewall-cmd --permanent --add-port=1234/tcp --zone="$(sudo firewall-cmd --get-default-zone)"
sudo firewall-cmd --reload
echo "== Setting KDE auto-suspend: 30 min idle on AC power =="
kwriteconfig6 --file powerdevilrc --group AC --group SuspendAndShutdown --key AutoSuspendAction 1
kwriteconfig6 --file powerdevilrc --group AC --group SuspendAndShutdown --key IdleTimeoutSec 1800
systemctl --user restart plasma-powerdevil.service
echo "== Installing LM Studio busy-guard (blocks suspend mid-generation) =="
chmod +x lmstudio-busy-guard.sh
systemctl --user daemon-reload
systemctl --user enable --now lmstudio-busy-guard.service
echo "== Starting LM Studio headless API server on login =="
systemctl --user enable --now lmstudio-server.service
echo
echo "Done. Verify:"
echo " nmcli -f 802-3-ethernet.wake-on-lan connection show 'Wired connection 1'"
echo " kreadconfig6 --file powerdevilrc --group AC --group SuspendAndShutdown --key AutoSuspendAction"
echo " systemctl --user status lmstudio-busy-guard.service lmstudio-server.service"
echo
echo "Remaining manual step: in BIOS, Settings -> Platform Power -> set ErP to Disabled."
echo "Run revert.sh at any time to undo everything on this machine."
What it does, in order: Wake-on-LAN on the wired connection, port 1234 in the firewall, KDE suspend after 30 min
idle on AC, the busy guard, and the LM Studio server unit from step 7. It expects both unit files to exist
already.
Create ~/wol-suspend-setup/revert.sh, the owner's undo:
On bigbuddy:
#!/usr/bin/env bash
set -e
cd "$(dirname "$0")"
echo "== Stopping LM Studio headless server auto-start =="
systemctl --user disable --now lmstudio-server.service 2>/dev/null || true
rm -f /home/burgerbarn/.config/systemd/user/lmstudio-server.service
echo "== Removing LM Studio busy-guard =="
systemctl --user disable --now lmstudio-busy-guard.service 2>/dev/null || true
rm -f /home/burgerbarn/.config/systemd/user/lmstudio-busy-guard.service
systemctl --user daemon-reload
echo "== Reverting KDE auto-suspend to original (never suspend on AC) =="
kwriteconfig6 --file powerdevilrc --group AC --group SuspendAndShutdown --key AutoSuspendAction 0
kwriteconfig6 --file powerdevilrc --group AC --group SuspendAndShutdown --key IdleTimeoutSec --delete
systemctl --user restart plasma-powerdevil.service
echo "== Closing firewall port 1234 =="
sudo firewall-cmd --permanent --remove-port=1234/tcp --zone="$(sudo firewall-cmd --get-default-zone)"
sudo firewall-cmd --reload
echo "== Reverting Wake-on-LAN setting to default =="
sudo nmcli connection modify "Wired connection 1" 802-3-ethernet.wake-on-lan default
sudo nmcli connection up "Wired connection 1" >/dev/null
echo
echo "Reverted. If you disabled ErP in BIOS for this, that's still off -- re-enable it there manually if you want it back."
Note that revert.sh deletes the LM Studio server unit. Keep a copy of it if you ever run the revert.
Run the kit:
On bigbuddy:
chmod +x ~/wol-suspend-setup/*.sh
~/wol-suspend-setup/apply.sh
apply.sh sets KDE to suspend after 30 minutes idle (AutoSuspendAction=1). On 2026-09-28 that was switched off
for the project. The edit was made with sed; a D-Bus "reparse" did not apply it (bigbuddy suspended at 10:15
anyway). Restarting the power manager did.
On bigbuddy:
cp ~/.config/powerdevilrc ~/.config/powerdevilrc.bak-20260928
sed -i 's/^AutoSuspendAction=1$/AutoSuspendAction=0/' ~/.config/powerdevilrc
systemctl --user restart plasma-powerdevil.service
kreadconfig6 --file powerdevilrc --group AC --group SuspendAndShutdown --key AutoSuspendAction
Check
The last command prints0. The live~/.config/powerdevilrcis:[AC][Display] TurnOffDisplayIdleTimeoutSec=3600 [AC][SuspendAndShutdown] AutoSuspendAction=0 IdleTimeoutSec=1800 PowerButtonAction=8
IdleTimeoutSec=1800has no effect whileAutoSuspendAction=0. The display-off value (screens off after an
hour idle) is dated 2026-09-29; who set it, and how, is not recorded.
If it fails
- Re-running
apply.shturns suspend back on. It writesAutoSuspendAction 1every time
(docs/hardware.md, bigbuddy voice host). After any run ofapply.sh, repeat thesedand restart above.- The setting is in the file but bigbuddy still suspends. A
qdbus-qt6 ... reparseConfigurationcall
reported success on 2026-09-28 and bigbuddy suspended anyway. Restartplasma-powerdevil.service.- Keeping it awake from another machine. Pinging or an open ssh session does not stop KDE's idle
suspend. A remotesystemd-inhibitis refused by polkit. What worked (docs/lessons.md):
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus kde-inhibit --power --screenSaver sleep N.
Check
systemctl --user is-active lmstudio-server lmstudio-busy-guardprintsactivetwice.
nmcli -f 802-3-ethernet.wake-on-lan connection show 'Wired connection 1'prints
802-3-ethernet.wake-on-lan: magic.
Not test-built
apply.shends by asking for one BIOS change: Settings, Platform Power, ErP Disabled. Whether the owner made
it is not recorded. ErP decides whether the network card keeps power when the PC is fully off. The wake below
was tested from suspend, not from power-off.
Test it from your laptop while bigbuddy is suspended. This is the exact snippet that woke it on 2026-09-28
(Python on the Mac, broadcast to UDP ports 9 and 7):
On your laptop:
python3 - <<'EOF'
import socket
mac=bytes.fromhex("30560f42eef7"); pkt=b"\xff"*6+mac*16
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
for addr in ("255.255.255.255","192.168.1.255"):
for port in (9,7): s.sendto(pkt,(addr,port))
print("magic packet sent to <bigbuddy-ethernet-MAC>")
EOF
for i in $(seq 1 12); do ping -c1 -t2 192.168.1.111 >/dev/null 2>&1 && { echo "bigbuddy up after ~$((i*5))s"; break; }; sleep 3; done; ssh -o ConnectTimeout=8 bigbuddy 'echo ssh-ok' 2>&1 | tail -1
A magic packet is 6 bytes of ff followed by the target MAC repeated 16 times. Put your own MAC in fromhex
(from ip -br link show enp8s0).
Check
Output on 2026-09-28:magic packet sent to <bigbuddy-ethernet-MAC> bigbuddy up after ~20s ssh-ok
If it fails
- ssh times out but bigbuddy is not asleep. On 2026-09-28 at 10:50 local, ssh timed out because bigbuddy
was out of memory (chapter 26), not asleep; sending WOL packets did nothing. Checkpingfirst: WOL only
helps when ping fails (docs/lessons.md, "bigbuddy OOM").- A long job after a suspend. A training run survived suspend and resume (it retried its download), but
it lost the time asleep. Keep suspend off.
nvidia-smi shows the RTX 5070 Ti with driver 615.71.09 (or newer).loginctl show-user burgerbarn -p Linger prints Linger=yes, and bigbuddy logs in by itself after a reboot.systemctl --user is-active lmstudio-server lmstudio-busy-guard prints active active.reasoning_effort: none test answers in well under a second once the model is loaded.curl http://192.168.1.111:1234/v1/models lists google/gemma-4-12b.kreadconfig6 ... AutoSuspendAction prints 0, and a magic packet from your laptop wakes bigbuddy fromWhere this comes from
sources/survey_bigbuddy.md(sections 1, 2 Phase 0-1, 4 and 5), read-only checks on bigbuddy 2026-10-07
(dnf history listanddnf history info 8-12,rpm -q,nvidia-smi,mokutil --sb-state,
/etc/plasmalogin.conf,~/.config/powerdevilrc,~/wol-suspend-setup/*,
~/.config/systemd/user/lmstudio-*.service, LM Studio settings keys,loginctl,nmcli,firewall-cmd,
ss -ltn),sources/cmdlog_bigbuddy.md2026-09-28 16:39-19:57 UTC (powerdevil edit and restart, LM Studio
load andreasoning_efforttest, WOL test, enablinglmstudio-server.service),
sources/cmdlog_robot.md2026-10-05 19:43 UTC (models list from the robot),docs/hardware.md
"bigbuddy voice host" and "bigbuddy screen",docs/lessons.md(bigbuddy suspends on idle; bigbuddy OOM;
2026-10-06 wrong runtime path),docs/decisions.md2026-09-28 (compute split, LLM runtime) and 2026-09-30,
docs/capabilities.mdline 24,voice/README.md"Boot (2026-10-01)",vision/think.py.
← Wheel skills - explore, practise, come, go home · Contents · Buddy's voice →