models.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. from dataclasses import dataclass, field
  2. from typing import List, Optional
  3. from enum import Enum
  4. class ModuleType(Enum):
  5. HD3200 = "HD3200"
  6. RFID = "RFID"
  7. class CameraPosition(Enum):
  8. LEFT = "left"
  9. RIGHT = "right"
  10. class CameraState(Enum):
  11. ONLINE = "online"
  12. OFFLINE = "offline"
  13. class SwitchMode(Enum):
  14. AUTO = "auto"
  15. HAND = "hand"
  16. @dataclass
  17. class CameraModel:
  18. position: CameraPosition
  19. rtsp_url: str
  20. topic: Optional[str] = None
  21. state: CameraState = CameraState.OFFLINE
  22. class HookState(Enum):
  23. IDLE = "idle"
  24. RELEASING = "releasing" # 放包中
  25. HOOKING = "hooking" # 挂包中
  26. READY = "ready" # 挂包成功
  27. @dataclass
  28. class BucketModel:
  29. id: int
  30. description: str
  31. code_x: str # 大车标识(RFID卡号或Modbus点号)
  32. code_y: str = "" # 小车标识(垂直工位)
  33. ai_module_id: Optional[int] = None # 关联AI模块索引
  34. cameras: List[CameraModel] = field(default_factory=list)
  35. is_active: bool = False
  36. ready_x: bool = False
  37. ready_y: bool = True # 无垂直工位时为True
  38. # 可以起吊判定:hook/lug 归一化偏移标定值(X 用中心点、Y 用框底边,每工位每侧,空=未标定)
  39. hook_lug_x_offset_ratio_left: Optional[float] = None
  40. hook_lug_y_offset_ratio_left: Optional[float] = None
  41. hook_lug_x_offset_ratio_right: Optional[float] = None
  42. hook_lug_y_offset_ratio_right: Optional[float] = None
  43. @dataclass
  44. class AIModuleModel:
  45. id: int
  46. broker: str = "127.0.0.1"
  47. port: int = 1883
  48. topics: List[str] = field(default_factory=list)
  49. @dataclass
  50. class AIConfig:
  51. enabled: bool = False
  52. tts_enabled: bool = False
  53. debug_trace: bool = True
  54. # 可以起吊:hook/lug 中心归一化偏移容差(x/y 共用)与防抖帧数
  55. offset_ratio_tolerance: float = 0.25
  56. ready_debounce: int = 3
  57. # 自动标定参数:窗口内出现 N 帧 ready 触发(不要求连续)/ 窗口时长(秒)/ 最少有效样本数
  58. auto_calib_ready_frames: int = 3
  59. auto_calib_duration_secs: float = 1.0
  60. auto_calib_min_samples: int = 2
  61. @dataclass
  62. class ModbusConfig:
  63. ip: str
  64. port: int = 502
  65. frequency: int = 100
  66. stability_count: int = 3
  67. @dataclass
  68. class SocketConfig:
  69. ip: str
  70. port: int = 6000
  71. stability_time: int = 20
  72. stability_count: int = 3
  73. class RestartInterval(Enum):
  74. DAY = "day"
  75. WEEK = "week"
  76. MONTH = "month"
  77. class RestartTarget(Enum):
  78. APP = "app"
  79. DEVICE = "device"
  80. @dataclass
  81. class AutoRestartConfig:
  82. enabled: bool = False
  83. interval: RestartInterval = RestartInterval.DAY
  84. hour: int = 3
  85. minute: int = 0
  86. target: RestartTarget = RestartTarget.APP
  87. weekdays: int = 0
  88. day_of_month: int = 1
  89. countdown: int = 60
  90. @dataclass
  91. class VideoConfig:
  92. rtsp_timeout: float = 5.0 # 默认 5 秒
  93. ratio_16_9: bool = True # 画面比例 16:9 / 4:3
  94. @dataclass
  95. class Config:
  96. app_name: str = "钢包工位视频监测系统"
  97. copyright: str = "恒莱达"
  98. screen: int = 0
  99. module_type: ModuleType = ModuleType.RFID
  100. rfid: Optional[SocketConfig] = None
  101. modbus: Optional[ModbusConfig] = None
  102. ai: AIConfig = field(default_factory=AIConfig)
  103. ai_modules: List[AIModuleModel] = field(default_factory=list)
  104. buckets: List[BucketModel] = field(default_factory=list)
  105. video: VideoConfig = field(default_factory=VideoConfig)
  106. auto_restart: AutoRestartConfig = field(default_factory=AutoRestartConfig)