print_queue.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. # Either archive_id OR library_file_id must be provided
  14. archive_id: int | None = None
  15. library_file_id: int | None = None
  16. scheduled_time: datetime | None = None # None = ASAP (next when idle)
  17. require_previous_success: bool = False
  18. auto_off_after: bool = False # Power off printer after print completes
  19. manual_start: bool = False # Requires manual trigger to start (staged)
  20. # AMS mapping: list of global tray IDs for each filament slot
  21. # Format: [5, -1, 2, -1] where position = slot_id-1, value = global tray ID (-1 = unused)
  22. ams_mapping: list[int] | None = None
  23. # Plate ID for multi-plate 3MF files (1-indexed, None = auto-detect/plate 1)
  24. plate_id: int | None = None
  25. # Print options
  26. bed_levelling: bool = True
  27. flow_cali: bool = False
  28. vibration_cali: bool = True
  29. layer_inspect: bool = False
  30. timelapse: bool = False
  31. use_ams: bool = True
  32. class PrintQueueItemUpdate(BaseModel):
  33. printer_id: int | None = None
  34. position: int | None = None
  35. scheduled_time: datetime | None = None
  36. require_previous_success: bool | None = None
  37. auto_off_after: bool | None = None
  38. manual_start: bool | None = None
  39. ams_mapping: list[int] | None = None
  40. plate_id: int | None = None
  41. # Print options
  42. bed_levelling: bool | None = None
  43. flow_cali: bool | None = None
  44. vibration_cali: bool | None = None
  45. layer_inspect: bool | None = None
  46. timelapse: bool | None = None
  47. use_ams: bool | None = None
  48. class PrintQueueItemResponse(BaseModel):
  49. id: int
  50. printer_id: int | None # None = unassigned
  51. archive_id: int | None # None if library_file_id is set (archive created at print start)
  52. library_file_id: int | None # For queue items from library files
  53. position: int
  54. scheduled_time: UTCDatetime
  55. require_previous_success: bool
  56. auto_off_after: bool
  57. manual_start: bool
  58. ams_mapping: list[int] | None = None
  59. plate_id: int | None = None # Plate ID for multi-plate 3MF files
  60. # Print options
  61. bed_levelling: bool = True
  62. flow_cali: bool = False
  63. vibration_cali: bool = True
  64. layer_inspect: bool = False
  65. timelapse: bool = False
  66. use_ams: bool = True
  67. status: Literal["pending", "printing", "completed", "failed", "skipped", "cancelled"]
  68. started_at: UTCDatetime
  69. completed_at: UTCDatetime
  70. error_message: str | None
  71. created_at: UTCDatetime
  72. # Nested info for UI (populated in route)
  73. archive_name: str | None = None
  74. archive_thumbnail: str | None = None
  75. library_file_name: str | None = None # Name of library file (if library_file_id is set)
  76. library_file_thumbnail: str | None = None # Thumbnail of library file
  77. printer_name: str | None = None
  78. print_time_seconds: int | None = None # Estimated print time from archive or library file
  79. class Config:
  80. from_attributes = True
  81. class PrintQueueReorderItem(BaseModel):
  82. id: int
  83. position: int
  84. class PrintQueueReorder(BaseModel):
  85. items: list[PrintQueueReorderItem]