mirror of
https://github.com/RunLit/Bambu-Run.git
synced 2026-06-22 22:19:03 +01:00
fixed chart missing whitenoise and not rendering
This commit is contained in:
@@ -5,6 +5,11 @@
|
|||||||
height: 300px;
|
height: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-data-message {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
/* Card styling */
|
/* Card styling */
|
||||||
.infra-card-warning {
|
.infra-card-warning {
|
||||||
background: linear-gradient(135deg, #ffc107 0%, #ffb300 100%);
|
background: linear-gradient(135deg, #ffc107 0%, #ffb300 100%);
|
||||||
|
|||||||
@@ -4,10 +4,30 @@
|
|||||||
let nozzleTempChart, bedTempChart, printProgressChart, fanSpeedsChart;
|
let nozzleTempChart, bedTempChart, printProgressChart, fanSpeedsChart;
|
||||||
let wifiSignalChart, amsConditionsChart, layerProgressChart, filamentTimelineChart;
|
let wifiSignalChart, amsConditionsChart, layerProgressChart, filamentTimelineChart;
|
||||||
|
|
||||||
|
function showNoDataMessage(canvasId) {
|
||||||
|
const canvas = document.getElementById(canvasId);
|
||||||
|
if (!canvas) return;
|
||||||
|
const container = canvas.closest('.chart-container');
|
||||||
|
if (!container) return;
|
||||||
|
canvas.style.display = 'none';
|
||||||
|
const msg = document.createElement('div');
|
||||||
|
msg.className = 'no-data-message d-flex align-items-center justify-content-center h-100 text-body-secondary';
|
||||||
|
msg.textContent = 'No data available for this period';
|
||||||
|
container.appendChild(msg);
|
||||||
|
}
|
||||||
|
|
||||||
function initPrinterCharts(printerData, apiUrl) {
|
function initPrinterCharts(printerData, apiUrl) {
|
||||||
// Apply filament card colors
|
// Apply filament card colors
|
||||||
applyFilamentColors();
|
applyFilamentColors();
|
||||||
|
|
||||||
|
// If no data, show placeholder messages and exit early
|
||||||
|
if (!printerData.timestamps || printerData.timestamps.length === 0) {
|
||||||
|
['nozzleTempChart', 'bedTempChart', 'printProgressChart', 'fanSpeedsChart',
|
||||||
|
'wifiSignalChart', 'amsConditionsChart', 'layerProgressChart', 'filamentTimelineChart'
|
||||||
|
].forEach(showNoDataMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Register the annotation plugin
|
// Register the annotation plugin
|
||||||
if (typeof Chart !== 'undefined' && typeof ChartAnnotation !== 'undefined') {
|
if (typeof Chart !== 'undefined' && typeof ChartAnnotation !== 'undefined') {
|
||||||
Chart.register(ChartAnnotation);
|
Chart.register(ChartAnnotation);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% load static %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" data-coreui-theme="dark">
|
<html lang="en" data-coreui-theme="dark">
|
||||||
<head>
|
<head>
|
||||||
@@ -45,7 +46,7 @@
|
|||||||
<ul class="sidebar-nav" data-coreui="navigation">
|
<ul class="sidebar-nav" data-coreui="navigation">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{% url 'bambu_run:printer_dashboard' %}">
|
<a class="nav-link" href="{% url 'bambu_run:printer_dashboard' %}">
|
||||||
<svg class="nav-icon"><use xlink:href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/sprites/free.svg#cil-expand-down"></use></svg>
|
<svg class="nav-icon"><use href="{% static 'bambu_run/vendors/coreui-icons-free.svg' %}#cil-expand-down"></use></svg>
|
||||||
3D Printer
|
3D Printer
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@@ -66,12 +67,12 @@
|
|||||||
<div class="container-fluid px-4">
|
<div class="container-fluid px-4">
|
||||||
<button class="header-toggler d-lg-none" type="button"
|
<button class="header-toggler d-lg-none" type="button"
|
||||||
onclick="coreui.Sidebar.getInstance(document.querySelector('#sidebar')).toggle()">
|
onclick="coreui.Sidebar.getInstance(document.querySelector('#sidebar')).toggle()">
|
||||||
<svg class="icon icon-lg"><use xlink:href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/sprites/free.svg#cil-menu"></use></svg>
|
<svg class="icon icon-lg"><use href="{% static 'bambu_run/vendors/coreui-icons-free.svg' %}#cil-menu"></use></svg>
|
||||||
</button>
|
</button>
|
||||||
<ul class="header-nav ms-auto">
|
<ul class="header-nav ms-auto">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<button class="nav-link" id="themeToggle" type="button">
|
<button class="nav-link" id="themeToggle" type="button">
|
||||||
<svg class="icon icon-lg"><use xlink:href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/sprites/free.svg#cil-moon"></use></svg>
|
<svg class="icon icon-lg"><use href="{% static 'bambu_run/vendors/coreui-icons-free.svg' %}#cil-moon"></use></svg>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
|
|||||||
@@ -158,7 +158,7 @@
|
|||||||
<h6 class="mb-0">Tray {{ filament.tray_id }}</h6>
|
<h6 class="mb-0">Tray {{ filament.tray_id }}</h6>
|
||||||
{% if filament.filament_pk %}
|
{% if filament.filament_pk %}
|
||||||
<a href="{% url 'bambu_run:filament_detail' filament.filament_pk %}" class="text-decoration-none" title="View in inventory">
|
<a href="{% url 'bambu_run:filament_detail' filament.filament_pk %}" class="text-decoration-none" title="View in inventory">
|
||||||
<svg class="icon icon-sm text-body-secondary"><use xlink:href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/sprites/free.svg#cil-external-link"></use></svg>
|
<svg class="icon icon-sm text-body-secondary"><use href="{% static 'bambu_run/vendors/coreui-icons-free.svg' %}#cil-external-link"></use></svg>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
@@ -235,11 +235,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- Buttons -->
|
<!-- Buttons -->
|
||||||
<button type="button" class="btn btn-primary btn-sm" id="refreshPrinterCharts">
|
<button type="button" class="btn btn-primary btn-sm" id="refreshPrinterCharts">
|
||||||
<svg class="icon"><use xlink:href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/sprites/free.svg#cil-reload"></use></svg>
|
<svg class="icon"><use href="{% static 'bambu_run/vendors/coreui-icons-free.svg' %}#cil-reload"></use></svg>
|
||||||
Refresh
|
Refresh
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-secondary btn-sm" id="resetPrinterCharts">
|
<button type="button" class="btn btn-secondary btn-sm" id="resetPrinterCharts">
|
||||||
<svg class="icon"><use xlink:href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/sprites/free.svg#cil-action-undo"></use></svg>
|
<svg class="icon"><use href="{% static 'bambu_run/vendors/coreui-icons-free.svg' %}#cil-action-undo"></use></svg>
|
||||||
Reset
|
Reset
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
75
docs/LOCAL_DEBUG_INSTRUCTIONS.md
Normal file
75
docs/LOCAL_DEBUG_INSTRUCTIONS.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# Setup Local Environment for Debug
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Docker Desktop running on macOS
|
||||||
|
- Your Bambu Lab account email + password
|
||||||
|
- Bambu-Run source at /Users/runnanli/src/Bambu-Run
|
||||||
|
|
||||||
|
---
|
||||||
|
### Step 1 — Create .env
|
||||||
|
|
||||||
|
Create /Users/runnanli/src/Bambu-Run/.env:
|
||||||
|
BAMBU_USERNAME=your_bambulab_email@example.com
|
||||||
|
BAMBU_PASSWORD=your_bambulab_password
|
||||||
|
TIMEZONE=Australia/Melbourne
|
||||||
|
No DB vars needed — SQLite is the default when DB_NAME is absent.
|
||||||
|
|
||||||
|
---
|
||||||
|
### Step 2 — Build the image
|
||||||
|
|
||||||
|
cd /Users/runnanli/src/Bambu-Run
|
||||||
|
docker compose build
|
||||||
|
Takes a few minutes first time.
|
||||||
|
|
||||||
|
---
|
||||||
|
### Step 3 — Run database migrations
|
||||||
|
|
||||||
|
docker compose run --rm bambu-run python standalone/manage.py migrate --noinput
|
||||||
|
|
||||||
|
---
|
||||||
|
### Step 4 — First-time Bambu Lab authentication (email verification)
|
||||||
|
|
||||||
|
docker compose run --rm bambu-run python standalone/manage.py bambu_collector --once
|
||||||
|
|
||||||
|
You'll be prompted for a 6-digit code sent to your email. Enter it.
|
||||||
|
On success the token is printed:
|
||||||
|
Token: eyJhbGci...
|
||||||
|
|
||||||
|
Add it to .env:
|
||||||
|
BAMBU_TOKEN=eyJhbGci...paste_full_token_here
|
||||||
|
Future restarts will skip email verification.
|
||||||
|
|
||||||
|
---
|
||||||
|
### Step 5 — Start everything
|
||||||
|
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
Supervisord starts three processes: migrate (idempotent), web (gunicorn on :8000), collector (polls printer continuously).
|
||||||
|
|
||||||
|
---
|
||||||
|
### Step 6 — Create a login account
|
||||||
|
|
||||||
|
docker compose exec bambu-run python standalone/manage.py createsuperuser
|
||||||
|
|
||||||
|
---
|
||||||
|
### Step 7 — Open the dashboard
|
||||||
|
|
||||||
|
http://localhost:8000
|
||||||
|
|
||||||
|
---
|
||||||
|
### Useful commands
|
||||||
|
|
||||||
|
#### Watch live logs
|
||||||
|
docker compose logs -f
|
||||||
|
|
||||||
|
#### Stop
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
#### Rebuild after code changes
|
||||||
|
docker compose up -d --build
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
|
||||||
|
- SQLite lives inside Docker volume bambu_data — persists across restarts
|
||||||
|
- If charts are blank: printer must be on; give collector ~1 minute to start polling
|
||||||
@@ -38,6 +38,7 @@ dependencies = [
|
|||||||
standalone = [
|
standalone = [
|
||||||
"gunicorn",
|
"gunicorn",
|
||||||
"python-dotenv",
|
"python-dotenv",
|
||||||
|
"whitenoise",
|
||||||
]
|
]
|
||||||
dev = [
|
dev = [
|
||||||
"ruff",
|
"ruff",
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ INSTALLED_APPS = [
|
|||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
|
"whitenoise.middleware.WhiteNoiseMiddleware",
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
"django.middleware.common.CommonMiddleware",
|
"django.middleware.common.CommonMiddleware",
|
||||||
"django.middleware.csrf.CsrfViewMiddleware",
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
@@ -90,6 +91,7 @@ USE_TZ = True
|
|||||||
# Static files
|
# Static files
|
||||||
STATIC_URL = "static/"
|
STATIC_URL = "static/"
|
||||||
STATIC_ROOT = BASE_DIR / "staticfiles"
|
STATIC_ROOT = BASE_DIR / "staticfiles"
|
||||||
|
STATICFILES_STORAGE = "whitenoise.storage.CompressedStaticFilesStorage"
|
||||||
|
|
||||||
# Default primary key field type
|
# Default primary key field type
|
||||||
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
||||||
|
|||||||
Reference in New Issue
Block a user