aee0f09db8
- Datafabrik: Dockerfile fix, agentorkestrering fungerar - Vision: Identify-modell, FAISS, OCR alla testade - API: Alla 7 integrationstester passerade - Upplösare: Entitetsupplösning verifierad
163 lines
5.3 KiB
Python
163 lines
5.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
RiskEngine - Regelbaserad riskanalys
|
|
"""
|
|
from dataclasses import dataclass
|
|
from typing import List, Optional
|
|
|
|
@dataclass
|
|
class RiskScore:
|
|
road_id: int
|
|
road_type: str
|
|
risk_type: str
|
|
severity: str # low, medium, high, critical
|
|
score: float # 0.0 - 1.0
|
|
description: str
|
|
factors: List[str]
|
|
|
|
class RiskEngine:
|
|
def __init__(self):
|
|
self.rules = [
|
|
self._ice_rule,
|
|
self._flooding_rule,
|
|
self._wind_rule,
|
|
self._heat_rule
|
|
]
|
|
|
|
def _ice_rule(self, road_type, temperature, precipitation, wind):
|
|
"""Isrisk: Temp < 0 + nederbörd"""
|
|
if temperature is None:
|
|
return None
|
|
|
|
if temperature < -5:
|
|
return RiskScore(
|
|
road_id=0, road_type=road_type,
|
|
risk_type="ice",
|
|
severity="critical",
|
|
score=0.9,
|
|
description="Mycket kallt, hög risk för is",
|
|
factors=[f"temp={temperature}°C"]
|
|
)
|
|
elif temperature < 0:
|
|
if precipitation and precipitation > 0:
|
|
return RiskScore(
|
|
road_id=0, road_type=road_type,
|
|
risk_type="black_ice",
|
|
severity="critical",
|
|
score=0.95,
|
|
description="Svartisrisk vid nederbörd och minusgrader",
|
|
factors=[f"temp={temperature}°C", f"precip={precipitation}mm"]
|
|
)
|
|
return RiskScore(
|
|
road_id=0, road_type=road_type,
|
|
risk_type="ice",
|
|
severity="high",
|
|
score=0.7,
|
|
description="Risk för isbildning",
|
|
factors=[f"temp={temperature}°C"]
|
|
)
|
|
return None
|
|
|
|
def _flooding_rule(self, road_type, temperature, precipitation, wind):
|
|
"""Översvämningsrisk: Kraftigt regn"""
|
|
if precipitation is None:
|
|
return None
|
|
|
|
if precipitation > 20:
|
|
return RiskScore(
|
|
road_id=0, road_type=road_type,
|
|
risk_type="flooding",
|
|
severity="critical",
|
|
score=0.9,
|
|
description="Kraftig nederbörd, översvämningsrisk",
|
|
factors=[f"precip={precipitation}mm"]
|
|
)
|
|
elif precipitation > 10:
|
|
return RiskScore(
|
|
road_id=0, road_type=road_type,
|
|
risk_type="flooding",
|
|
severity="high",
|
|
score=0.7,
|
|
description="Hög nederbörd, risk för vatten på vägbanan",
|
|
factors=[f"precip={precipitation}mm"]
|
|
)
|
|
elif precipitation > 5:
|
|
return RiskScore(
|
|
road_id=0, road_type=road_type,
|
|
risk_type="wet_road",
|
|
severity="medium",
|
|
score=0.4,
|
|
description="Blöt vägbana",
|
|
factors=[f"precip={precipitation}mm"]
|
|
)
|
|
return None
|
|
|
|
def _wind_rule(self, road_type, temperature, precipitation, wind):
|
|
"""Vindrisk: Kraftig vind"""
|
|
if wind is None:
|
|
return None
|
|
|
|
if wind > 20:
|
|
return RiskScore(
|
|
road_id=0, road_type=road_type,
|
|
risk_type="falling_objects",
|
|
severity="high",
|
|
score=0.8,
|
|
description="Kraftig vind, risk för nedfallande föremål",
|
|
factors=[f"wind={wind}m/s"]
|
|
)
|
|
elif wind > 15:
|
|
return RiskScore(
|
|
road_id=0, road_type=road_type,
|
|
risk_type="strong_wind",
|
|
severity="medium",
|
|
score=0.5,
|
|
description="Stark vind",
|
|
factors=[f"wind={wind}m/s"]
|
|
)
|
|
return None
|
|
|
|
def _heat_rule(self, road_type, temperature, precipitation, wind):
|
|
"""Värmerisk: Extrem värme"""
|
|
if temperature is None:
|
|
return None
|
|
|
|
if temperature > 30:
|
|
return RiskScore(
|
|
road_id=0, road_type=road_type,
|
|
risk_type="asphalt_stress",
|
|
severity="medium",
|
|
score=0.5,
|
|
description="Extrem värme, risk för asfaltpåfrestning",
|
|
factors=[f"temp={temperature}°C"]
|
|
)
|
|
return None
|
|
|
|
def calculate_risk(self, road_id, road_type, temperature=None, precipitation=None, wind=None):
|
|
"""Beräkna risk för en väg"""
|
|
risks = []
|
|
|
|
for rule in self.rules:
|
|
risk = rule(road_type, temperature, precipitation, wind)
|
|
if risk:
|
|
risk.road_id = road_id
|
|
risks.append(risk)
|
|
|
|
return risks
|
|
|
|
if __name__ == "__main__":
|
|
engine = RiskEngine()
|
|
|
|
# Testa med olika scenarion
|
|
tests = [
|
|
(1, "primary", -5, 0, 5, "Vinter"),
|
|
(2, "secondary", 2, 15, 10, "Regn + kallt"),
|
|
(3, "primary", 22, 3, 5, "Sommar"),
|
|
]
|
|
|
|
for road_id, road_type, temp, precip, wind, name in tests:
|
|
risks = engine.calculate_risk(road_id, road_type, temp, precip, wind)
|
|
print(f"\n{name}:")
|
|
for risk in risks:
|
|
print(f" {risk.risk_type}: {risk.severity} (score: {risk.score})")
|