From 34ef5d697360cde968492d0a3e7f6dce66f2b8fc Mon Sep 17 00:00:00 2001 From: RNL Date: Sun, 29 Mar 2026 23:08:31 +1100 Subject: [PATCH] back fill and relink print name using cloud if there is --- .../management/commands/bambu_sync_cloud.py | 4 +- bambu_run/models.py | 7 +++ .../templates/bambu_run/filament_detail.html | 2 +- .../bambu_run/printer_dashboard.html | 2 +- bambu_run/views.py | 48 +++++++++++++++++-- 5 files changed, 54 insertions(+), 9 deletions(-) diff --git a/bambu_run/management/commands/bambu_sync_cloud.py b/bambu_run/management/commands/bambu_sync_cloud.py index a8186f8..738da6b 100644 --- a/bambu_run/management/commands/bambu_sync_cloud.py +++ b/bambu_run/management/commands/bambu_sync_cloud.py @@ -112,8 +112,8 @@ class Command(BaseCommand): serial_number=cloud_task.device_serial ).first() if printer: - window_start = cloud_task.cloud_start_time - timedelta(minutes=2) - window_end = cloud_task.cloud_start_time + timedelta(minutes=2) + window_start = cloud_task.cloud_start_time - timedelta(minutes=5) + window_end = cloud_task.cloud_start_time + timedelta(minutes=5) historical = PrintJob.objects.filter( device=printer, start_time__gte=window_start, diff --git a/bambu_run/models.py b/bambu_run/models.py index 9cf763d..e6d8f26 100644 --- a/bambu_run/models.py +++ b/bambu_run/models.py @@ -595,6 +595,13 @@ class PrintJob(models.Model): status = self.final_status or 'In Progress' return f"{self.project_name} ({status}) - {self.start_time.strftime('%Y-%m-%d %H:%M')}" + @property + def display_name(self): + """Human-readable job name: cloud design_title if available, else project_name.""" + if self.cloud_task_id and self.cloud_task and self.cloud_task.design_title: + return self.cloud_task.design_title + return self.project_name + def calculate_duration(self): """Calculate print duration if end_time is set""" if self.end_time and self.start_time: diff --git a/bambu_run/templates/bambu_run/filament_detail.html b/bambu_run/templates/bambu_run/filament_detail.html index aba3c62..b0a0679 100644 --- a/bambu_run/templates/bambu_run/filament_detail.html +++ b/bambu_run/templates/bambu_run/filament_detail.html @@ -154,7 +154,7 @@ {% for usage in print_usages %} - {{ usage.print_job.project_name }} + {{ usage.print_job.display_name }} {{ usage.print_job.start_time|date:"Y-m-d H:i" }} Tray {{ usage.tray_id }} {{ usage.consumed_percent|default:"?" }}% ({{ usage.consumed_grams|default:"?" }}g) diff --git a/bambu_run/templates/bambu_run/printer_dashboard.html b/bambu_run/templates/bambu_run/printer_dashboard.html index 49ae1cc..58eeb95 100644 --- a/bambu_run/templates/bambu_run/printer_dashboard.html +++ b/bambu_run/templates/bambu_run/printer_dashboard.html @@ -94,7 +94,7 @@
- Job Name: {{ stats.subtask_name }} + Job Name: {{ stats.job_display_name }}
State: {{ stats.gcode_state }} diff --git a/bambu_run/views.py b/bambu_run/views.py index 73d42a2..1ca6a41 100644 --- a/bambu_run/views.py +++ b/bambu_run/views.py @@ -130,6 +130,24 @@ class PrinterDashboardView(LoginRequiredMixin, TemplateView): except Exception: filaments_list = [] + subtask_name = latest_metric.subtask_name or "No active print" + # Look up active PrintJob for a better display name (cloud design_title) + job_display_name = subtask_name + if latest_metric.subtask_name: + active_job = ( + PrintJob.objects.filter( + device=printer_device, + project_name=latest_metric.subtask_name, + end_time__isnull=True, + ).select_related('cloud_task').first() + or PrintJob.objects.filter( + device=printer_device, + project_name=latest_metric.subtask_name, + ).select_related('cloud_task').order_by('-start_time').first() + ) + if active_job: + job_display_name = active_job.display_name + stats = { "nozzle_temp": float(latest_metric.nozzle_temp) if latest_metric.nozzle_temp else 0, "bed_temp": float(latest_metric.bed_temp) if latest_metric.bed_temp else 0, @@ -137,7 +155,8 @@ class PrinterDashboardView(LoginRequiredMixin, TemplateView): "print_percent": latest_metric.print_percent or 0, "gcode_state": latest_metric.gcode_state or "Unknown", "print_type": latest_metric.print_type or "idle", - "subtask_name": latest_metric.subtask_name or "No active print", + "subtask_name": subtask_name, + "job_display_name": job_display_name, "chamber_light": latest_metric.chamber_light or "unknown", "ams_temp": float(latest_metric.ams_temp) if latest_metric.ams_temp else None, "ams_humidity": latest_metric.ams_humidity, @@ -158,7 +177,24 @@ class PrinterDashboardView(LoginRequiredMixin, TemplateView): return context def _calculate_project_markers(self, metrics, timezone_info): - """Calculate where print jobs start and end""" + """Calculate where print jobs start and end, using cloud design_title when available.""" + if not metrics: + return [] + + # Build a lookup: subtask_name -> display_name from PrintJobs in this time window + window_start = metrics[0].timestamp + window_end = metrics[-1].timestamp + device = metrics[0].device + jobs_qs = PrintJob.objects.filter( + device=device, + start_time__gte=window_start - timedelta(minutes=5), + start_time__lte=window_end + timedelta(minutes=5), + ).select_related('cloud_task') + # Map project_name (= subtask_name) -> best display name + subtask_to_display = {} + for job in jobs_qs: + subtask_to_display[job.project_name] = job.display_name + markers = [] current_job = None last_state = None @@ -170,21 +206,23 @@ class PrinterDashboardView(LoginRequiredMixin, TemplateView): is_printing = gcode_state not in ['FINISH', 'IDLE', None, ''] if subtask and subtask != current_job and is_printing: + display = subtask_to_display.get(subtask, subtask) markers.append({ 'type': 'start', 'index': idx, 'timestamp': metric.timestamp.astimezone(timezone_info).isoformat(), - 'project_name': subtask, + 'project_name': display, }) current_job = subtask last_state = gcode_state elif current_job and last_state and last_state not in ['FINISH', 'IDLE'] and gcode_state in ['FINISH', 'IDLE']: + display = subtask_to_display.get(current_job, current_job) markers.append({ 'type': 'end', 'index': idx, 'timestamp': metric.timestamp.astimezone(timezone_info).isoformat(), - 'project_name': current_job, + 'project_name': display, }) current_job = None @@ -613,7 +651,7 @@ class FilamentDetailView(LoginRequiredMixin, DetailView): context['bambu_run_base_template'] = app_settings.BASE_TEMPLATE filament = self.object - context['print_usages'] = filament.print_usages.select_related('print_job').order_by('-print_job__start_time')[:20] + context['print_usages'] = filament.print_usages.select_related('print_job__cloud_task').order_by('-print_job__start_time')[:20] total_consumed = filament.print_usages.aggregate( total=Sum('consumed_percent')