from pydantic import BaseModel, ConfigDict, Field, JsonValue, model_validator class ScadaMonitoringSettings(BaseModel): """Project-owned device roles used by the manual SCADA monitoring demo.""" model_config = ConfigDict(extra="forbid", allow_inf_nan=False) rule_version: str = Field( default="burst-monitor-v1", min_length=1, max_length=80, pattern=r"^[a-zA-Z0-9_.-]+$", ) pressure_device_ids: list[str] = Field(default_factory=list, max_length=20) outlet_flow_device_ids: list[str] = Field(default_factory=list, max_length=20) @model_validator(mode="after") def distinct_roles(self): for values in (self.pressure_device_ids, self.outlet_flow_device_ids): if len(set(values)) != len(values) or any(not value.strip() for value in values): raise ValueError("SCADA 监测角色中的设备标识不能为空或重复") if set(self.pressure_device_ids) & set(self.outlet_flow_device_ids): raise ValueError("同一设备不能同时作为压力与出厂边界流量") return self class ProjectSettings(BaseModel): """Extensible, non-secret project parameters stored in MetaDB as JSON.""" model_config = ConfigDict(extra="allow", allow_inf_nan=False) __pydantic_extra__: dict[str, JsonValue] = Field(init=False) scada_monitoring_interval_seconds: int | None = Field( default=None, strict=True, ge=60, le=31_536_000, description="SCADA 主动监测演示步长,单位秒;null 表示未配置", ) scada_monitoring: ScadaMonitoringSettings | None = Field( default=None, description="主动监测使用的项目设备角色;不创建定时任务", )