Grafana dashboard flexibilite/agregation
This commit is contained in:
132
scripts/inject_final.py
Normal file
132
scripts/inject_final.py
Normal file
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Cariflex - Injecte les données météo réelles et prix DSO dans FM via le CLI."""
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import random
|
||||
import math
|
||||
from datetime import datetime, timezone, timedelta
|
||||
import pytz
|
||||
import requests
|
||||
|
||||
MARTINIQUE_TZ = pytz.timezone("America/Martinique")
|
||||
|
||||
# Sensor IDs (from previous creation)
|
||||
SENSORS = {
|
||||
"irradiance": 81,
|
||||
"temperature": 82,
|
||||
"wind_speed": 83,
|
||||
"consumption_price": 84,
|
||||
"production_price": 85,
|
||||
}
|
||||
|
||||
def run_fm_cli(args):
|
||||
"""Run FM CLI inside the container."""
|
||||
cmd = ["docker", "exec", "flexmeasures-server", "bash", "-c",
|
||||
f"cd /app && .venv/bin/flexmeasures {' '.join(args)}"]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
|
||||
return result.stdout.strip(), result.stderr.strip(), result.returncode
|
||||
|
||||
def post_sensor_data(sensor_id, values, unit, start, duration="PT1H"):
|
||||
"""Post sensor data via FM API."""
|
||||
import re
|
||||
|
||||
# Login first
|
||||
session = requests.Session()
|
||||
session.verify = False
|
||||
r = session.get("https://cariflex.digitribe.fr/login")
|
||||
match = re.search(r'<input[^>]*csrf_token[^>]*value="([^"]+)"', r.text)
|
||||
if not match:
|
||||
return False
|
||||
csrf = match.group(1)
|
||||
r = session.post("https://cariflex.digitribe.fr/login", data={
|
||||
"email": "admin@digitribe.fr", "password": "Digitribe972",
|
||||
"csrf_token": csrf, "remember": "y"
|
||||
}, allow_redirects=True)
|
||||
|
||||
if "dashboard" not in r.url:
|
||||
return False
|
||||
|
||||
# Post data - use proper ISO format with timezone
|
||||
r = session.post(
|
||||
f"https://cariflex.digitribe.fr/api/v3_0/sensors/{sensor_id}/data",
|
||||
json={
|
||||
"values": values,
|
||||
"start": start,
|
||||
"duration": duration,
|
||||
"unit": unit
|
||||
},
|
||||
timeout=30
|
||||
)
|
||||
return r.status_code in [200, 201, 202]
|
||||
|
||||
# ========================================
|
||||
# 1. Données météo réelles via API Open-Meteo
|
||||
# ========================================
|
||||
print("=== Récupération des données météo ===")
|
||||
|
||||
LAT, LON = 14.6091, -61.2155
|
||||
today = datetime.now(MARTINIQUE_TZ).strftime("%Y-%m-%d")
|
||||
|
||||
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():
|
||||
sensor_id = SENSORS[sensor_name]
|
||||
values = wdata["hourly"][key]
|
||||
posted = 0
|
||||
|
||||
for i, t in enumerate(times):
|
||||
# Parse datetime and format properly
|
||||
dt = datetime.fromisoformat(t)
|
||||
dt_utc = dt.astimezone(timezone.utc)
|
||||
start_str = dt_utc.strftime("%Y-%m-%dT%H:%M:%S+00:00")
|
||||
val = round(max(0, values[i]), 1)
|
||||
|
||||
if post_sensor_data(sensor_id, [val], unit, start_str):
|
||||
posted += 1
|
||||
|
||||
print(f" '{sensor_name}': {posted}/{len(times)} posted")
|
||||
else:
|
||||
print(f" Erreur API: {resp.status_code}")
|
||||
|
||||
# ========================================
|
||||
# 2. Prix DSO simulés (24h)
|
||||
# ========================================
|
||||
print("\n=== Injection des prix DSO ===")
|
||||
|
||||
now_utc = datetime.now(timezone.utc)
|
||||
|
||||
for sensor_name, sensor_id in [("consumption_price", SENSORS["consumption_price"]),
|
||||
("production_price", SENSORS["production_price"])]:
|
||||
posted = 0
|
||||
for h in range(24):
|
||||
dt = now_utc - timedelta(hours=23-h)
|
||||
hour_of_day = dt.hour
|
||||
|
||||
if 6 <= hour_of_day <= 22:
|
||||
price = round(random.uniform(80, 150), 2) if "consumption" in sensor_name else round(random.uniform(60, 120), 2)
|
||||
else:
|
||||
price = round(random.uniform(40, 80), 2) if "consumption" in sensor_name else round(random.uniform(30, 60), 2)
|
||||
|
||||
start_str = dt.strftime("%Y-%m-%dT%H:%M:%S+00:00")
|
||||
if post_sensor_data(sensor_id, [price], "EUR/MWh", start_str):
|
||||
posted += 1
|
||||
|
||||
print(f" '{sensor_name}': {posted}/24 posted")
|
||||
|
||||
print("\n=== Terminé ===")
|
||||
Reference in New Issue
Block a user