Turn a 3D printer into a 2D plotter / drawing robot using OctoPrint, Sacred experiment tracking, MongoDB (GridFS), and a Dash web UI.
- Generate paths from built‑in Python examples or uploaded Python code stored in MongoDB
- Convert paths to G-code with frame drawing & safety moves
- Toggle between path preview and generated G-code preview
- Printer bed size auto-sync (button fetches OctoPrint profile → updates
formats.jsonmaxentry) - Upload & persist both G-code and Python files directly into MongoDB (no local FS dependency)
- Create Sacred experiments only when G-code + matching timelapse pairs exist (duplicate experiments skipped)
- Thumbnails (plot_image.png) + MP4 timelapse streaming with HTTP Range support (fast seek)
- Fallback artifact/image retrieval from raw Mongo/GridFS when Incense loader unavailable
- Recent experiments & DB stats panel
- Dynamic line thickness control via env var
PLOT_PATH_LINE_WIDTH(thinner default lines) - Frame & path scaling / auto orientation inside selected format constraints
| Layer | Tools |
|---|---|
| UI | Dash, Plotly, Dash Bootstrap Components |
| Backend / App | Flask (inside Dash), Python 3.10+ |
| Data / Experiments | MongoDB + GridFS + Sacred + (Incense loader when present) |
| G-code / Path | Custom utilities (utils.py), optional TextToGcode (ttgLib) |
| Printer Control | OctoPrint REST API |
- Python 3.10+ (3.8+ may work, project currently uses 3.10 semantics)
- OctoPrint instance reachable (local Docker or Raspberry Pi)
- MongoDB (local Docker compose provided)
- (Optional) Incense for Sacred experiment artifact access (already included via git dependency in
requirements.txt) - (Optional) TextToGcode / DrawingBot style assets for text/frame labeling
Install via:
pip install -r requirements.txtrequirements.txt already includes: dash, sacred, pymongo, numpy, matplotlib, dash-bootstrap-components, TextToGcode, tqdm, dotenv, kaleido, incense (git). No need to manually list them.
Create a .env file at project root (same dir as octoprint_dash_refactored.py). Example:
OCTOPRINT_URL=http://localhost:5055
OCTOPRINT_API_KEY=REPLACE_WITH_KEY
MONGO_URI=mongodb://admin:PASSWORD@localhost:27020/octoplot_data?authSource=admin
# Backward compatibility (either works):
MONOGO_URI=mongodb://admin:PASSWORD@localhost:27020/octoplot_data?authSource=admin
DEBUG=True
Notes:
- Both
MONGO_URIand the (typo)MONOGO_URIare accepted for resilience. - Set
PLOT_PATH_LINE_WIDTH=0.6(or another float) to globally thin plot strokes. - If using SSH tunnels: forward ports (see below) before launching.
- Ensure OctoPrint running somewhere (Docker or Pi). Obtain API Key (Settings → API).
- Start MongoDB via compose (see next section) OR use an existing instance.
- Populate
.env. - (Optional) Create virtual environment:
python -m venv .venv # Linux/macOS source .venv/bin/activate # Windows PowerShell .\.venv\Scripts\Activate.ps1
- Install deps:
pip install -r requirements.txt - Launch app:
python octoprint_dash_refactored.py
- Open browser: http://localhost:8050
- Use Drawing page: select / upload code, generate path, toggle preview, create experiment.
Runs MongoDB for Sacred + (if configured) an Omniboard-like dashboard.
docker-compose -f docker-compose.mongo-omniboard.yml up -dCleanup / reset (e.g., to change admin password):
docker-compose -f docker-compose.mongo-omniboard.yml down
docker volume rm octoplot_mongo_data
docker-compose -f docker-compose.mongo-omniboard.yml up -d --remove-orphansConnectivity test (adjust password):
mongosh "mongodb://admin:PASSWORD@localhost:27020/octoplot_data?authSource=admin"docker-compose -f docker-compose.octoprint.yml up -dThen visit http://localhost:5055 for initial wizard: set bed size, camera, API key.
If running remotely:
ssh -L 8055:localhost:8050 -L 5055:localhost:5000 user@REMOTE_HOSTThen open local http://localhost:8055 for the Dash UI (if app bound to 8050 on remote) and http://localhost:5055 for OctoPrint.
- Choose a sample from
test_codes/or upload Python file → it’s stored in Mongo and appended to dropdown. - Execute: backend evaluates and stores X, Y, Z arrays in PlotData JSON.
- Button toggles between: Path (thin lines, hidden axes) and G-code (with printer frame if enabled).
- Use Find File Matches → marks which G-code/timelapse pairs are READY.
- Create experiment only allowed for new, complete pairs to avoid duplicates.
- Artifacts stored: plot_image.png (thumbnail), timelapse.mp4 (streamable via Range).
- Thumbnails served from
/image/png/<experiment_id>. - If Incense loader fails, raw Mongo fallback path streams stored PNG.
- Clicking video icon fetches
/video/mp4/<experiment_id>with partial content (seekable).
- Button calls OctoPrint profiles API → updates
formats.jsonmaxformat. Path scaling uses that boundary.
- Python scripts & G-code uploaded via UI stored in
uploaded_filescollection (GridFS or BSON document depending on size). - Listed after built-in examples in dropdowns.
Set before launch (example PowerShell):
$env:PLOT_PATH_LINE_WIDTH = '0.5'
python octoprint_dash_refactored.pyformats.json defines named printable areas (e.g., A4, postcard, max). Path ingestion auto-rotates/orients to maximize scale (transpose check) and applies margin.
To add a new format manually:
{
"A4": {"x_min":5, "x_max":205, "y_min":5, "y_max":292},
"custom": {"x_min":10, "x_max":180, "y_min":10, "y_max":250},
"max": {"x_min":0, "x_max":220, "y_min":0, "y_max":300}
}| Task | Command / Action |
|---|---|
| Start Mongo stack | docker-compose -f docker-compose.mongo-omniboard.yml up -d |
| Reset Mongo (wipe) | See cleanup commands above |
| Start OctoPrint | docker-compose -f docker-compose.octoprint.yml up -d |
| Launch app | python octoprint_dash_refactored.py |
| Change line width | Set PLOT_PATH_LINE_WIDTH env var |
| Test DB connectivity | mongosh connection string |
| Update bed size | Click “Load Bed Size” button in UI |
| Remove duplicate experiments | Automatically skipped (no manual action) |
| Symptom | Cause | Fix |
|---|---|---|
| “No loader” on image route | Incense not available / loader failure | Fallback now active; ensure image stored; reinstall incense if needed |
| Empty gallery thumbnail | Missing plot_image.png artifact |
Re-run experiment creation or inspect GridFS entry |
| Cannot connect OctoPrint | Wrong URL/API key | Verify .env OCTOPRINT_URL & key, test via curl/Postman |
| Experiments not created | Missing matching timelapse | Ensure mp4 + gcode filenames align per matching rules |
| Thick lines | Env var not set | Set PLOT_PATH_LINE_WIDTH and restart |
| Mongo auth failure | Wrong credentials / wiped volume | Reset password or recreate volume (cleanup section) |
Logs: run app in a terminal; enable DEBUG=True in .env for verbose output.
- Path simplification (Douglas–Peucker) toggle
- Live line-width slider in UI
- Webcam embedding from OctoPrint stream
- Per-experiment deletion & artifact regeneration
- Advanced pen pressure / multi-color management
- Raspi-friendly lightweight distribution image
SSH key (first-time Git):
ssh-keygen -t ed25519 -C "your_email@example.com"
cat ~/.ssh/id_ed25519.pub # add to GitHub SSH keysBranch workflow (example):
git clone <repo>
git checkout virtualpython -m venv .venv
source .venv/bin/activate # Linux/macOS
.# Windows PowerShell
.# .\.venv\Scripts\Activate.ps1
pip install -r requirements.txtSee LICENSE file.
- Older script
octoprint_dash.pyreplaced byoctoprint_dash_refactored.py. - Format management moved from Settings tab directly into Drawing page flows.
plotly_get_chrome(environment-specific headless export issues) – consider using Kaleido (already in requirements) fully for static image export.
docker run hello-world
docker-compose -f docker-compose.octoprint.yml up -d
docker-compose -f docker-compose.mongo-omniboard.yml down
docker volume rm octoplot_mongo_data
docker-compose -f docker-compose.mongo-omniboard.yml up -d --remove-orphans




