This commit is contained in:
Jonas Bengtsson
2026-10-07 17:57:30 +02:00
parent 2aa040e757
commit 76b1cc5ccf
9 changed files with 538 additions and 478 deletions
+12 -1
View File
@@ -66,6 +66,13 @@ class StaleConfig:
max_age_s: float = 120.0 # D12 / D13
@dataclass(frozen=True)
class BrowseConfig:
# Address-space walk guard: deeper SCADA trees are fine, but a walk this
# deep is almost certainly a server-side cycle (list-items --depth 0).
max_depth: int = 32
@dataclass(frozen=True)
class JsonlConfig:
dir: str = "C:/ProgramData/OPCDA-Diagnozer/logs"
@@ -96,10 +103,11 @@ class Config:
latency: LatencyConfig = field(default_factory=LatencyConfig)
quality: QualityConfig = field(default_factory=QualityConfig)
stale: StaleConfig = field(default_factory=StaleConfig)
browse: BrowseConfig = field(default_factory=BrowseConfig)
report: ReportConfig = field(default_factory=ReportConfig)
_ALLOWED_TOP_LEVEL = {"opc", "poll", "tags", "latency", "quality", "stale", "report"}
_ALLOWED_TOP_LEVEL = {"opc", "poll", "tags", "latency", "quality", "stale", "browse", "report"}
_TAG_KEYS = {"name", "expect_change"}
@@ -207,6 +215,8 @@ def _validate(config: Config) -> None:
raise ConfigError(f"quality.flapping_window_s: must be > 0, got {config.quality.flapping_window_s}")
if config.stale.enabled and config.stale.max_age_s <= 0:
raise ConfigError(f"stale.max_age_s: must be > 0, got {config.stale.max_age_s}")
if config.browse.max_depth < 1:
raise ConfigError(f"browse.max_depth: must be >= 1, got {config.browse.max_depth}")
if config.report.heartbeat_s <= 0:
raise ConfigError(f"report.heartbeat_s: must be > 0, got {config.report.heartbeat_s}")
if config.report.eventlog.min_severity not in ("INFO", "WARN", "CRITICAL"):
@@ -246,6 +256,7 @@ def load_config(path: str | Path) -> Config:
latency=_build_section(LatencyConfig, data.get("latency"), "latency"),
quality=_build_section(QualityConfig, data.get("quality"), "quality"),
stale=_build_section(StaleConfig, data.get("stale"), "stale"),
browse=_build_section(BrowseConfig, data.get("browse"), "browse"),
report=_build_report(data.get("report")),
)
try: