feat(scada): add calibrated monitoring and incident recovery
This commit is contained in:
@@ -5,6 +5,8 @@ from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
||||
|
||||
from app.domain.schemas.project_settings import ScadaMonitoringSettings
|
||||
|
||||
|
||||
class ReplayModel(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid", allow_inf_nan=False)
|
||||
@@ -78,7 +80,26 @@ class ScadaReplayCreate(ReplayModel):
|
||||
class ScadaReplayCommand(ReplayModel):
|
||||
request_id: UUID
|
||||
expected_revision: int = Field(ge=1)
|
||||
action: Literal["step", "stop", "retry"]
|
||||
action: Literal["step", "monitor", "stop", "retry"]
|
||||
at_time: datetime | None = None
|
||||
|
||||
@model_validator(mode="after")
|
||||
def monitoring_time(self):
|
||||
if self.action == "monitor":
|
||||
if self.at_time is None or self.at_time.tzinfo is None:
|
||||
raise ValueError("选定时刻监测需要提供带时区的 at_time")
|
||||
elif self.at_time is not None:
|
||||
raise ValueError("只有选定时刻监测可以指定 at_time")
|
||||
return self
|
||||
|
||||
|
||||
class ScadaMonitoringIncident(ReplayModel):
|
||||
incident_id: UUID
|
||||
status: Literal["active", "resolved"]
|
||||
action: Literal["raised", "ongoing", "resolved"]
|
||||
started_at: datetime
|
||||
last_observed_at: datetime
|
||||
recovery_count: int = Field(ge=0, le=2)
|
||||
|
||||
|
||||
class ScadaMonitoringResult(ReplayModel):
|
||||
@@ -94,7 +115,10 @@ class ScadaMonitoringResult(ReplayModel):
|
||||
pressure: dict
|
||||
outlet_flow: dict
|
||||
burst_detection: dict
|
||||
weighted: dict | None = None
|
||||
incident: ScadaMonitoringIncident | None = None
|
||||
role_gaps: list[str] = Field(default_factory=list)
|
||||
anomaly_signals: list[dict] = Field(default_factory=list)
|
||||
|
||||
|
||||
class ScadaReplaySnapshot(ReplayModel):
|
||||
@@ -108,6 +132,8 @@ class ScadaReplaySnapshot(ReplayModel):
|
||||
step_pending: bool = False
|
||||
monitoring_count: int = 0
|
||||
last_monitoring: ScadaMonitoringResult | None = None
|
||||
monitoring_config: ScadaMonitoringSettings | None = None
|
||||
monitoring_calibration: dict | None = None
|
||||
virtual_now: datetime
|
||||
delivered_until: datetime | None = None
|
||||
processed_until: datetime | None = None
|
||||
@@ -129,6 +155,7 @@ class ScadaReplayCapabilities(ReplayModel):
|
||||
monitoring_interval_seconds: int | None = Field(None, ge=60, le=31_536_000)
|
||||
burst_monitoring_ready: bool = False
|
||||
burst_monitoring_reason: str | None = None
|
||||
monitoring_config: ScadaMonitoringSettings | None = None
|
||||
current: ScadaReplaySnapshot | None = None
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user