mirror of
https://github.com/RunLit/Bambu-Run.git
synced 2026-10-21 23:39:01 +01:00
feat(mcp): add get_print_job tool
This commit is contained in:
@@ -72,3 +72,45 @@ def _job_summary(job):
|
|||||||
"cost": None,
|
"cost": None,
|
||||||
"has_cover_image": bool(cloud and cloud.cover_url),
|
"has_cover_image": bool(cloud and cloud.cover_url),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_print_job(job_id: int) -> dict:
|
||||||
|
"""Full detail for one print job: the list_print_jobs fields plus
|
||||||
|
per-slot filament breakdown, estimate-vs-actual delta, and linked cloud
|
||||||
|
metadata. Raises PrintJob.DoesNotExist if job_id is unknown.
|
||||||
|
"""
|
||||||
|
job = PrintJob.objects.select_related("cloud_task", "device").get(id=job_id)
|
||||||
|
summary = _job_summary(job)
|
||||||
|
|
||||||
|
delta_percent = None
|
||||||
|
if summary["estimated_duration_min"] and summary["duration_min"]:
|
||||||
|
delta_percent = round(
|
||||||
|
100 * (summary["duration_min"] - summary["estimated_duration_min"])
|
||||||
|
/ summary["estimated_duration_min"],
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
|
usages = []
|
||||||
|
for u in job.filament_usages.select_related("filament"):
|
||||||
|
consumed_percent, consumed_grams, quality = normalize_consumed(
|
||||||
|
u.starting_percent, u.ending_percent,
|
||||||
|
u.filament.initial_weight_grams if u.filament else None,
|
||||||
|
)
|
||||||
|
usages.append({
|
||||||
|
"tray_id": u.tray_id,
|
||||||
|
"ams_unit_id": u.ams_unit_id,
|
||||||
|
"filament_id": u.filament_id,
|
||||||
|
"consumed_percent": consumed_percent,
|
||||||
|
"consumed_grams": consumed_grams,
|
||||||
|
"data_quality": quality,
|
||||||
|
"is_primary": u.is_primary,
|
||||||
|
})
|
||||||
|
|
||||||
|
cloud = job.cloud_task
|
||||||
|
return {
|
||||||
|
**summary,
|
||||||
|
"estimate_delta_percent": delta_percent,
|
||||||
|
"filament_usages": usages,
|
||||||
|
"cloud_design_title": cloud.design_title if cloud else None,
|
||||||
|
"cover_url": cloud.cover_url if cloud and cloud.cover_url else None,
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import pytest
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from bambu_run.models import Printer, PrintJob, BambuCloudTask
|
from bambu_run.models import Printer, PrintJob, BambuCloudTask, Filament, FilamentUsage
|
||||||
from bambu_run.mcp.jobs import list_print_jobs
|
from bambu_run.mcp.jobs import list_print_jobs, get_print_job
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
@@ -69,3 +69,40 @@ def test_list_print_jobs_display_name_falls_back_to_project_name():
|
|||||||
result = list_print_jobs()
|
result = list_print_jobs()
|
||||||
|
|
||||||
assert result["jobs"][0]["display_name"] == "raw_project"
|
assert result["jobs"][0]["display_name"] == "raw_project"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_get_print_job_marks_negative_consumption_unreliable():
|
||||||
|
p = Printer.objects.create(name="RNL-H2C", model="H2C", is_active=True)
|
||||||
|
job = PrintJob.objects.create(device=p, project_name="Bracket", start_time=timezone.now(), final_status="FINISH")
|
||||||
|
filament = Filament.objects.create(type="ABS", brand="Bambu Lab", color="Mint", initial_weight_grams=1000)
|
||||||
|
FilamentUsage.objects.create(
|
||||||
|
print_job=job, filament=filament, tray_id=0,
|
||||||
|
starting_percent=51, ending_percent=52, # ordinary RFID jitter, spec finding
|
||||||
|
)
|
||||||
|
|
||||||
|
result = get_print_job(job.id)
|
||||||
|
|
||||||
|
usage = result["filament_usages"][0]
|
||||||
|
assert usage["consumed_grams"] is None
|
||||||
|
assert usage["data_quality"] == "unreliable"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_get_print_job_computes_estimate_delta_percent():
|
||||||
|
p = Printer.objects.create(name="RNL-H2C", model="H2C", is_active=True)
|
||||||
|
cloud = BambuCloudTask.objects.create(task_id=1, cost_time_seconds=205 * 60)
|
||||||
|
job = PrintJob.objects.create(
|
||||||
|
device=p, project_name="Bracket", start_time=timezone.now(),
|
||||||
|
final_status="FINISH", cloud_task=cloud, duration_minutes=237,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = get_print_job(job.id)
|
||||||
|
|
||||||
|
assert result["estimate_delta_percent"] == round(100 * (237 - 205) / 205, 1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_get_print_job_unknown_id_raises():
|
||||||
|
with pytest.raises(PrintJob.DoesNotExist):
|
||||||
|
get_print_job(999999)
|
||||||
|
|||||||
Reference in New Issue
Block a user