#!/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})")