mirror of
https://github.com/RunLit/Bambu-Run.git
synced 2026-06-22 22:19:03 +01:00
back fill and relink print name using cloud if there is
This commit is contained in:
@@ -112,8 +112,8 @@ class Command(BaseCommand):
|
|||||||
serial_number=cloud_task.device_serial
|
serial_number=cloud_task.device_serial
|
||||||
).first()
|
).first()
|
||||||
if printer:
|
if printer:
|
||||||
window_start = 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=2)
|
window_end = cloud_task.cloud_start_time + timedelta(minutes=5)
|
||||||
historical = PrintJob.objects.filter(
|
historical = PrintJob.objects.filter(
|
||||||
device=printer,
|
device=printer,
|
||||||
start_time__gte=window_start,
|
start_time__gte=window_start,
|
||||||
|
|||||||
@@ -595,6 +595,13 @@ class PrintJob(models.Model):
|
|||||||
status = self.final_status or 'In Progress'
|
status = self.final_status or 'In Progress'
|
||||||
return f"{self.project_name} ({status}) - {self.start_time.strftime('%Y-%m-%d %H:%M')}"
|
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):
|
def calculate_duration(self):
|
||||||
"""Calculate print duration if end_time is set"""
|
"""Calculate print duration if end_time is set"""
|
||||||
if self.end_time and self.start_time:
|
if self.end_time and self.start_time:
|
||||||
|
|||||||
@@ -154,7 +154,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for usage in print_usages %}
|
{% for usage in print_usages %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ usage.print_job.project_name }}</td>
|
<td>{{ usage.print_job.display_name }}</td>
|
||||||
<td>{{ usage.print_job.start_time|date:"Y-m-d H:i" }}</td>
|
<td>{{ usage.print_job.start_time|date:"Y-m-d H:i" }}</td>
|
||||||
<td>Tray {{ usage.tray_id }}</td>
|
<td>Tray {{ usage.tray_id }}</td>
|
||||||
<td>{{ usage.consumed_percent|default:"?" }}% ({{ usage.consumed_grams|default:"?" }}g)</td>
|
<td>{{ usage.consumed_percent|default:"?" }}% ({{ usage.consumed_grams|default:"?" }}g)</td>
|
||||||
|
|||||||
@@ -94,7 +94,7 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<strong>Job Name:</strong> {{ stats.subtask_name }}
|
<strong>Job Name:</strong> {{ stats.job_display_name }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<strong>State:</strong> {{ stats.gcode_state }}
|
<strong>State:</strong> {{ stats.gcode_state }}
|
||||||
|
|||||||
@@ -130,6 +130,24 @@ class PrinterDashboardView(LoginRequiredMixin, TemplateView):
|
|||||||
except Exception:
|
except Exception:
|
||||||
filaments_list = []
|
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 = {
|
stats = {
|
||||||
"nozzle_temp": float(latest_metric.nozzle_temp) if latest_metric.nozzle_temp else 0,
|
"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,
|
"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,
|
"print_percent": latest_metric.print_percent or 0,
|
||||||
"gcode_state": latest_metric.gcode_state or "Unknown",
|
"gcode_state": latest_metric.gcode_state or "Unknown",
|
||||||
"print_type": latest_metric.print_type or "idle",
|
"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",
|
"chamber_light": latest_metric.chamber_light or "unknown",
|
||||||
"ams_temp": float(latest_metric.ams_temp) if latest_metric.ams_temp else None,
|
"ams_temp": float(latest_metric.ams_temp) if latest_metric.ams_temp else None,
|
||||||
"ams_humidity": latest_metric.ams_humidity,
|
"ams_humidity": latest_metric.ams_humidity,
|
||||||
@@ -158,7 +177,24 @@ class PrinterDashboardView(LoginRequiredMixin, TemplateView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def _calculate_project_markers(self, metrics, timezone_info):
|
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 = []
|
markers = []
|
||||||
current_job = None
|
current_job = None
|
||||||
last_state = None
|
last_state = None
|
||||||
@@ -170,21 +206,23 @@ class PrinterDashboardView(LoginRequiredMixin, TemplateView):
|
|||||||
is_printing = gcode_state not in ['FINISH', 'IDLE', None, '']
|
is_printing = gcode_state not in ['FINISH', 'IDLE', None, '']
|
||||||
|
|
||||||
if subtask and subtask != current_job and is_printing:
|
if subtask and subtask != current_job and is_printing:
|
||||||
|
display = subtask_to_display.get(subtask, subtask)
|
||||||
markers.append({
|
markers.append({
|
||||||
'type': 'start',
|
'type': 'start',
|
||||||
'index': idx,
|
'index': idx,
|
||||||
'timestamp': metric.timestamp.astimezone(timezone_info).isoformat(),
|
'timestamp': metric.timestamp.astimezone(timezone_info).isoformat(),
|
||||||
'project_name': subtask,
|
'project_name': display,
|
||||||
})
|
})
|
||||||
current_job = subtask
|
current_job = subtask
|
||||||
last_state = gcode_state
|
last_state = gcode_state
|
||||||
|
|
||||||
elif current_job and last_state and last_state not in ['FINISH', 'IDLE'] and gcode_state in ['FINISH', 'IDLE']:
|
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({
|
markers.append({
|
||||||
'type': 'end',
|
'type': 'end',
|
||||||
'index': idx,
|
'index': idx,
|
||||||
'timestamp': metric.timestamp.astimezone(timezone_info).isoformat(),
|
'timestamp': metric.timestamp.astimezone(timezone_info).isoformat(),
|
||||||
'project_name': current_job,
|
'project_name': display,
|
||||||
})
|
})
|
||||||
current_job = None
|
current_job = None
|
||||||
|
|
||||||
@@ -613,7 +651,7 @@ class FilamentDetailView(LoginRequiredMixin, DetailView):
|
|||||||
context['bambu_run_base_template'] = app_settings.BASE_TEMPLATE
|
context['bambu_run_base_template'] = app_settings.BASE_TEMPLATE
|
||||||
filament = self.object
|
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_consumed = filament.print_usages.aggregate(
|
||||||
total=Sum('consumed_percent')
|
total=Sum('consumed_percent')
|
||||||
|
|||||||
Reference in New Issue
Block a user