[migrate]:[FL-13][迁移防雷计算规程法公式]
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -315,7 +315,7 @@ def execute_job(job_id: str) -> None:
|
||||
latitude=tower.latitude,
|
||||
altitude_m=tower.altitude_m,
|
||||
terrain=tower.terrain,
|
||||
base_tower_json=_build_base_tower_json(tower),
|
||||
base_tower_json=_build_base_tower_json(tower, job.line),
|
||||
profile_json=_build_profile_json(profile),
|
||||
create_date=utcnow(),
|
||||
)
|
||||
@@ -497,11 +497,15 @@ def _mark_job_failed_without_run(db: Session, *, job_id: str, error_message: str
|
||||
)
|
||||
|
||||
|
||||
def _build_base_tower_json(tower: LineTower) -> dict[str, Any]:
|
||||
def _build_base_tower_json(tower: LineTower, line: Line | None) -> dict[str, Any]:
|
||||
return {
|
||||
"tower_id": tower.id,
|
||||
"line_id": tower.line_id,
|
||||
"line_voltage_kv": tower.line.voltage_kv if tower.line else None,
|
||||
"line_name": line.name if line else None,
|
||||
"line_voltage_kv": line.voltage_kv if line else None,
|
||||
"line_phase_sequence_json": (line.phase_sequence_json or {}) if line else {},
|
||||
"line_arrester_install_json": (line.arrester_install_json or {}) if line else {},
|
||||
"line_lightning_param_json": (line.lightning_param_json or {}) if line else {},
|
||||
"seq_no": tower.seq_no,
|
||||
"tower_no": tower.tower_no,
|
||||
"tower_model": tower.tower_model,
|
||||
@@ -552,6 +556,10 @@ def _build_profile_json(profile: TowerProfile | None) -> dict[str, Any]:
|
||||
}
|
||||
|
||||
|
||||
def _grade_snapshot_payload(payload: dict[str, Any]) -> dict[str, Any]:
|
||||
return grade_snapshot_payload(payload)
|
||||
|
||||
|
||||
def _new_result_summary() -> dict[str, Any]:
|
||||
return {
|
||||
"risk_counts": {"high": 0, "medium": 0, "low": 0},
|
||||
@@ -688,6 +696,16 @@ def _resolve_source_run_id(job: FlAnalysisJob) -> str | None:
|
||||
return None
|
||||
|
||||
|
||||
def _as_int(value: Any) -> int | None:
|
||||
parsed = _as_float(value)
|
||||
if parsed is None:
|
||||
return None
|
||||
try:
|
||||
return int(parsed)
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
|
||||
|
||||
def _placeholder_message_for_adapter(adapter: str) -> str:
|
||||
if adapter == "wine":
|
||||
return "Wine 外部程序适配器已预留,真实执行链路尚未接入"
|
||||
|
||||
@@ -1,187 +1,370 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
import pytest
|
||||
|
||||
from app.services.fl_analysis_rules import grade_mitigation_snapshot_payload, grade_snapshot_payload
|
||||
|
||||
|
||||
class FlAnalysisRulesTest(unittest.TestCase):
|
||||
def test_grade_snapshot_payload_marks_high_risk_and_actions(self) -> None:
|
||||
payload = {
|
||||
"base_tower_json": {
|
||||
"tower_no": "T001",
|
||||
"tower_type": "耐张",
|
||||
"ground_resistance_ohm": 35.0,
|
||||
"lightning_density": 6.5,
|
||||
"span_large_m": 620.0,
|
||||
"line_voltage_kv": 110,
|
||||
"slope_1": 18.0,
|
||||
"slope_2": 6.0,
|
||||
"circuit_geometry_json": {
|
||||
"I": {
|
||||
"phase_height_m": {"upper": 28.0, "middle": 24.0, "lower": 20.0},
|
||||
},
|
||||
"lightning_wire": {
|
||||
"left_mid_distance_m": 9.0,
|
||||
"right_mid_distance_m": 9.0,
|
||||
"height_m": 32.0,
|
||||
},
|
||||
def _build_circuit_geometry(
|
||||
*,
|
||||
shield_left_m: float,
|
||||
shield_right_m: float,
|
||||
shield_height_m: float,
|
||||
insulator_length_mm: float,
|
||||
circuit_i_upper_m: float,
|
||||
circuit_i_middle_m: float,
|
||||
circuit_i_lower_m: float,
|
||||
circuit_i_upper_h_m: float,
|
||||
circuit_i_middle_h_m: float,
|
||||
circuit_i_lower_h_m: float,
|
||||
circuit_ii_upper_m: float | None = None,
|
||||
circuit_ii_middle_m: float | None = None,
|
||||
circuit_ii_lower_m: float | None = None,
|
||||
circuit_ii_upper_h_m: float | None = None,
|
||||
circuit_ii_middle_h_m: float | None = None,
|
||||
circuit_ii_lower_h_m: float | None = None,
|
||||
) -> dict[str, object]:
|
||||
return {
|
||||
"I": {
|
||||
"phase_spacing_m": {
|
||||
"upper": circuit_i_upper_m,
|
||||
"middle": circuit_i_middle_m,
|
||||
"lower": circuit_i_lower_m,
|
||||
},
|
||||
"phase_height_m": {
|
||||
"upper": circuit_i_upper_h_m,
|
||||
"middle": circuit_i_middle_h_m,
|
||||
"lower": circuit_i_lower_h_m,
|
||||
},
|
||||
},
|
||||
"II": {
|
||||
"phase_spacing_m": {
|
||||
"upper": circuit_ii_upper_m,
|
||||
"middle": circuit_ii_middle_m,
|
||||
"lower": circuit_ii_lower_m,
|
||||
},
|
||||
"phase_height_m": {
|
||||
"upper": circuit_ii_upper_h_m,
|
||||
"middle": circuit_ii_middle_h_m,
|
||||
"lower": circuit_ii_lower_h_m,
|
||||
},
|
||||
},
|
||||
"lightning_wire": {
|
||||
"left_mid_distance_m": shield_left_m,
|
||||
"right_mid_distance_m": shield_right_m,
|
||||
"height_m": shield_height_m,
|
||||
},
|
||||
"insulator_length_mm": insulator_length_mm,
|
||||
}
|
||||
|
||||
|
||||
def test_grade_snapshot_payload_marks_high_risk_and_actions() -> None:
|
||||
payload = {
|
||||
"base_tower_json": {
|
||||
"tower_no": "T001",
|
||||
"tower_type": "耐张",
|
||||
"ground_resistance_ohm": 35.0,
|
||||
"lightning_density": 6.5,
|
||||
"span_large_m": 620.0,
|
||||
"line_voltage_kv": 110,
|
||||
"slope_1": 18.0,
|
||||
"slope_2": 6.0,
|
||||
"circuit_geometry_json": {
|
||||
"I": {
|
||||
"phase_height_m": {"upper": 28.0, "middle": 24.0, "lower": 20.0},
|
||||
},
|
||||
"lightning_wire": {
|
||||
"left_mid_distance_m": 9.0,
|
||||
"right_mid_distance_m": 9.0,
|
||||
"height_m": 32.0,
|
||||
},
|
||||
},
|
||||
"profile_json": {
|
||||
"structure_kind": "耐张",
|
||||
"stroke_mode": "反击",
|
||||
"arrester_a": "否",
|
||||
"arrester_b": "否",
|
||||
"arrester_c": "否",
|
||||
"insulator_length_m": 1200.0,
|
||||
},
|
||||
}
|
||||
},
|
||||
"profile_json": {
|
||||
"structure_kind": "耐张",
|
||||
"stroke_mode": "反击",
|
||||
"arrester_a": "否",
|
||||
"arrester_b": "否",
|
||||
"arrester_c": "否",
|
||||
"insulator_length_m": 1200.0,
|
||||
},
|
||||
}
|
||||
|
||||
result = grade_snapshot_payload(payload)
|
||||
result = grade_snapshot_payload(payload)
|
||||
|
||||
self.assertEqual(result["risk_level"], "high")
|
||||
self.assertGreaterEqual(result["score"], 80)
|
||||
self.assertIn("接地电阻偏高", result["cause_analysis"])
|
||||
self.assertIn("避雷器", result["mitigation_recommendation"])
|
||||
self.assertTrue(any(item["code"] == "insulator_length" for item in result["reason_details"]))
|
||||
assert result["risk_level"] == "high"
|
||||
assert result["score"] >= 80
|
||||
assert "接地电阻偏高" in result["cause_analysis"]
|
||||
assert "避雷器" in result["mitigation_recommendation"]
|
||||
assert any(item["code"] == "insulator_length" for item in result["reason_details"])
|
||||
|
||||
def test_grade_snapshot_payload_marks_low_risk_when_inputs_are_good(self) -> None:
|
||||
payload = {
|
||||
"base_tower_json": {
|
||||
"tower_no": "T002",
|
||||
"tower_type": "直线",
|
||||
"ground_resistance_ohm": 4.0,
|
||||
"lightning_density": 1.5,
|
||||
"span_large_m": 180.0,
|
||||
"line_voltage_kv": 110,
|
||||
},
|
||||
"profile_json": {
|
||||
"structure_kind": "直线",
|
||||
"stroke_mode": "绕击",
|
||||
"arrester_a": "是",
|
||||
"arrester_b": "是",
|
||||
"arrester_c": "是",
|
||||
"insulator_length_m": 1800.0,
|
||||
},
|
||||
}
|
||||
|
||||
result = grade_snapshot_payload(payload)
|
||||
def test_grade_snapshot_payload_marks_low_risk_when_inputs_are_good() -> None:
|
||||
payload = {
|
||||
"base_tower_json": {
|
||||
"tower_no": "T002",
|
||||
"tower_type": "直线",
|
||||
"ground_resistance_ohm": 4.0,
|
||||
"lightning_density": 1.5,
|
||||
"span_large_m": 180.0,
|
||||
"line_voltage_kv": 110,
|
||||
},
|
||||
"profile_json": {
|
||||
"structure_kind": "直线",
|
||||
"stroke_mode": "绕击",
|
||||
"arrester_a": "是",
|
||||
"arrester_b": "是",
|
||||
"arrester_c": "是",
|
||||
"insulator_length_m": 1800.0,
|
||||
},
|
||||
}
|
||||
|
||||
self.assertEqual(result["risk_level"], "low")
|
||||
self.assertLess(result["score"], 40)
|
||||
self.assertTrue(result["cause_analysis"])
|
||||
self.assertTrue(result["mitigation_recommendation"])
|
||||
result = grade_snapshot_payload(payload)
|
||||
|
||||
def test_grade_mitigation_snapshot_payload_builds_actions_and_reduces_expected_risk(self) -> None:
|
||||
payload = {
|
||||
"base_tower_json": {
|
||||
"tower_no": "T003",
|
||||
"tower_type": "耐张",
|
||||
"ground_resistance_ohm": 28.0,
|
||||
"lightning_density": 5.0,
|
||||
"span_large_m": 420.0,
|
||||
"line_voltage_kv": 220,
|
||||
"slope_1": 12.0,
|
||||
"slope_2": 8.0,
|
||||
"circuit_geometry_json": {
|
||||
"I": {
|
||||
"phase_height_m": {"upper": 36.0, "middle": 32.0, "lower": 28.0},
|
||||
},
|
||||
"lightning_wire": {
|
||||
"left_mid_distance_m": 8.5,
|
||||
"right_mid_distance_m": 8.5,
|
||||
"height_m": 40.0,
|
||||
},
|
||||
assert result["risk_level"] == "low"
|
||||
assert result["score"] < 40
|
||||
assert result["cause_analysis"]
|
||||
assert result["mitigation_recommendation"]
|
||||
|
||||
|
||||
def test_grade_mitigation_snapshot_payload_builds_actions_and_reduces_expected_risk() -> None:
|
||||
payload = {
|
||||
"base_tower_json": {
|
||||
"tower_no": "T003",
|
||||
"tower_type": "耐张",
|
||||
"ground_resistance_ohm": 28.0,
|
||||
"lightning_density": 5.0,
|
||||
"span_large_m": 420.0,
|
||||
"line_voltage_kv": 220,
|
||||
"slope_1": 12.0,
|
||||
"slope_2": 8.0,
|
||||
"circuit_geometry_json": {
|
||||
"I": {
|
||||
"phase_height_m": {"upper": 36.0, "middle": 32.0, "lower": 28.0},
|
||||
},
|
||||
"lightning_wire": {
|
||||
"left_mid_distance_m": 8.5,
|
||||
"right_mid_distance_m": 8.5,
|
||||
"height_m": 40.0,
|
||||
},
|
||||
},
|
||||
"profile_json": {
|
||||
"structure_kind": "耐张",
|
||||
"stroke_mode": "反击",
|
||||
"arrester_a": "否",
|
||||
"arrester_b": "否",
|
||||
"arrester_c": "否",
|
||||
"insulator_length_m": 2000.0,
|
||||
},
|
||||
}
|
||||
},
|
||||
"profile_json": {
|
||||
"structure_kind": "耐张",
|
||||
"stroke_mode": "反击",
|
||||
"arrester_a": "否",
|
||||
"arrester_b": "否",
|
||||
"arrester_c": "否",
|
||||
"insulator_length_m": 2000.0,
|
||||
},
|
||||
}
|
||||
|
||||
result = grade_mitigation_snapshot_payload(payload, non_construction=False)
|
||||
result = grade_mitigation_snapshot_payload(payload, non_construction=False)
|
||||
|
||||
self.assertIn(result["recommendation_result"], {"需要安装避雷器", "不需要安装避雷器"})
|
||||
self.assertTrue(result["mitigation_actions"])
|
||||
self.assertLess(result["expected_score"], result["current_score"])
|
||||
self.assertTrue(any(action["code"] == "grounding_upgrade" for action in result["mitigation_actions"]))
|
||||
assert result["recommendation_result"] in {"需要安装避雷器", "不需要安装避雷器"}
|
||||
assert result["mitigation_actions"]
|
||||
assert result["expected_score"] < result["current_score"]
|
||||
assert any(action["code"] == "grounding_upgrade" for action in result["mitigation_actions"])
|
||||
|
||||
def test_grade_mitigation_snapshot_payload_includes_non_construction_action(self) -> None:
|
||||
payload = {
|
||||
"base_tower_json": {
|
||||
"tower_no": "T004",
|
||||
"tower_model": "s220guxing",
|
||||
"tower_type": "直线",
|
||||
"ground_resistance_ohm": 16.0,
|
||||
"lightning_density": 3.5,
|
||||
"span_large_m": 260.0,
|
||||
"line_voltage_kv": 220,
|
||||
"circuit_geometry_json": {
|
||||
"I": {
|
||||
"phase_height_m": {"upper": 30.0, "middle": 26.0, "lower": 22.0},
|
||||
},
|
||||
"lightning_wire": {
|
||||
"left_mid_distance_m": 10.0,
|
||||
"right_mid_distance_m": 10.0,
|
||||
"height_m": 33.0,
|
||||
},
|
||||
|
||||
def test_grade_mitigation_snapshot_payload_includes_non_construction_action() -> None:
|
||||
payload = {
|
||||
"base_tower_json": {
|
||||
"tower_no": "T004",
|
||||
"tower_model": "s220guxing",
|
||||
"tower_type": "直线",
|
||||
"ground_resistance_ohm": 16.0,
|
||||
"lightning_density": 3.5,
|
||||
"span_large_m": 260.0,
|
||||
"line_voltage_kv": 220,
|
||||
"circuit_geometry_json": {
|
||||
"I": {
|
||||
"phase_height_m": {"upper": 30.0, "middle": 26.0, "lower": 22.0},
|
||||
},
|
||||
"lightning_wire": {
|
||||
"left_mid_distance_m": 10.0,
|
||||
"right_mid_distance_m": 10.0,
|
||||
"height_m": 33.0,
|
||||
},
|
||||
},
|
||||
"profile_json": {
|
||||
"structure_kind": "直线",
|
||||
"stroke_mode": "绕击",
|
||||
"arrester_a": "是",
|
||||
"arrester_b": "是",
|
||||
"arrester_c": "是",
|
||||
"insulator_length_m": 2500.0,
|
||||
},
|
||||
"profile_json": {
|
||||
"structure_kind": "直线",
|
||||
"stroke_mode": "绕击",
|
||||
"arrester_a": "是",
|
||||
"arrester_b": "是",
|
||||
"arrester_c": "是",
|
||||
"insulator_length_m": 2500.0,
|
||||
},
|
||||
}
|
||||
|
||||
result = grade_mitigation_snapshot_payload(payload, non_construction=True)
|
||||
|
||||
assert result["non_construction"] is True
|
||||
assert any(action["code"] == "shielding_geometry" for action in result["mitigation_actions"])
|
||||
|
||||
|
||||
def test_grade_mitigation_snapshot_payload_prefers_source_risk_result() -> None:
|
||||
payload = {
|
||||
"base_tower_json": {
|
||||
"tower_no": "T005",
|
||||
"tower_type": "直线",
|
||||
"ground_resistance_ohm": 4.0,
|
||||
"lightning_density": 1.5,
|
||||
"span_large_m": 180.0,
|
||||
"line_voltage_kv": 110,
|
||||
},
|
||||
"profile_json": {
|
||||
"structure_kind": "直线",
|
||||
"stroke_mode": "绕击",
|
||||
"arrester_a": "是",
|
||||
"arrester_b": "是",
|
||||
"arrester_c": "是",
|
||||
"insulator_length_m": 1800.0,
|
||||
},
|
||||
"source_result_json": {
|
||||
"risk_level": "high",
|
||||
"score": 92,
|
||||
"cause_analysis": "沿用前驱风险结果",
|
||||
"reason_details": [{"code": "source_reason", "label": "前驱原因"}],
|
||||
"inputs": {"ground_resistance_ohm": 35.0},
|
||||
},
|
||||
}
|
||||
|
||||
result = grade_mitigation_snapshot_payload(payload, non_construction=False)
|
||||
|
||||
assert result["current_risk_level"] == "high"
|
||||
assert result["current_score"] == 92
|
||||
assert result["cause_analysis"] == "沿用前驱风险结果"
|
||||
assert result["reason_details"][0]["code"] == "source_reason"
|
||||
|
||||
|
||||
def test_grade_snapshot_payload_uses_source_formula_and_converts_mm_to_m() -> None:
|
||||
geometry = _build_circuit_geometry(
|
||||
shield_left_m=12.4,
|
||||
shield_right_m=15.9,
|
||||
shield_height_m=73.5,
|
||||
insulator_length_mm=5945.0,
|
||||
circuit_i_upper_m=14.5,
|
||||
circuit_i_middle_m=10.5,
|
||||
circuit_i_lower_m=12.0,
|
||||
circuit_i_upper_h_m=53.0,
|
||||
circuit_i_middle_h_m=65.5,
|
||||
circuit_i_lower_h_m=42.0,
|
||||
circuit_ii_upper_m=14.5,
|
||||
circuit_ii_middle_m=10.5,
|
||||
circuit_ii_lower_m=12.0,
|
||||
circuit_ii_upper_h_m=53.0,
|
||||
circuit_ii_middle_h_m=65.5,
|
||||
circuit_ii_lower_h_m=42.0,
|
||||
)
|
||||
payload = {
|
||||
"base_tower_json": {
|
||||
"tower_no": "P1",
|
||||
"tower_type": "耐张",
|
||||
"tower_model": "500-MC31S-DJC2-42",
|
||||
"line_name": "交流500kV雁船线(双回段)",
|
||||
"line_voltage_kv": 500,
|
||||
"ground_resistance_ohm": 20.0,
|
||||
"lightning_density": 5.42528304182587,
|
||||
"slope_1": -5.70339674677262,
|
||||
"slope_2": -1.42923539492821,
|
||||
"circuit_geometry_json": geometry,
|
||||
"lightning_result_json": {},
|
||||
},
|
||||
"profile_json": {
|
||||
"structure_kind": "耐张",
|
||||
"arrester_a": "否",
|
||||
"arrester_b": "否",
|
||||
"arrester_c": "否",
|
||||
"shield_wire_height_m": 73.5,
|
||||
"insulator_length_m": 5945.0,
|
||||
"current_a": 25.109,
|
||||
"current_b": 3.62,
|
||||
},
|
||||
}
|
||||
|
||||
result = grade_snapshot_payload(payload)
|
||||
|
||||
assert result["risk_level"] == "high"
|
||||
assert result["risk_grade"] == 3
|
||||
assert result["inputs"]["insulator_length_m"] == pytest.approx(5.945, abs=1e-6)
|
||||
assert result["counterstrike_withstand_ka"] == pytest.approx(75.8070, rel=1e-4)
|
||||
assert result["counterstrike_trip_rate"] == pytest.approx(0.529876, rel=1e-4)
|
||||
assert result["shielding_withstand_ka"] == pytest.approx(31.2860, rel=1e-4)
|
||||
assert result["shielding_trip_rate"] == pytest.approx(0.000003, abs=1e-6)
|
||||
assert "接地电阻" in result["cause_analysis"]
|
||||
assert "规程法等级 3" in result["summary_text"]
|
||||
|
||||
|
||||
def test_grade_snapshot_payload_marks_low_risk_for_good_inputs() -> None:
|
||||
geometry = _build_circuit_geometry(
|
||||
shield_left_m=8.0,
|
||||
shield_right_m=8.0,
|
||||
shield_height_m=40.0,
|
||||
insulator_length_mm=3500.0,
|
||||
circuit_i_upper_m=10.0,
|
||||
circuit_i_middle_m=3.0,
|
||||
circuit_i_lower_m=8.0,
|
||||
circuit_i_upper_h_m=28.0,
|
||||
circuit_i_middle_h_m=31.0,
|
||||
circuit_i_lower_h_m=24.0,
|
||||
)
|
||||
payload = {
|
||||
"base_tower_json": {
|
||||
"tower_no": "L1",
|
||||
"tower_type": "直线",
|
||||
"tower_model": "220-TEST-ZX",
|
||||
"line_name": "交流220kV示例线",
|
||||
"line_voltage_kv": 220,
|
||||
"ground_resistance_ohm": 5.0,
|
||||
"lightning_density": 1.2,
|
||||
"slope_1": 0.0,
|
||||
"slope_2": 0.0,
|
||||
"circuit_geometry_json": geometry,
|
||||
"lightning_result_json": {},
|
||||
},
|
||||
"profile_json": {
|
||||
"structure_kind": "直线",
|
||||
"arrester_a": "是",
|
||||
"arrester_b": "是",
|
||||
"arrester_c": "是",
|
||||
"shield_wire_height_m": 40.0,
|
||||
"insulator_length_m": 3500.0,
|
||||
"current_a": 31.0,
|
||||
"current_b": 2.6,
|
||||
},
|
||||
}
|
||||
|
||||
result = grade_snapshot_payload(payload)
|
||||
|
||||
assert result["risk_level"] == "low"
|
||||
assert result["risk_grade"] == 1
|
||||
assert result["score"] < 30
|
||||
assert result["counterstrike_trip_rate"] == pytest.approx(0.109404, rel=1e-4)
|
||||
assert result["shielding_trip_rate"] == pytest.approx(0.006737, rel=1e-4)
|
||||
assert "高风险" not in result["summary_text"]
|
||||
|
||||
|
||||
def test_grade_snapshot_payload_falls_back_to_legacy_result_when_geometry_is_missing() -> None:
|
||||
payload = {
|
||||
"base_tower_json": {
|
||||
"tower_no": "F1",
|
||||
"lightning_result_json": {
|
||||
"counterstroke_withstand_ka": 52.3,
|
||||
"counterstroke_trip_rate": 0.12,
|
||||
"shielding_withstand_ka": 18.6,
|
||||
"shielding_trip_rate": 0.03,
|
||||
"risk_level": 2,
|
||||
},
|
||||
}
|
||||
},
|
||||
"profile_json": {},
|
||||
}
|
||||
|
||||
result = grade_mitigation_snapshot_payload(payload, non_construction=True)
|
||||
result = grade_snapshot_payload(payload)
|
||||
|
||||
self.assertTrue(result["non_construction"])
|
||||
self.assertTrue(any(action["code"] == "shielding_geometry" for action in result["mitigation_actions"]))
|
||||
|
||||
def test_grade_mitigation_snapshot_payload_prefers_source_risk_result(self) -> None:
|
||||
payload = {
|
||||
"base_tower_json": {
|
||||
"tower_no": "T005",
|
||||
"tower_type": "直线",
|
||||
"ground_resistance_ohm": 4.0,
|
||||
"lightning_density": 1.5,
|
||||
"span_large_m": 180.0,
|
||||
"line_voltage_kv": 110,
|
||||
},
|
||||
"profile_json": {
|
||||
"structure_kind": "直线",
|
||||
"stroke_mode": "绕击",
|
||||
"arrester_a": "是",
|
||||
"arrester_b": "是",
|
||||
"arrester_c": "是",
|
||||
"insulator_length_m": 1800.0,
|
||||
},
|
||||
"source_result_json": {
|
||||
"risk_level": "high",
|
||||
"score": 92,
|
||||
"cause_analysis": "沿用前驱风险结果",
|
||||
"reason_details": [{"code": "source_reason", "label": "前驱原因"}],
|
||||
"inputs": {"ground_resistance_ohm": 35.0},
|
||||
},
|
||||
}
|
||||
|
||||
result = grade_mitigation_snapshot_payload(payload, non_construction=False)
|
||||
|
||||
self.assertEqual(result["current_risk_level"], "high")
|
||||
self.assertEqual(result["current_score"], 92)
|
||||
self.assertEqual(result["cause_analysis"], "沿用前驱风险结果")
|
||||
self.assertEqual(result["reason_details"][0]["code"], "source_reason")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
assert result["used_legacy_fallback"] is True
|
||||
assert result["risk_level"] == "medium"
|
||||
assert result["counterstrike_withstand_ka"] == pytest.approx(52.3)
|
||||
assert result["shielding_trip_rate"] == pytest.approx(0.03)
|
||||
assert "历史结果" in result["cause_analysis"]
|
||||
|
||||
Reference in New Issue
Block a user