-
Notifications
You must be signed in to change notification settings - Fork 0
Installation
How to install, enable, upgrade, and uninstall afanctl — one command from the
release, or from a checkout. packaging/PKGBUILD builds your working tree;
packaging/aur/PKGBUILD builds a released source tarball and is the recipe for
the AUR (complete, but unpublished — the AUR has closed registration to new
maintainers). Both install the same five files, and afanctl.service, the
polkit rule 49-afanctl.rules and afanctl.toml.default live in packaging/
and travel inside the release tarball.
| Requirement | Detail |
|---|---|
| Machine | Pre-T2 Intel Mac with applesmc + coretemp (tested: MacBook Pro 2017 A1708, MacBookPro14,1). No pwm* attributes needed — applesmc does not expose them. |
| OS | Arch Linux (Omarchy) with systemd as PID1, kernel 7.2.3-arch1-3 at verification time. |
| Build tool |
extra/rust 1:1.98.1 (cargo 1.98.1, rustc 1.98.1), makepkg (base-devel). |
| Privileges |
makepkg -si and systemctl enable/start, doctor --roundtrip, selftest-panic, and any mode-changing verb against the live daemon need root (sudo/pkexec). Plain status reads work as a normal user against fixtures; against live /sys the L2-related doctor checks need root (see Diagnostics (doctor)). |
| Distribution | A tagged GitHub release (v0.1.0) plus install.sh at releases/latest/download/ for the one-command install. No AUR package yet — registration there is closed to new maintainers. The taken neighbours are fanctl/macfanctl/smctl. |
curl -fsSL https://github.com/yadav-prakhar/afanctl/releases/latest/download/install.sh | sudo bash
sudo systemctl enable --now afanctlThat fetches the package attached to the latest release, checks its SHA-256
against that release's SHA256SUMS, and installs it with pacman -U. Read it
before you pipe it — the script is install.sh in the repository root, and
... | bash -s -- --dry-run resolves, downloads and verifies without installing
(--version 0.1.0 pins a release).
Re-run the same command to upgrade; sudo pacman -R afanctl removes it.
cd packaging && makepkgThis builds the release binary (cargo build --release --locked) and stages
the package without touching the system. Artifacts (*.pkg.tar.zst) are
untracked build outputs.
cd packaging && makepkg -siWhat package() installs (see packaging/PKGBUILD):
| Path | Purpose | Mode |
|---|---|---|
/usr/bin/afanctl |
the binary | 755 |
/usr/lib/systemd/system/afanctl.service |
the systemd unit (systemd and Packaging) | 644 |
/etc/afanctl/afanctl.toml |
active config (from afanctl.toml.default on first install) |
644, pacman backup=-protected |
/usr/share/afanctl/afanctl.toml.default |
pristine default copy | 644 |
/usr/share/polkit-1/rules.d/49-afanctl.rules |
optional passwordless pkexec rule (wheel only) |
644 |
backup=('etc/afanctl/afanctl.toml') means pacman preserves your edits across
upgrades (kills the "missing≡0 / silently reset config" class).
The unit installs disabled, and its ExecStart is
/usr/bin/afanctl daemon --mode observe — so even after enabling, the daemon
writes nothing until you opt in:
sudo systemctl enable --now afanctl
systemctl status afanctl
afanctl status
sudo afanctl doctorExpected healthy state after install: mode: observe, fan1_manual = 0, fan
~1200 rpm on the SMC curve, doctor all PASS (see Diagnostics (doctor)).
After EVERY package reinstall, restart the unit and confirm the loaded build. A fresh install without a restart silently keeps testing the old binary — this cost one hardware round during the build.
sudo systemctl restart afanctl
sudo afanctl doctor # includes the stale-binary check: FAIL/WARN if
# the running daemon predates the installed binarydoctor's running daemon matches installed binary check detects "unit older
than the installed binary" (it compares daemon start time against the binary
mtime, with a /proc/<pid>/exe → /usr/bin/afanctl fallback). It does not
detect "package older than repo HEAD" — the restart discipline covers that gap.
- Re-run the install command (from a checkout:
cd packaging && makepkg -si). - Restart:
sudo systemctl restart afanctl. - Verify:
sudo afanctl doctor(all PASS),afanctl status(mode/config as expected). Your/etc/afanctl/afanctl.tomledits survive viabackup=. - If you edited the unit's
ReadWritePathsorExecStart --mode, re-apply withsudo systemctl daemon-reloadafter reinstall.
sudo afanctl curve # continuous curve control (writes cmd.json; daemon applies it)
sudo afanctl observe # release back to firmware (always safe)
sudo afanctl hold 3000 # fixed 3000 rpm (clamped to fan1_min..fan1_max)/run is tmpfs: after every reboot the machine is back on the SMC curve in
observe, regardless of what was commanded before. There is deliberately no
persisted mode across reboots (PRD §12).
sudo systemctl disable --now afanctl # stop + disable; startup reconcile already restored AUTO
sudo pacman -R afanctl # remove package; backup config handling per pacman policy
cat /sys/devices/platform/applesmc.768/fan1_manual # expect 0 (firmware owns the fan)-
afanctl --version→afanctl 0.1.0. -
afanctl -h→ usage text (see CLI Reference). -
afanctl status→ per-sensor temps,t_eff, mode, fan rpm/min/max, config provenance, recent errors. -
sudo afanctl doctor→ 10PASSlines, exit 0. Non-root run FAILs the write-mode checks by design (see Diagnostics (doctor) "Root required"). -
systemctl status afanctl→active (running),READY+ watchdog armed in the journal.
| Symptom | Cause / fix |
|---|---|
makepkg fails on missing rust
|
Install extra/rust (sudo pacman -S rust), verify cargo --version → 1.98.x. |
systemctl enable survives but fan still manual after reboot |
Reboot always lands in observe; if fan1_manual reads 1, a foreign supervisor (e.g. mbpfan) or a stale cmd.json re-applied curve — doctor's daemon-mode check names it. The daemon's startup reconcile unconditionally restores AUTO out of any Manual owner first. |
doctor WARN unit not installed
|
Expected until makepkg -si installs the unit; WARN never blocks (exit stays 0). |
doctor WARN running daemon predates the installed binary
|
You reinstalled without restarting — sudo systemctl restart afanctl. |
| Config error on first start | A present-but-broken /etc/afanctl/afanctl.toml refuses to start (never defaults silently). Every error names the key and the fix — see Configuration. |
- Home
- Installation
- CLI Reference
- Configuration
- Control Policy
- Supervisor and Run Modes
- Safety Model
- Hardware Interface
- Diagnostics (doctor)
- Plugin Surface (omafan)
- JSON Schemas
- systemd and Packaging
- Development and Testing
- Architecture and Internals
- Troubleshooting and FAQ
- Background and Verification
- afanctl-vs-mbpfan