spoolbuddy.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. ssh_public_key: str | None = None
  67. # --- NFC schemas ---
  68. class TagScannedRequest(BaseModel):
  69. device_id: str
  70. tag_uid: str
  71. tray_uuid: str | None = None
  72. sak: int | None = None
  73. tag_type: str | None = None
  74. raw_blocks: dict | None = None
  75. class TagRemovedRequest(BaseModel):
  76. device_id: str
  77. tag_uid: str
  78. # --- Scale schemas ---
  79. class ScaleReadingRequest(BaseModel):
  80. device_id: str
  81. weight_grams: float
  82. stable: bool = False
  83. raw_adc: int | None = None
  84. class UpdateSpoolWeightRequest(BaseModel):
  85. spool_id: int
  86. weight_grams: float
  87. # --- Calibration schemas ---
  88. class SetTareRequest(BaseModel):
  89. tare_offset: int
  90. class SetCalibrationFactorRequest(BaseModel):
  91. known_weight_grams: float = Field(..., gt=0)
  92. raw_adc: int
  93. tare_raw_adc: int | None = None
  94. class CalibrationResponse(BaseModel):
  95. tare_offset: int
  96. calibration_factor: float
  97. # --- Display schemas ---
  98. class WriteTagRequest(BaseModel):
  99. device_id: str
  100. spool_id: int
  101. class WriteTagResultRequest(BaseModel):
  102. device_id: str
  103. spool_id: int
  104. tag_uid: str
  105. success: bool
  106. message: str | None = None
  107. class DisplaySettingsRequest(BaseModel):
  108. brightness: int = Field(ge=0, le=100)
  109. blank_timeout: int = Field(ge=0)
  110. class SystemConfigRequest(BaseModel):
  111. backend_url: str = Field(..., min_length=1, max_length=255)
  112. api_key: str | None = Field(default=None, max_length=255)
  113. class SystemCommandRequest(BaseModel):
  114. command: str = Field(..., description="System command: reboot, shutdown, restart_daemon, restart_browser")
  115. class SystemCommandResultRequest(BaseModel):
  116. command: str
  117. success: bool
  118. message: str | None = None
  119. # --- Diagnostics schemas ---
  120. class DiagnosticResultRequest(BaseModel):
  121. diagnostic: str # 'nfc', 'scale', or 'read_tag'
  122. success: bool
  123. output: str
  124. exit_code: int