spoolbuddy.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. from datetime import datetime
  2. from pydantic import BaseModel, Field
  3. # --- Device schemas ---
  4. class DeviceRegisterRequest(BaseModel):
  5. device_id: str = Field(..., min_length=1, max_length=50)
  6. hostname: str = Field(..., min_length=1, max_length=100)
  7. ip_address: str = Field(..., min_length=1, max_length=45)
  8. firmware_version: str | None = None
  9. has_nfc: bool = True
  10. has_scale: bool = True
  11. tare_offset: int = 0
  12. calibration_factor: float = 1.0
  13. nfc_reader_type: str | None = None
  14. nfc_connection: str | None = None
  15. backend_url: str | None = None
  16. has_backlight: bool = False
  17. class DeviceResponse(BaseModel):
  18. id: int
  19. device_id: str
  20. hostname: str
  21. ip_address: str
  22. firmware_version: str | None = None
  23. has_nfc: bool
  24. has_scale: bool
  25. tare_offset: int
  26. calibration_factor: float
  27. nfc_reader_type: str | None = None
  28. nfc_connection: str | None = None
  29. backend_url: str | None = None
  30. display_brightness: int = 100
  31. display_blank_timeout: int = 0
  32. has_backlight: bool = False
  33. last_calibrated_at: datetime | None = None
  34. last_seen: datetime | None = None
  35. pending_command: str | None = None
  36. nfc_ok: bool
  37. scale_ok: bool
  38. uptime_s: int
  39. update_status: str | None = None
  40. update_message: str | None = None
  41. system_stats: dict | None = None
  42. online: bool = False
  43. ssh_public_key: str | None = None
  44. created_at: datetime
  45. updated_at: datetime
  46. class Config:
  47. from_attributes = True
  48. class HeartbeatRequest(BaseModel):
  49. nfc_ok: bool = False
  50. scale_ok: bool = False
  51. uptime_s: int = 0
  52. firmware_version: str | None = None
  53. ip_address: str | None = None
  54. nfc_reader_type: str | None = None
  55. nfc_connection: str | None = None
  56. backend_url: str | None = None
  57. system_stats: dict | None = None
  58. class HeartbeatResponse(BaseModel):
  59. pending_command: str | None = None
  60. pending_write_payload: dict | None = None
  61. pending_system_payload: dict | None = None
  62. tare_offset: int
  63. calibration_factor: float
  64. display_brightness: int = 100
  65. display_blank_timeout: int = 0
  66. # --- NFC schemas ---
  67. class TagScannedRequest(BaseModel):
  68. device_id: str
  69. tag_uid: str
  70. tray_uuid: str | None = None
  71. sak: int | None = None
  72. tag_type: str | None = None
  73. raw_blocks: dict | None = None
  74. class TagRemovedRequest(BaseModel):
  75. device_id: str
  76. tag_uid: str
  77. # --- Scale schemas ---
  78. class ScaleReadingRequest(BaseModel):
  79. device_id: str
  80. weight_grams: float
  81. stable: bool = False
  82. raw_adc: int | None = None
  83. class UpdateSpoolWeightRequest(BaseModel):
  84. spool_id: int
  85. weight_grams: float
  86. # --- Calibration schemas ---
  87. class SetTareRequest(BaseModel):
  88. tare_offset: int
  89. class SetCalibrationFactorRequest(BaseModel):
  90. known_weight_grams: float = Field(..., gt=0)
  91. raw_adc: int
  92. tare_raw_adc: int | None = None
  93. class CalibrationResponse(BaseModel):
  94. tare_offset: int
  95. calibration_factor: float
  96. # --- Display schemas ---
  97. class WriteTagRequest(BaseModel):
  98. device_id: str
  99. spool_id: int
  100. class WriteTagResultRequest(BaseModel):
  101. device_id: str
  102. spool_id: int
  103. tag_uid: str
  104. success: bool
  105. message: str | None = None
  106. class DisplaySettingsRequest(BaseModel):
  107. brightness: int = Field(ge=0, le=100)
  108. blank_timeout: int = Field(ge=0)
  109. class SystemConfigRequest(BaseModel):
  110. backend_url: str = Field(..., min_length=1, max_length=255)
  111. api_key: str | None = Field(default=None, max_length=255)
  112. class SystemCommandResultRequest(BaseModel):
  113. command: str
  114. success: bool
  115. message: str | None = None
  116. # --- Diagnostics schemas ---
  117. class DiagnosticResultRequest(BaseModel):
  118. diagnostic: str # 'nfc', 'scale', or 'read_tag'
  119. success: bool
  120. output: str
  121. exit_code: int