#!/usr/bin/env python3 """Cariflex - Injecte les données météo réelles et prix DSO simulés.""" import json import requests import re import warnings import random from datetime import datetime, timezone, timedelta import pytz warnings.filterwarnings("ignore") FM_HOST = "https://cariflex.digitribe.fr" CREDS_FILE = "/tmp/fm_creds.json" MARTINIQUE_TZ = pytz.timezone("America/Martinique") with open(CREDS_FILE) as f: creds = json.load(f) session = requests.Session() session.verify = False # Login r = session.get(f"{FM_HOST}/login") match = re.search(r']*csrf_token[^>]*value="([^"]+)"', r.text) csrf = match.group(1) r = session.post(f"{FM_HOST}/login", data={ "email": creds["email"], "password": creds["password"], "csrf_token": csrf, "remember": "y" }, allow_redirects=True) print(f"Login: {'OK' if 'dashboard' in r.url else 'FAILED'}") # Get existing sensors r = session.get(f"{FM_HOST}/api/v3_0/sensors") sensors = {} if r.status_code == 200: for s in r.json(): sensors[s["name"]] = s["id"] print(f" Sensor: {s['id']} - {s['name']} (asset {s.get('generic_asset_id', '?')})") # ======================================== # 1. Injecter les prévisions météo réelles # ======================================== print("\n=== Injection des données météo ===") LAT, LON = 14.6091, -61.2155 now_local = datetime.now(MARTINIQUE_TZ) today = now_local.strftime("%Y-%m-%d") url = ( f"https://api.open-meteo.com/v1/forecast?" f"latitude={LAT}&longitude={LON}" f"&hourly=shortwave_radiation,temperature_2m,wind_speed_10m" f"&timezone=America/Martinique" f"&start_date={today}&end_date={today}" ) try: resp = requests.get(url, timeout=15) if resp.status_code == 200: wdata = resp.json() hourly = wdata["hourly"] times = hourly["time"] irradiance = hourly["shortwave_radiation"] temperature = hourly["temperature_2m"] wind_speed = hourly["wind_speed_10m"] print(f" Données météo récupérées: {len(times)} heures") # Map sensor names to data sensor_data_map = { "irradiance": (irradiance, "W/m²"), "temperature": (temperature, "°C"), "wind_speed": (wind_speed, "m/s"), } for sensor_name, (data, unit) in sensor_data_map.items(): if sensor_name not in sensors: print(f" Sensor '{sensor_name}' non trouvé, ignoré") continue sensor_id = sensors[sensor_name] posted = 0 for i, t in enumerate(times): dt = datetime.fromisoformat(t) value = max(0, data[i]) if data[i] is not None else 0 r = session.post( f"{FM_HOST}/api/v3_0/sensors/{sensor_id}/data", json={ "values": [round(value, 1)], "start": dt.isoformat(), "duration": "PT1H", "unit": unit }, timeout=30 ) if r.status_code in [200, 201, 202]: posted += 1 print(f" Sensor '{sensor_name}' (ID {sensor_id}): {posted}/{len(times)} values posted") else: print(f" Erreur API météo: HTTP {resp.status_code}") except Exception as e: print(f" Erreur récupération météo: {e}") # ======================================== # 2. Injecter les prix DSO simulés # ======================================== print("\n=== Injection des prix DSO ===") if "consumption_price" in sensors and "production_price" in sensors: consumption_price_id = sensors["consumption_price"] production_price_id = sensors["production_price"] now_utc = datetime.now(timezone.utc) posted = 0 for hour in range(24): dt = now_utc - timedelta(hours=23-hour) hour_of_day = dt.hour # Price pattern: peak during day, lower at night if 6 <= hour_of_day <= 22: consumption_price = round(random.uniform(80, 150), 2) production_price = round(random.uniform(60, 120), 2) else: consumption_price = round(random.uniform(40, 80), 2) production_price = round(random.uniform(30, 60), 2) # Post consumption price r = session.post( f"{FM_HOST}/api/v3_0/sensors/{consumption_price_id}/data", json={ "values": [consumption_price], "start": dt.isoformat(), "duration": "PT1H", "unit": "EUR/MWh" }, timeout=30 ) if r.status_code in [200, 201, 202]: posted += 1 # Post production price r = session.post( f"{FM_HOST}/api/v3_0/sensors/{production_price_id}/data", json={ "values": [production_price], "start": dt.isoformat(), "duration": "PT1H", "unit": "EUR/MWh" }, timeout=30 ) if r.status_code in [200, 201, 202]: posted += 1 print(f" Prix DSO injectés: {posted} values") else: print(" Sensors de prix non trouvés") print("\n=== Injection terminée ===")