printer.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. from datetime import datetime
  2. from pydantic import BaseModel, Field
  3. class PrinterBase(BaseModel):
  4. name: str = Field(..., min_length=1, max_length=100)
  5. serial_number: str = Field(..., min_length=1, max_length=50)
  6. ip_address: str = Field(..., pattern=r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
  7. access_code: str = Field(..., min_length=1, max_length=20)
  8. model: str | None = None
  9. auto_archive: bool = True
  10. class PrinterCreate(PrinterBase):
  11. pass
  12. class PrinterUpdate(BaseModel):
  13. name: str | None = None
  14. ip_address: str | None = None
  15. access_code: str | None = None
  16. model: str | None = None
  17. is_active: bool | None = None
  18. auto_archive: bool | None = None
  19. print_hours_offset: float | None = None
  20. class PrinterResponse(PrinterBase):
  21. id: int
  22. is_active: bool
  23. nozzle_count: int = 1 # 1 or 2, auto-detected from MQTT
  24. print_hours_offset: float = 0.0
  25. created_at: datetime
  26. updated_at: datetime
  27. class Config:
  28. from_attributes = True
  29. class HMSErrorResponse(BaseModel):
  30. code: str
  31. attr: int = 0 # Attribute value for constructing wiki URL
  32. module: int
  33. severity: int # 1=fatal, 2=serious, 3=common, 4=info
  34. class AMSTray(BaseModel):
  35. id: int
  36. tray_color: str | None = None
  37. tray_type: str | None = None
  38. remain: int = 0
  39. k: float | None = None # Pressure advance value
  40. class AMSUnit(BaseModel):
  41. id: int
  42. humidity: int | None = None
  43. temp: float | None = None
  44. tray: list[AMSTray] = []
  45. class NozzleInfoResponse(BaseModel):
  46. nozzle_type: str = "" # "stainless_steel" or "hardened_steel"
  47. nozzle_diameter: str = "" # e.g., "0.4"
  48. class PrintOptionsResponse(BaseModel):
  49. """AI detection and print options from xcam data."""
  50. # Core AI detectors
  51. spaghetti_detector: bool = False
  52. print_halt: bool = False
  53. halt_print_sensitivity: str = "medium" # Spaghetti sensitivity
  54. first_layer_inspector: bool = False
  55. printing_monitor: bool = False
  56. buildplate_marker_detector: bool = False
  57. allow_skip_parts: bool = False
  58. # Additional AI detectors (decoded from cfg bitmask)
  59. nozzle_clumping_detector: bool = True
  60. nozzle_clumping_sensitivity: str = "medium"
  61. pileup_detector: bool = True
  62. pileup_sensitivity: str = "medium"
  63. airprint_detector: bool = True
  64. airprint_sensitivity: str = "medium"
  65. auto_recovery_step_loss: bool = True
  66. filament_tangle_detect: bool = False
  67. class PrinterStatus(BaseModel):
  68. id: int
  69. name: str
  70. connected: bool
  71. state: str | None = None
  72. current_print: str | None = None
  73. subtask_name: str | None = None
  74. gcode_file: str | None = None
  75. progress: float | None = None
  76. remaining_time: int | None = None
  77. layer_num: int | None = None
  78. total_layers: int | None = None
  79. temperatures: dict | None = None
  80. cover_url: str | None = None
  81. hms_errors: list[HMSErrorResponse] = []
  82. ams: list[AMSUnit] = []
  83. ams_exists: bool = False
  84. vt_tray: AMSTray | None = None # Virtual tray / external spool
  85. sdcard: bool = False # SD card inserted
  86. store_to_sdcard: bool = False # Store sent files on SD card
  87. timelapse: bool = False # Timelapse recording active
  88. ipcam: bool = False # Live view enabled
  89. nozzles: list[NozzleInfoResponse] = [] # Nozzle hardware info (index 0=left/primary, 1=right)
  90. print_options: PrintOptionsResponse | None = None # AI detection and print options
  91. # Calibration stage tracking
  92. stg_cur: int = -1 # Current stage number (-1 = not calibrating)
  93. stg_cur_name: str | None = None # Human-readable current stage name
  94. stg: list[int] = [] # List of stage numbers in calibration sequence
  95. # Air conditioning mode (0=cooling, 1=heating)
  96. airduct_mode: int = 0
  97. # Print speed level (1=silent, 2=standard, 3=sport, 4=ludicrous)
  98. speed_level: int = 2
  99. # Chamber light on/off
  100. chamber_light: bool = False
  101. # Active extruder for dual nozzle (0=right, 1=left)
  102. active_extruder: int = 0
  103. # AMS mapping for dual nozzle: which AMS is connected to which nozzle
  104. ams_mapping: list[int] = []
  105. # Per-AMS extruder map: {ams_id: extruder_id} where 0=right, 1=left
  106. ams_extruder_map: dict[str, int] = {}
  107. # Currently loaded tray (global ID): 254 = external spool, 255 = no filament
  108. tray_now: int = 255