Files
turf_saas/weather_module.py
2026-04-25 17:18:43 +02:00

171 lines
5.2 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Weather Module - Open-Meteo API Integration
Adds weather context for horse racing analysis
"""
import requests
from datetime import datetime
# Hippodrome coordinates (France)
HIPPODROMES = {
'auteuil': (48.8718, 2.2525),
' Chantilly': (49.1939, 2.4744),
'deauville': (49.3563, 0.0775),
'vincennes': (48.8414, 2.4375),
'longchamp': (48.8641, 2.2372),
'saint-cloud': (48.8419, 2.1039),
'pau': (43.2917, -0.3708),
'cagnes-sur-mer': (43.6689, 7.1914),
'lyon-parilly': (45.7378, 4.8092),
'marseille': (43.2964, 5.3695),
}
def get_weather(hippodrome, date=None):
"""
Get weather for hippodrome from Open-Meteo API (FREE!)
Args:
hippodrome: Name of hippodrome
date: Optional date (YYYY-MM-DD), defaults to today
Returns:
dict: Weather data
"""
if hippodrome.lower() not in HIPPODROMES:
return {'error': f'Hippodrome not found: {hippodrome}'}
lat, lon = HIPPODROMES[hippodrome.lower()]
# Open-Meteo API (free, no key needed)
url = f"https://api.open-meteo.com/v1/forecast"
params = {
'latitude': lat,
'longitude': lon,
'current': 'temperature_2m,relative_humidity_2m,precipitation,rain,weather_code,wind_speed_10m,wind_direction_10m',
'timezone': 'Europe/Paris'
}
if date:
# Historical data
url = f"https://archive-api.open-meteo.com/v1/archive"
params['start_date'] = date
params['end_date'] = date
try:
r = requests.get(url, params=params, timeout=10)
data = r.json()
if 'current' in data:
current = data['current']
return {
'hippodrome': hippodrome,
'temperature': current.get('temperature_2m'),
'humidity': current.get('relative_humidity_2m'),
'precipitation': current.get('precipitation'),
'rain': current.get('rain'),
'weather_code': current.get('weather_code'),
'wind_speed': current.get('wind_speed_10m'),
'wind_direction': current.get('wind_direction_10m'),
'timestamp': datetime.now().isoformat()
}
elif 'daily' in data:
return {
'hippodrome': hippodrome,
'date': date,
'temperature_max': data['daily'].get('temperature_2m_max', [None])[0],
'temperature_min': data['daily'].get('temperature_2m_min', [None])[0],
'precipitation_sum': data['daily'].get('precipitation_sum', [None])[0],
'rain_sum': data['daily'].get('rain_sum', [None])[0],
'wind_speed_max': data['daily'].get('wind_speed_10m_max', [None])[0],
}
except Exception as e:
return {'error': str(e)}
def weather_code_to_desc(code):
"""Convert weather code to description"""
codes = {
0: "Ciel dégagé",
1: "Mainly clear",
2: "Partly cloudy",
3: "Overcast",
45: "Brouillard",
48: "Fog",
51: "Bruine légère",
53: "Bruine modérée",
55: "Bruine dense",
61: "Pluie légère",
63: "Pluie modérée",
65: "Pluie forte",
71: "Neige légère",
73: "Neige modérée",
75: "Neige forte",
80: "Averses légères",
81: "Averses modérées",
82: "Averses fortes",
95: "Orage",
}
return codes.get(code, f"Code {code}")
def get_ground_condition(weather_data):
"""
Determine ground condition based on weather
Returns: BON, SOUPLE, LOURD, TERRE PERTURBÉE, etc.
"""
if 'error' in weather_data:
return 'INCONNU'
precip = weather_data.get('precipitation', 0)
rain = weather_data.get('rain', 0)
humidity = weather_data.get('humidity', 0)
# Simple logic for turf conditions
if precip > 10 or rain > 5:
return 'LOURD'
elif precip > 5 or rain > 2:
return 'SOUPLE'
elif precip > 1:
return 'BON'
else:
return 'BON'
def analyze_weather_impact(weather_data, horse_history):
"""
Analyze how horse performs in current weather
Args:
weather_data: Current weather conditions
horse_history: List of past performances with weather
Returns:
dict: Weather impact analysis
"""
analysis = {
'ground_condition': get_ground_condition(weather_data),
'recommendation': 'NEUTRAL'
}
# Check ground preference based on history
# This would need historical data to be implemented
return analysis
# Example usage
if __name__ == "__main__":
# Test
print("="*50)
print("Weather Module - Test")
print("="*50)
for hippo in ['Auteuil', 'Vincennes', 'Pau']:
print(f"\n{hippo}:")
w = get_weather(hippo)
if 'error' not in w:
print(f" Temp: {w.get('temperature')}°C")
print(f" Humidity: {w.get('humidity')}%")
print(f" Wind: {w.get('wind_speed')} km/h")
print(f" Ground: {get_ground_condition(w)}")
else:
print(f" Error: {w.get('error')}")