feat(scada): add calibrated monitoring and incident recovery

This commit is contained in:
2026-11-07 19:44:58 +08:00
parent 26fa5d1909
commit ff8aba4964
109 changed files with 9165 additions and 629 deletions
+21 -1
View File
@@ -1,19 +1,39 @@
from math import isclose
from typing import Literal
from pydantic import BaseModel, ConfigDict, Field, JsonValue, model_validator
class ScadaMonitoringWeights(BaseModel):
model_config = ConfigDict(extra="forbid", allow_inf_nan=False)
burst_detection: float = Field(default=0.5, ge=0, le=1)
pressure: float = Field(default=0.4, ge=0, le=1)
outlet_flow: float = Field(default=0.1, ge=0, le=1)
@model_validator(mode="after")
def normalized(self):
if not isclose(self.burst_detection + self.pressure + self.outlet_flow, 1.0, abs_tol=1e-9):
raise ValueError("SCADA 三项监测权重之和必须为 1")
return self
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",
default="burst-monitor-v2",
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)
decision_policy: Literal["all_signals", "weighted"] = "weighted"
weights: ScadaMonitoringWeights = Field(default_factory=ScadaMonitoringWeights)
alert_threshold: float = Field(default=0.8, gt=0, le=1)
@model_validator(mode="after")
def distinct_roles(self):