From 283e0ec6c8bd1f6a1f81b9b9ef4ce2a3d3b7b196 Mon Sep 17 00:00:00 2001 From: RNL Date: Fri, 6 Mar 2026 22:16:41 +1100 Subject: [PATCH] One command native setup --- README.md | 193 ++++++++++++++-------------- native/bambu-run-collector.service | 15 +++ native/bambu-run-web.service | 15 +++ native/bambu-run.sh | 58 +++++++++ setup.sh | 194 +++++++++++++++++++++++++++++ standalone/manage.py | 10 +- 6 files changed, 389 insertions(+), 96 deletions(-) create mode 100644 native/bambu-run-collector.service create mode 100644 native/bambu-run-web.service create mode 100755 native/bambu-run.sh create mode 100755 setup.sh diff --git a/README.md b/README.md index 4c0cf5a..bfc363f 100644 --- a/README.md +++ b/README.md @@ -22,151 +22,154 @@ It runs quietly in the background 24/7, capturing every print, filament change, ## Table of Contents -- [Quick Start: One-Click Docker Setup — Beginner Friendly](#quick-start-one-click-docker-setup--beginner-friendly) +- [Native Setup (Recommended for Raspberry Pi)](#native-setup-recommended-for-raspberry-pi) - [What You'll Need](#what-youll-need) - - [Step 1: Connect to Your Raspberry Pi](#step-1-connect-to-your-raspberry-pi) - - [Step 2: Install Docker](#step-2-install-docker) - - [Step 3: Download and Configure](#step-3-download-and-configure) - - [Step 4: Build the Container](#step-4-build-the-container) - - [Step 5: First-Time Authentication](#step-5-first-time-authentication) - - [Step 6: Start Bambu-Run and Create Your Login](#step-6-start-bambu-run-and-create-your-login) - - [Step 7: Open the Dashboard](#step-7-open-the-dashboard) - - [Troubleshooting](#troubleshooting) + - [Step 1: Clone and run setup.sh](#step-1-clone-and-run-setupsh) + - [Step 2: Credentials and .env](#step-2-credentials-and-env) + - [Step 3: Bambu Cloud authentication](#step-3-bambu-cloud-authentication) + - [Step 4: Dashboard login](#step-4-dashboard-login) + - [Step 5: Services start automatically](#step-5-services-start-automatically) + - [Managing Bambu-Run](#managing-bambu-run) + - [Troubleshooting (Native)](#troubleshooting-native) +- [Docker Setup](#docker-setup) - [Batch Importing Filament Colors and Filament Types](#batch-importing-filament-colors-and-filament-types) --- -## Quick Start: One-Click Docker Setup — Beginner Friendly +## Native Setup (Recommended for Raspberry Pi) -Get Bambu-Run running on a **Raspberry Pi** in minutes. No prior server experience needed. +No Docker required. Works on any Raspberry Pi (including 32-bit Pi Model B) running Raspberry Pi OS with Python 3.10+. ### What You'll Need -- A Raspberry Pi (3B+, 4, or 5) running Raspberry Pi OS 64-bit, with a 32 GB+ MicroSD card, connected to your network -- Your Bambu Lab printer on the **same local network** -- Your Bambu Lab account **email and password** -- A computer to SSH into the Pi +- Raspberry Pi on your local network (Python 3.10+ — ships with Raspberry Pi OS Bookworm by default) +- Bambu Lab printer on the **same local network** +- Bambu Lab account **email and password** -### Step 1: Connect to Your Raspberry Pi - -From your computer, open a terminal (Mac/Linux) or PowerShell (Windows): +### Step 1: Clone and run setup.sh ```bash -ssh pi@raspberrypi.local +git clone https://github.com/RunLit/Bambu-Run.git +cd Bambu-Run +bash setup.sh ``` -> Can't connect? Use your Pi's IP address (find it in your router's admin page). Default password: `raspberry` +The script is fully interactive and idempotent (safe to re-run). It: -### Step 2: Install Docker +1. Checks Python >= 3.10 and installs `python3-venv` if missing +2. Creates `.venv`, stubs opencv to avoid slow ARM compilation, and runs `pip install ".[standalone]"` +3. Prompts for credentials and auto-generates `DJANGO_SECRET_KEY` — writes `.env` +4. Runs `manage.py migrate` +5. Runs `bambu_collector --once` for Bambu Cloud email verification (see Step 3) +6. Runs `manage.py createsuperuser` for your dashboard login +7. Runs `collectstatic` +8. Optionally imports the bundled Bambu filament color catalog +9. Writes and enables `systemd` user services, calls `loginctl enable-linger` so they survive SSH disconnect, and starts them + +### Step 2: Credentials and .env + +If `.env` doesn't exist, the script prompts for: + +| Variable | Description | +|---|---| +| `BAMBU_USERNAME` | Bambu Lab account email | +| `BAMBU_PASSWORD` | Bambu Lab account password | +| `TIMEZONE` | e.g. `America/New_York` (default: `UTC`) | + +`DJANGO_SECRET_KEY` is auto-generated. To edit later: `nano .env`, then `./native/bambu-run.sh restart`. + +### Step 3: Bambu Cloud authentication + +Bambu Lab requires email verification on first login: + +1. The script runs `bambu_collector --once` — a 6-digit code is sent to your email +2. Enter the code when prompted +3. A `BAMBU_TOKEN` is printed — paste it when the script asks, and it's appended to `.env` + +Future restarts skip verification automatically. To re-authenticate, remove `BAMBU_TOKEN` from `.env` and re-run the script. + +### Step 4: Dashboard login + +The script runs `manage.py createsuperuser` — choose a username and password for the web dashboard. + +### Step 5: Services start automatically + +Two systemd user services are installed and started: + +| Service | Role | +|---|---| +| `bambu-run-web` | gunicorn on port 8000 (1 worker <1 GB RAM, 2 workers otherwise) | +| `bambu-run-collector` | MQTT poller, restarts on failure | + +Both auto-start on boot via `loginctl enable-linger`. Open `http://:8000` from any device on your network. + +### Managing Bambu-Run ```bash -curl -fsSL https://get.docker.com | sudo sh -sudo usermod -aG docker $USER +./native/bambu-run.sh status # service status +./native/bambu-run.sh logs # tail live logs (Ctrl+C to stop) +./native/bambu-run.sh restart # restart both services +./native/bambu-run.sh stop # stop everything +./native/bambu-run.sh update # git pull + pip install + migrate + restart ``` -Log out and back in for the change to take effect, then verify: +### Troubleshooting (Native) +**Services die when SSH disconnects:** `sudo loginctl enable-linger $USER` + +**Services not starting:** `./native/bambu-run.sh status` and `./native/bambu-run.sh logs` + +**Auth errors / token expired:** Remove `BAMBU_TOKEN` from `.env` and re-run `bash setup.sh` + +**Uninstall:** ```bash -exit +systemctl --user disable --now bambu-run-web bambu-run-collector +rm ~/.config/systemd/user/bambu-run-{web,collector}.service +systemctl --user daemon-reload ``` -```bash -ssh pi@raspberrypi.local -docker --version # should show Docker version 27.x.x -``` +--- -> Installation issues? See: https://docs.docker.com/engine/install/raspberry-pi-os/ +## Docker Setup -### Step 3: Download and Configure +Requires Docker and Docker Compose installed. Assumes you already know how to get there. + +**Clone and configure:** ```bash git clone https://github.com/RunLit/Bambu-Run.git cd Bambu-Run cp .env.example .env -nano .env +# Edit .env: set BAMBU_USERNAME, BAMBU_PASSWORD, TIMEZONE ``` -Fill in your Bambu Lab credentials: - -``` -BAMBU_USERNAME=your_email@example.com -BAMBU_PASSWORD=your_password -TIMEZONE=Australia/Melbourne # optional — find yours at https://en.wikipedia.org/wiki/List_of_tz_database_time_zones -``` - -Save: `Ctrl + X`, `Y`, `Enter` - -### Step 4: Build the Container +**First-time auth** (Bambu Lab sends a 6-digit verification code to your email): ```bash docker compose build -``` - -This takes a few minutes the first time — it downloads all required software. - -### Step 5: First-Time Authentication - -Bambu Lab requires email verification on first login. Run these two commands: - -```bash docker compose run --rm bambu-run python standalone/manage.py migrate --noinput docker compose run --rm bambu-run python standalone/manage.py bambu_collector --once +# Paste the printed token into .env as BAMBU_TOKEN=... ``` -When prompted, enter the 6-digit code sent to your email. On success you'll see a token printed — copy it and add it to your `.env`: - -```bash -nano .env -``` - -``` -BAMBU_TOKEN=eyJhbGciOiJIUzI1N...paste_full_token_here -``` - -> Saving the token lets future restarts skip re-verification automatically. - -### Step 6: Start Bambu-Run and Create Your Login +**Start and create your dashboard login:** ```bash docker compose up -d docker compose exec bambu-run python standalone/manage.py createsuperuser ``` -Choose a username and password — this is your dashboard login. +Dashboard is at `http://:8000`. -### Step 7: Open the Dashboard +**Common operations:** -On any device on your network, open a browser and go to: - -``` -http://raspberrypi.local:8000 -``` - -> If that doesn't work, use your Pi's IP: `http://:8000` - -Log in with the account you just created. Your printer dashboard should be live. - -### Troubleshooting - -**No data / cannot connect to printer:** Make sure the printer is on and on the same network. Check logs: `docker compose logs -f`. If you see auth errors, re-run Step 5 to get a fresh token. - -**401 Unauthorized / verification loop:** Remove `BAMBU_TOKEN` from `.env` and re-run Step 5. - -**Docker daemon error:** Log out and back in after Step 2 — the group change requires a new session. - -**Dashboard not loading:** Run `docker compose ps` to confirm the service is `Up`, then try the Pi's IP address directly. - -**Update Bambu-Run:** ```bash -cd ~/Bambu-Run && git pull && docker compose up -d --build +docker compose logs -f # live logs +docker compose down # stop (data preserved in volume) +git pull && docker compose up -d --build # update ``` -**Stop Bambu-Run:** -```bash -docker compose down -``` - -Your data is preserved in a Docker volume and will be there when you start it again. +**Troubleshooting:** Auth errors → remove `BAMBU_TOKEN` from `.env` and re-run the auth step. No data → check `docker compose logs -f` for MQTT connection errors. --- diff --git a/native/bambu-run-collector.service b/native/bambu-run-collector.service new file mode 100644 index 0000000..2049b8d --- /dev/null +++ b/native/bambu-run-collector.service @@ -0,0 +1,15 @@ +[Unit] +Description=Bambu-Run MQTT Collector +After=network.target + +[Service] +Type=exec +WorkingDirectory={{REPO_DIR}} +EnvironmentFile={{REPO_DIR}}/.env +Environment=DJANGO_SETTINGS_MODULE=standalone.settings +ExecStart={{VENV_DIR}}/bin/python standalone/manage.py bambu_collector +Restart=on-failure +RestartSec=10 + +[Install] +WantedBy=default.target diff --git a/native/bambu-run-web.service b/native/bambu-run-web.service new file mode 100644 index 0000000..ef46637 --- /dev/null +++ b/native/bambu-run-web.service @@ -0,0 +1,15 @@ +[Unit] +Description=Bambu-Run Web Dashboard +After=network.target + +[Service] +Type=exec +WorkingDirectory={{REPO_DIR}} +EnvironmentFile={{REPO_DIR}}/.env +Environment=DJANGO_SETTINGS_MODULE=standalone.settings +ExecStart={{VENV_DIR}}/bin/gunicorn standalone.wsgi:application --bind 0.0.0.0:8000 --workers {{WORKERS}} --timeout 120 +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=default.target diff --git a/native/bambu-run.sh b/native/bambu-run.sh new file mode 100755 index 0000000..9541c00 --- /dev/null +++ b/native/bambu-run.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +# Bambu-Run convenience wrapper +# Usage: ./native/bambu-run.sh {start|stop|restart|status|logs|update} +set -euo pipefail + +REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)" +VENV_DIR="$REPO_DIR/.venv" +MANAGE="$VENV_DIR/bin/python $REPO_DIR/standalone/manage.py" +SERVICES="bambu-run-web.service bambu-run-collector.service" + +case "${1:-help}" in + start) + systemctl --user start $SERVICES + echo "Bambu-Run started." + ;; + stop) + systemctl --user stop $SERVICES + echo "Bambu-Run stopped." + ;; + restart) + systemctl --user restart $SERVICES + echo "Bambu-Run restarted." + ;; + status) + systemctl --user status $SERVICES --no-pager + ;; + logs) + journalctl --user -u bambu-run-web -u bambu-run-collector -f --no-hostname + ;; + update) + echo "Pulling latest code..." + cd "$REPO_DIR" && git pull + + echo "Installing dependencies..." + "$VENV_DIR/bin/pip" install --quiet ".[standalone]" + + echo "Running migrations..." + $MANAGE migrate --noinput + + echo "Collecting static files..." + $MANAGE collectstatic --noinput --clear 2>/dev/null + + echo "Restarting services..." + systemctl --user restart $SERVICES + + echo "Update complete." + ;; + help|*) + echo "Usage: $0 {start|stop|restart|status|logs|update}" + echo + echo " start Start web + collector services" + echo " stop Stop web + collector services" + echo " restart Restart web + collector services" + echo " status Show service status" + echo " logs Tail live logs (Ctrl+C to stop)" + echo " update Pull latest code, install deps, migrate, restart" + ;; +esac diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..edf93e3 --- /dev/null +++ b/setup.sh @@ -0,0 +1,194 @@ +#!/usr/bin/env bash +# Bambu-Run Native Setup — single entry point for Raspberry Pi (or any Linux) +# Usage: git clone ... && cd Bambu-Run && bash setup.sh +set -euo pipefail + +REPO_DIR="$(cd "$(dirname "$0")" && pwd)" +VENV_DIR="$REPO_DIR/.venv" +ENV_FILE="$REPO_DIR/.env" +MANAGE="$VENV_DIR/bin/python $REPO_DIR/standalone/manage.py" +SERVICE_DIR="$HOME/.config/systemd/user" + +green() { printf '\033[1;32m%s\033[0m\n' "$*"; } +yellow() { printf '\033[1;33m%s\033[0m\n' "$*"; } +red() { printf '\033[1;31m%s\033[0m\n' "$*"; } + +# ── 1. Pre-flight checks ───────────────────────────────────────────────────── + +green "=== Bambu-Run Native Setup ===" +echo + +# Python >= 3.10 +PYTHON="" +for cmd in python3.12 python3.11 python3.10 python3; do + if command -v "$cmd" &>/dev/null; then + ver=$("$cmd" -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') + major=${ver%%.*} + minor=${ver##*.} + if [ "$major" -ge 3 ] && [ "$minor" -ge 10 ]; then + PYTHON="$cmd" + break + fi + fi +done + +if [ -z "$PYTHON" ]; then + red "Error: Python >= 3.10 is required." + echo "Install it with: sudo apt install python3" + exit 1 +fi +green "Found $PYTHON ($ver)" + +# Ensure python3-venv is available +if ! "$PYTHON" -m venv --help &>/dev/null; then + yellow "Installing python3-venv..." + sudo apt-get update -qq && sudo apt-get install -y -qq python3-venv +fi + +# Detect RAM for gunicorn worker count +TOTAL_RAM_KB=$(grep MemTotal /proc/meminfo 2>/dev/null | awk '{print $2}' || echo 0) +if [ "$TOTAL_RAM_KB" -lt 1048576 ]; then + WORKERS=1 +else + WORKERS=2 +fi + +# ── 2. Venv + install ──────────────────────────────────────────────────────── + +if [ ! -d "$VENV_DIR" ]; then + green "Creating virtual environment..." + "$PYTHON" -m venv "$VENV_DIR" +else + yellow "Virtual environment already exists, reusing." +fi + +green "Installing dependencies..." + +# Stub opencv-python (same trick as Dockerfile — avoids hour-long ARM build) +"$VENV_DIR/bin/python" -c " +import site, pathlib +d = pathlib.Path(site.getsitepackages()[0]) / 'opencv_python-4.99.0.dist-info' +if not d.exists(): + d.mkdir() + (d / 'METADATA').write_text('Metadata-Version: 2.1\nName: opencv-python\nVersion: 4.99.0\n') + (d / 'INSTALLER').write_text('pip\n') + (d / 'RECORD').write_text('') + print(' opencv stub created') +else: + print(' opencv stub already exists') +" + +"$VENV_DIR/bin/pip" install --quiet --upgrade pip +"$VENV_DIR/bin/pip" install --quiet ".[standalone]" + +# ── 3. Interactive .env ─────────────────────────────────────────────────────── + +if [ ! -f "$ENV_FILE" ]; then + green "Setting up .env configuration..." + echo + + read -rp "Bambu Lab email: " BAMBU_USERNAME + read -rsp "Bambu Lab password: " BAMBU_PASSWORD + echo + read -rp "Timezone [UTC] (e.g. America/New_York): " TIMEZONE + TIMEZONE="${TIMEZONE:-UTC}" + + # Generate a random Django secret key + DJANGO_SECRET_KEY=$("$VENV_DIR/bin/python" -c "import secrets; print(secrets.token_urlsafe(50))") + + cat > "$ENV_FILE" <