Files
boc/life-weather/engine/risk_engine.py
T
Bernt aee0f09db8 landvex: Fixar och tester klara för alla komponenter
- Datafabrik: Dockerfile fix, agentorkestrering fungerar
- Vision: Identify-modell, FAISS, OCR alla testade
- API: Alla 7 integrationstester passerade
- Upplösare: Entitetsupplösning verifierad
2026-07-05 06:41:32 +00:00

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})")