print_queue.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. from datetime import datetime
  2. from typing import Annotated, Literal
  3. from pydantic import BaseModel, PlainSerializer
  4. # Custom serializer to ensure UTC datetimes have Z suffix
  5. def serialize_utc_datetime(dt: datetime | None) -> str | None:
  6. if dt is None:
  7. return None
  8. # Add Z suffix to indicate UTC
  9. return dt.isoformat() + "Z"
  10. UTCDatetime = Annotated[datetime | None, PlainSerializer(serialize_utc_datetime)]
  11. class PrintQueueItemCreate(BaseModel):
  12. printer_id: int | None = None # None = unassigned, user assigns later
  13. target_model: str | None = None # Target printer model (mutually exclusive with printer_id)
  14. # Either archive_id OR library_file_id must be provided
  15. archive_id: int | None = None
  16. library_file_id: int | None = None
  17. scheduled_time: datetime | None = None # None = ASAP (next when idle)
  18. require_previous_success: bool = False
  19. auto_off_after: bool = False # Power off printer after print completes
  20. manual_start: bool = False # Requires manual trigger to start (staged)
  21. # AMS mapping: list of global tray IDs for each filament slot
  22. # Format: [5, -1, 2, -1] where position = slot_id-1, value = global tray ID (-1 = unused)
  23. ams_mapping: list[int] | None = None
  24. # Plate ID for multi-plate 3MF files (1-indexed, None = auto-detect/plate 1)
  25. plate_id: int | None = None
  26. # Print options
  27. bed_levelling: bool = True
  28. flow_cali: bool = False
  29. vibration_cali: bool = True
  30. layer_inspect: bool = False
  31. timelapse: bool = False
  32. use_ams: bool = True
  33. class PrintQueueItemUpdate(BaseModel):
  34. printer_id: int | None = None
  35. target_model: str | None = None # Target printer model (mutually exclusive with printer_id)
  36. position: int | None = None
  37. scheduled_time: datetime | None = None
  38. require_previous_success: bool | None = None
  39. auto_off_after: bool | None = None
  40. manual_start: bool | None = None
  41. ams_mapping: list[int] | None = None
  42. plate_id: int | None = None
  43. # Print options
  44. bed_levelling: bool | None = None
  45. flow_cali: bool | None = None
  46. vibration_cali: bool | None = None
  47. layer_inspect: bool | None = None
  48. timelapse: bool | None = None
  49. use_ams: bool | None = None
  50. class PrintQueueItemResponse(BaseModel):
  51. id: int
  52. printer_id: int | None # None = unassigned
  53. target_model: str | None = None # Target printer model for model-based assignment
  54. archive_id: int | None # None if library_file_id is set (archive created at print start)
  55. library_file_id: int | None # For queue items from library files
  56. position: int
  57. scheduled_time: UTCDatetime
  58. require_previous_success: bool
  59. auto_off_after: bool
  60. manual_start: bool
  61. ams_mapping: list[int] | None = None
  62. plate_id: int | None = None # Plate ID for multi-plate 3MF files
  63. # Print options
  64. bed_levelling: bool = True
  65. flow_cali: bool = False
  66. vibration_cali: bool = True
  67. layer_inspect: bool = False
  68. timelapse: bool = False
  69. use_ams: bool = True
  70. status: Literal["pending", "printing", "completed", "failed", "skipped", "cancelled"]
  71. started_at: UTCDatetime
  72. completed_at: UTCDatetime
  73. error_message: str | None
  74. created_at: UTCDatetime
  75. # Nested info for UI (populated in route)
  76. archive_name: str | None = None
  77. archive_thumbnail: str | None = None
  78. library_file_name: str | None = None # Name of library file (if library_file_id is set)
  79. library_file_thumbnail: str | None = None # Thumbnail of library file
  80. printer_name: str | None = None
  81. print_time_seconds: int | None = None # Estimated print time from archive or library file
  82. class Config:
  83. from_attributes = True
  84. class PrintQueueReorderItem(BaseModel):
  85. id: int
  86. position: int
  87. class PrintQueueReorder(BaseModel):
  88. items: list[PrintQueueReorderItem]
  89. class PrintQueueBulkUpdate(BaseModel):
  90. """Bulk update multiple queue items with the same values."""
  91. item_ids: list[int]
  92. # Fields to update (all optional - only set fields are applied)
  93. printer_id: int | None = None
  94. scheduled_time: datetime | None = None
  95. require_previous_success: bool | None = None
  96. auto_off_after: bool | None = None
  97. manual_start: bool | None = None
  98. # Print options
  99. bed_levelling: bool | None = None
  100. flow_cali: bool | None = None
  101. vibration_cali: bool | None = None
  102. layer_inspect: bool | None = None
  103. timelapse: bool | None = None
  104. use_ams: bool | None = None
  105. class PrintQueueBulkUpdateResponse(BaseModel):
  106. """Response for bulk update operation."""
  107. updated_count: int
  108. skipped_count: int # Items that were not pending
  109. message: str