Grafana dashboard flexibilite/agregation
This commit is contained in:
123
scripts/simulation_setup.py
Normal file
123
scripts/simulation_setup.py
Normal file
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Cariflex - Crée les sensors et injecte données météo/prix."""
|
||||
|
||||
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'<input[^>]*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'}")
|
||||
|
||||
RESOLUTION = "PT1H"
|
||||
|
||||
print("\n=== Création des sensors ===")
|
||||
sensors_to_create = [
|
||||
{"name": "irradiance", "unit": "W/m²", "generic_asset_id": 81, "event_resolution": RESOLUTION},
|
||||
{"name": "temperature", "unit": "°C", "generic_asset_id": 81, "event_resolution": RESOLUTION},
|
||||
{"name": "wind_speed", "unit": "m/s", "generic_asset_id": 81, "event_resolution": RESOLUTION},
|
||||
{"name": "consumption_price", "unit": "EUR/MWh", "generic_asset_id": 82, "event_resolution": RESOLUTION},
|
||||
{"name": "production_price", "unit": "EUR/MWh", "generic_asset_id": 82, "event_resolution": RESOLUTION},
|
||||
]
|
||||
|
||||
created_sensors = {}
|
||||
for s in sensors_to_create:
|
||||
r = session.post(f"{FM_HOST}/api/v3_0/sensors", json=s)
|
||||
if r.status_code == 201:
|
||||
sid = r.json().get("id")
|
||||
created_sensors[s["name"]] = sid
|
||||
print(f" ✓ Sensor '{s['name']}' (ID {sid})")
|
||||
|
||||
if not created_sensors:
|
||||
# Find existing sensors
|
||||
r = session.get(f"{FM_HOST}/api/v3_0/sensors")
|
||||
for s in r.json():
|
||||
if s["name"] in ["irradiance", "temperature", "wind_speed", "consumption_price", "production_price"]:
|
||||
created_sensors[s["name"]] = s["id"]
|
||||
print(f" Found sensor '{s['name']}' (ID {s['id']})")
|
||||
|
||||
print(f"\nSensors: {created_sensors}")
|
||||
|
||||
# Inject weather data from Open-Meteo
|
||||
print("\n=== Données météo réelles ===")
|
||||
LAT, LON = 14.6091, -61.2155
|
||||
today = datetime.now(MARTINIQUE_TZ).strftime("%Y-%m-%d")
|
||||
|
||||
try:
|
||||
resp = requests.get(
|
||||
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}",
|
||||
timeout=15
|
||||
)
|
||||
if resp.status_code == 200:
|
||||
wdata = resp.json()
|
||||
times = wdata["hourly"]["time"]
|
||||
|
||||
for sensor_name, (key, unit) in {
|
||||
"irradiance": ("shortwave_radiation", "W/m²"),
|
||||
"temperature": ("temperature_2m", "°C"),
|
||||
"wind_speed": ("wind_speed_10m", "m/s")
|
||||
}.items():
|
||||
if sensor_name not in created_sensors:
|
||||
continue
|
||||
sensor_id = created_sensors[sensor_name]
|
||||
values = wdata["hourly"][key]
|
||||
posted = 0
|
||||
for i, t in enumerate(times):
|
||||
dt = datetime.fromisoformat(t)
|
||||
r = session.post(f"{FM_HOST}/api/v3_0/sensors/{sensor_id}/data",
|
||||
json={"values": [round(max(0, values[i]), 1)], "start": dt.isoformat(), "duration": RESOLUTION, "unit": unit},
|
||||
timeout=30)
|
||||
if r.status_code in [200, 201, 202]:
|
||||
posted += 1
|
||||
print(f" '{sensor_name}': {posted}/{len(times)} posted")
|
||||
else:
|
||||
print(f" API error: {resp.status_code}")
|
||||
except Exception as e:
|
||||
print(f" Error: {e}")
|
||||
|
||||
# Inject DSO prices (24h)
|
||||
print("\n=== Prix DSO ===")
|
||||
if "consumption_price" in created_sensors and "production_price" in created_sensors:
|
||||
c_id = created_sensors["consumption_price"]
|
||||
p_id = created_sensors["production_price"]
|
||||
now_utc = datetime.now(timezone.utc)
|
||||
posted = 0
|
||||
for h in range(24):
|
||||
dt = now_utc - timedelta(hours=23-h)
|
||||
hd = dt.hour
|
||||
cp = round(random.uniform(80, 150) if 6 <= hd <= 22 else random.uniform(40, 80), 2)
|
||||
pp = round(random.uniform(60, 120) if 6 <= hd <= 22 else random.uniform(30, 60), 2)
|
||||
for sid, price in [(c_id, cp), (p_id, pp)]:
|
||||
r = session.post(f"{FM_HOST}/api/v3_0/sensors/{sid}/data",
|
||||
json={"values": [price], "start": dt.isoformat(), "duration": RESOLUTION, "unit": "EUR/MWh"}, timeout=30)
|
||||
if r.status_code in [200, 201, 202]:
|
||||
posted += 1
|
||||
print(f" Prix injectés: {posted}")
|
||||
|
||||
print("\n=== Terminé ===")
|
||||
Reference in New Issue
Block a user