359afb3a59
Infrastructure configs for GMKtec K11 (Docker, vLLM, LocalAI, ComfyUI, control-plane, gpu-fan agent, Server UI with CLI/file explorer/GPU fan curve). Co-authored-by: Cursor <cursoragent@cursor.com>
86 lines
2.6 KiB
Bash
Executable File
86 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Self-test: curve logic, NVML read, API (dry-run). Full fan write needs sudo.
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
STACK_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
cd "${STACK_DIR}"
|
|
|
|
mkdir -p config
|
|
cp -n curve.default.json config/curve.json 2>/dev/null || true
|
|
|
|
export CURVE_PATH="${STACK_DIR}/config/curve.json"
|
|
export DRY_RUN=true
|
|
export GPU_FAN_PORT=18090
|
|
|
|
echo "=== 1. Curve logic ==="
|
|
.venv/bin/python -c "
|
|
from fan_controller import parse_curve, interpolate_speed
|
|
pts = parse_curve({'30':50,'40':65,'50':80,'55':90,'60':100,'70':100})
|
|
assert interpolate_speed(45, pts) in (72, 73)
|
|
assert interpolate_speed(70, pts) == 100
|
|
print('OK')
|
|
"
|
|
|
|
echo "=== 2. NVML read ==="
|
|
.venv/bin/python -c "
|
|
import pynvml
|
|
pynvml.nvmlInit()
|
|
h = pynvml.nvmlDeviceGetHandleByIndex(0)
|
|
t = pynvml.nvmlDeviceGetTemperature(h, pynvml.NVML_TEMPERATURE_GPU)
|
|
print(f'GPU temp: {t}C')
|
|
pynvml.nvmlShutdown()
|
|
print('OK')
|
|
"
|
|
|
|
echo "=== 3. API dry-run (background) ==="
|
|
.venv/bin/python app.py &
|
|
APP_PID=$!
|
|
trap 'kill $APP_PID 2>/dev/null || true' EXIT
|
|
sleep 2
|
|
|
|
STATUS=$(curl -sf "http://127.0.0.1:${GPU_FAN_PORT}/api/status")
|
|
echo "$STATUS" | .venv/bin/python -m json.tool | head -20
|
|
|
|
TARGET=$(echo "$STATUS" | .venv/bin/python -c "import sys,json; print(json.load(sys.stdin)['target_speed_pct'])")
|
|
TEMP=$(echo "$STATUS" | .venv/bin/python -c "import sys,json; print(json.load(sys.stdin)['temperature_c'])")
|
|
echo "Temp=${TEMP}C target=${TARGET}%"
|
|
|
|
curl -sf -X PUT "http://127.0.0.1:${GPU_FAN_PORT}/api/curve" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"points":[{"temp":30,"speed":50},{"temp":40,"speed":65},{"temp":50,"speed":80},{"temp":55,"speed":90},{"temp":60,"speed":100},{"temp":70,"speed":100}]}' \
|
|
| .venv/bin/python -m json.tool >/dev/null
|
|
echo "Curve PUT: OK"
|
|
|
|
curl -sf -X POST "http://127.0.0.1:${GPU_FAN_PORT}/api/mode" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"mode":"manual","speed":100}' >/dev/null
|
|
echo "Mode manual 100%: OK"
|
|
|
|
kill $APP_PID 2>/dev/null || true
|
|
trap - EXIT
|
|
|
|
echo ""
|
|
if sudo -n true 2>/dev/null; then
|
|
echo "=== 4. Fan write (root) ==="
|
|
sudo -n env CURVE_PATH="$CURVE_PATH" .venv/bin/python -c "
|
|
from pathlib import Path
|
|
from fan_controller import FanController
|
|
c = FanController(Path('$CURVE_PATH'), 0, 2.0)
|
|
c.init_nvml()
|
|
c.set_mode('manual', 50)
|
|
m = c.update_once()
|
|
print(f\"Applied: {m['temperature_c']}C -> {m['target_speed_pct']}%\")
|
|
c.set_mode('auto')
|
|
c.update_once()
|
|
c.shutdown()
|
|
print('OK')
|
|
"
|
|
else
|
|
echo "=== 4. Fan write (root) — SKIP (sudo needs password) ==="
|
|
echo " Run: sudo scripts/install.sh && sudo systemctl start gpu-fan"
|
|
fi
|
|
|
|
echo ""
|
|
echo "All automated checks passed."
|