Externe Berichtserstellung - API-Beispiele
Rufen Sie Anlagendaten direkt aus den Mirox-Export-APIs ab und erstellen Sie Ihre eigenen Berichte mit dem Werkzeug Ihrer Wahl. Dieses Beispiel führt der Klarheit halber mit curl durch die relevanten Endpunkte, aber dieselben Prinzipien gelten auch für Python, Power BI, Tableau oder jeden anderen HTTP-Client.
Voraussetzungen
Bevor Sie Daten für die externe Berichtserstellung exportieren können, benötigen Sie:
- Mirox-Konto - Ein gültiges Mirox-Benutzerkonto
- Berechtigungen - Ihr Konto muss die Berechtigung haben, den Park zu lesen und Berichte zu erstellen für diesen Park
- Park-UID - Die eindeutige Kennung der Park-Ressource, zu der Sie berichten möchten
- API-Token - Ein API-Token mit mindestens der Berechtigungsgruppe Reporting (siehe API-Token-Nutzung für eine Anleitung zur Erstellung)
Verfügbare Export-Endpunkte
Die Mirox-Plattform stellt mehrere API-Endpunkte bereit, um Daten in Formaten zu exportieren, die für die externe Berichtserstellung geeignet sind. Parkinformationen und Ereignis-Exporte liegen unter dem API-Pfad /v1/export/report/; Produktionsmetriken nutzen den dedizierten Template-Export-Endpunkt /v1/export/metrics/template/{template_uid}.
Wichtiger Hinweis
Die in diesem Dokument gezeigten API-Endpunkte sind Beispiele zur Veranschaulichung. Die genauen Endpunkte können sich ändern. Bitte konsultieren Sie die aktuelle API-Dokumentation unter https://service.mirox.io/docs für die neuesten Informationen.
Parkinformationen (JSON)
Grundlegende Parkinformationen können als JSON exportiert werden mit:
GET /v1/export/report/{park_uid}/info
Dies liefert Park-Metadaten einschließlich:
- Name, Typ und Beschreibung
- Geografische Lage und Zeitzone
- Technische Spezifikationen (Spitzenproduktion usw.)
- Organisations- und Portfolio-Informationen
- Adresse und Inbetriebnahmedetails
Vollständige Details zum Antwortschema finden Sie in der API-Dokumentation für Parkinformationen.
Park-Ereignisse (CSV)
Ereignisdaten können als CSV exportiert werden mit:
GET /v1/export/report/{park_uid}/events.csv
Dieser Endpunkt unterstützt die folgenden Abfrageparameter:
year: Filtern nach Jahr (z. B. 2025)quarter: Filtern nach Quartal (1-4)month: Filtern nach Monat (1-12)
Die zurückgegebene CSV-Datei enthält die folgenden Spalten:
- Ereignis-ID
- Startdatum
- Enddatum
- Dauer (Stunden)
- Typ
- Ersteller
- Beschreibung
- Priorität
Ereignisfilterung nach Priorität
Das Feld Priorität gibt die Wichtigkeit eines Ereignisses an:
- Werte >= 1000: Wichtige Ereignisse (produktionsrelevante Abschaltungen, Alarme)
- Werte < 1000: Informative Ereignisse (Verbindungen, geringfügige Statusänderungen)
Filtern Sie in Ihrem Berichtswerkzeug nach Priorität, um bedeutsame Ereignisse hervorzuheben.
Wenn keine Zeitparameter angegeben werden, gibt der Endpunkt Ereignisse aus dem zuletzt abgeschlossenen Quartal zurück.
Details zu Anfrageparametern und Antwortformat finden Sie in der API-Dokumentation für Park-Ereignisse.
Park-Metriken (CSV)
Produktions- und Leistungsmetriken können über den Template-Export-Endpunkt als CSV exportiert werden:
GET /v1/export/metrics/template/{template_uid}
Dieser Endpunkt unterstützt die folgenden Abfrageparameter:
park: Eine oder mehrere Park-UIDs (kommagetrennt), die in den Export einbezogen werden sollenportfolio: Eine oder mehrere Portfolio-UIDs (kommagetrennt); jedes Portfolio wird zu seinen Parks aufgelöstresolution: Aggregationsintervall (daily,weekly,monthly,quarterlyoderyearly; Standardwert istmonthly)year: Filtern nach Jahr (z. B. 2025)quarter: Filtern nach Quartal (1-4)month: Filtern nach Monat (1-12)week: Filtern nach ISO-Woche (wöchentliche Auflösung)day: Filtern nach Tag (erfordertmonth)
Der Parameter resolution bestimmt, wie die Daten aggregiert werden:
daily: Gibt eine Zeile pro Tag mit täglichen Messwerten zurückmonthly: Gibt eine Zeile pro Monat mit aggregierten Monatssummen und einer zusätzlichen Spalte „Tage im Monat" zurück
Ihr Business-Intelligence-Werkzeug muss diese unterschiedlichen Auflösungsformate für die Visualisierung und Analyse entsprechend verarbeiten.
Exporte über mehrere Anlagen
Ein einziger Aufruf kann mehrere Anlagen oder ganze Portfolios auf einmal exportieren, indem kommagetrennte park- und portfolio-UIDs übergeben werden. Dies ist der empfohlene Weg, wenn Sie einen Bericht erstellen, der mehr als eine Anlage umfasst.
Die Spalten werden durch das Export-Template definiert, auf das Sie verweisen. Das folgende Beispiel verwendet das Template ABCD12340001 („Report Technical v1"), das Folgendes enthält:
- Energieproduktion (kWh)
- Energiebericht (kWh)
- Energie-Abschaltung durch Netz (kWh)
- Energie-Abschaltung extern (kWh)
- Energieziel (kWh)
- Einstrahlung (kWh)
Vollständige Details zu Anfrageparametern und Antwortformat finden Sie in der aktuellen API-Dokumentation unter https://service.mirox.io/docs.
API-Nutzungsbeispiele
Nachfolgend finden Sie Beispiele dafür, wie die Export-Endpunkte direkt mit curl verwendet werden. Diese Beispiele veranschaulichen die Struktur von API-Aufrufen und das Format der Antworten.
Beispiel 1: Abrufen von Parkinformationen (JSON)
Anfrage:
curl "https://service.mirox.io/api/v1/export/report/ABC123DEF456/info" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Antwort (Auszug):
{
"uid": "ABC123DEF456",
"name": "Sunnyside Solar Park",
"type": "solar",
"description": "Sunnyside Solar Park is a 42 MW photovoltaic installation...",
"latitude": 48.7511,
"longitude": 9.1225,
"timezone": "Europe/Berlin",
"peak_production_w": 42000000,
"active": true,
"created_at": "2024-05-16T10:30:25.104830Z",
"portfolio": {
"uid": "GHI789JKL012",
"name": "Renewable South"
},
"organization": {
"uid": "MNO345PQR678",
"name": "GreenPower Inc."
},
"address": {
"address1": "123 Solar Way",
"zip_code": "70123",
"city": "Sunnyville",
"country": "Germany"
}
}
Beispiel 2: Export von Ereignisdaten (CSV)
Anfrage:
curl "https://service.mirox.io/api/v1/export/report/ABC123DEF456/events.csv" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Antwort (CSV):
Event ID,Start Date,End Date,Duration (hours),Type,Creator,Description,Priority
9876543210123456789,2025-01-15 08:45,Ongoing,720.25,Sensor Error,System,Irradiation sensor malfunction detected,1200
8765432101234567890,2025-02-10 14:30,2025-02-15 09:15,114.75,Data Availability,System,Connection issues with data acquisition system,1100
Beachten Sie das Feld Priority mit Werten größer als 1000, das bedeutsame, produktionsrelevante Ereignisse kennzeichnet.
Beispiel 3: Export monatlicher Metriken (CSV)
Anfrage:
curl "https://service.mirox.io/api/v1/export/metrics/template/ABCD12340001?park=ABC123DEF456&resolution=monthly" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Antwort (CSV):
Date (YYYY-MM),Energy Production (kWh),Energy Report (kWh),Energy Shutdown by grid (kWh),Energy Shutdown by external (kWh),Energy Target (kWh),Irradiation (kWh),Days in Month (d)
2025-01,950000.45,980000.00,15000.50,25000.75,980000.00,18.350,31
2025-02,1250000.32,1300000.00,2000.25,18500.40,1300000.00,22.780,28
2025-03,1850000.75,1900000.00,45000.20,30000.65,1900000.00,35.420,31
Dieses Beispiel zeigt monatlich aggregierte Daten mit der für die monatliche Intervalloption spezifischen Spalte „Days in Month (d)".
Nutzung in verschiedenen Werkzeugen
Diese API-Aufrufe lassen sich in verschiedenen Umgebungen anwenden:
- Python/Requests: Verwenden Sie die
requests-Bibliothek, um API-Aufrufe in Python-Skripten durchzuführen - Power BI: Verwenden Sie „Web"-Datenquellen, um JSON-/CSV-Daten direkt zu importieren
- Tableau: Konfigurieren Sie Web Data Connectors für die API-Integration
- Excel: Verwenden Sie Power Query, um API-Daten zu importieren und zu transformieren
- Eigene Skripte: Implementieren Sie in jeder Sprache mit HTTP-Client-Unterstützung
Best Practices
Für eine effektive API-Nutzung:
- API-Token sicher verwenden - Hinterlegen Sie Token niemals fest im Skript; verwenden Sie Umgebungsvariablen
- Intervalldaten korrekt verarbeiten - Stellen Sie sicher, dass Ihre Analyse tägliche und monatliche Datenformate korrekt verarbeitet
- Ereignisse angemessen filtern - Verwenden Sie das Prioritätsfeld, um sich auf bedeutsame Ereignisse zu konzentrieren (>=1000)
- Datenvolumen berücksichtigen - Exportieren Sie bei großen Parks oder langen Zeiträumen Daten in handhabbaren Teilstücken
- Fehlerbehandlung implementieren - Behandeln Sie HTTP-Fehler und Netzwerkprobleme angemessen
Fehlerbehebung
Authentifizierungsfehler
Wenn Sie einen HTTP-401-Fehler erhalten:
Überprüfen Sie Ihr API-Token: Stellen Sie sicher, dass Sie ein gültiges, nicht abgelaufenes API-Token verwenden. Token können in Ihren Mirox-Benutzereinstellungen erzeugt werden.
Überprüfen Sie die Park-UID: Stellen Sie sicher, dass die Park-UID gültig ist und Sie Zugriff darauf haben. Der Beispielwert
ABC123DEF456ist ein Platzhalter.Token-Berechtigungen: Überprüfen Sie, dass Ihrem Token die erforderlichen Berechtigungen für den Zugriff auf die Export-Endpunkte erteilt wurden.
Probleme mit der CSV-Kodierung
CSV-Exporte verwenden die UTF-8-Kodierung. In manchen Werkzeugen (z. B. Excel) müssen Sie die Kodierung beim Import möglicherweise explizit angeben.
Beispiel einer Python-Implementierung: SolarViz Report Generator
Das folgende Beispiel zeigt eine vollständige Python-Implementierung, die die oben beschriebenen APIs verwendet, um einen individuellen Energieproduktionsbericht zu erstellen.
Voraussetzungen
Um dieses Python-Beispiel auszuführen, benötigen Sie die folgenden Bibliotheken:
pip install requests pandas matplotlib seaborn tabulate
requests: Für API-Aufrufe an die Mirox-Plattformpandas: Für Datenmanipulation und -analysematplotlibundseaborn: Für die Erstellung von Visualisierungentabulate: Für die Formatierung von Tabellen im Bericht
Vollständiger Beispielcode
Nachfolgend finden Sie den vollständigen Code für den SolarViz Report Generator:
#!/usr/bin/env python3
"""
SolarViz - Mirox External Report Generator
This script demonstrates how to fetch data from the Mirox API and generate
a custom energy production report with visualizations as a PDF file.
"""
import os
import requests
import json
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime, timezone
import io
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, Table, TableStyle
from reportlab.graphics.shapes import Drawing
from reportlab.lib.units import inch, cm
# Configuration - Replace with your values
API_URL = "https://service.mirox.io"
API_TOKEN = "YOUR_API_TOKEN" # Your personal access token
PARK_UID = "ABC123DEF456" # The UID of the park you want to work with
TEMPLATE_UID = "ABCD12340001" # The export template ("Report Technical v1")
# Time range parameters
YEAR = datetime.now(timezone.utc).year
QUARTER = (datetime.now(timezone.utc).month - 1) // 3 + 1
# Setup headers
headers = {
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json"
}
def fetch_park_info():
"""Fetch basic park information as JSON"""
response = requests.get(
f"{API_URL}/api/v1/export/report/{PARK_UID}/info",
headers=headers
)
response.raise_for_status()
return response.json()
def fetch_events(year=None, quarter=None):
"""Fetch park events as DataFrame"""
params = {}
if year:
params["year"] = year
if quarter:
params["quarter"] = quarter
response = requests.get(
f"{API_URL}/api/v1/export/report/{PARK_UID}/events.csv",
headers=headers,
params=params
)
response.raise_for_status()
# Convert CSV content to DataFrame
events_df = pd.read_csv(io.StringIO(response.content.decode('utf-8')))
# Filter for significant events (priority >= 1000)
significant_events = events_df[events_df['Priority'] >= 1000]
# Process events data - remove ID, Priority, and format duration
if not significant_events.empty:
# Remove any ID-related columns (there could be 'ID', 'Event ID', etc.)
id_columns = [col for col in significant_events.columns if 'id' in col.lower()]
significant_events = significant_events.drop(id_columns, axis=1, errors='ignore')
# Remove Priority column as well
if 'Priority' in significant_events.columns:
significant_events = significant_events.drop('Priority', axis=1)
# Convert duration from minutes to days/hours
if 'DurationMin' in significant_events.columns:
def format_duration(minutes):
if minutes < 60:
return f"{minutes} min"
elif minutes < 24*60:
hours = minutes / 60
return f"{hours:.1f} hours"
else:
days = minutes / (24*60)
return f"{days:.1f} days"
significant_events['Duration'] = significant_events['DurationMin'].apply(format_duration)
significant_events = significant_events.drop('DurationMin', axis=1)
return significant_events
def fetch_metrics(resolution="monthly", year=None, quarter=None):
"""Fetch park production metrics as DataFrame"""
params = {"park": PARK_UID, "resolution": resolution}
if year:
params["year"] = year
if quarter:
params["quarter"] = quarter
response = requests.get(
f"{API_URL}/api/v1/export/metrics/template/{TEMPLATE_UID}",
headers=headers,
params=params
)
response.raise_for_status()
# Convert CSV content to DataFrame
metrics_df = pd.read_csv(io.StringIO(response.content.decode('utf-8')))
return metrics_df
def create_production_chart(metrics_df):
"""Create a chart visualizing energy production and target with stacked losses"""
plt.figure(figsize=(8, 4))
# Set seaborn style
sns.set_style("whitegrid")
# Prepare data for stacked bar chart
x_positions = range(len(metrics_df))
months = metrics_df.iloc[:, 0]
# Create stacked bar chart
# Base layer: Actual production
plt.bar(x_positions, metrics_df['Energy Production (kWh)'],
color='#2986cc', label='Actual Production')
# Stack grid shutdown losses on top
grid_shutdown = metrics_df['Energy Shutdown by grid (kWh)']
external_shutdown = metrics_df['Energy Shutdown by external (kWh)']
# Second layer: Grid shutdown losses
plt.bar(x_positions, grid_shutdown,
bottom=metrics_df['Energy Production (kWh)'],
color='#e06666', label='Grid Shutdown Losses')
# Third layer: External shutdown losses
plt.bar(x_positions, external_shutdown,
bottom=metrics_df['Energy Production (kWh)'] + grid_shutdown,
color='#f1c232', label='External Shutdown Losses')
# Plot Target as a line
plt.plot(x_positions, metrics_df['Energy Target (kWh)'],
marker='o', color='#6aa84f', linewidth=2, label='Target')
# Customize the chart
plt.title('Monthly Energy Production vs Target with Losses')
plt.xlabel('Month')
plt.ylabel('Energy (kWh)')
plt.xticks(x_positions, months, rotation=45)
# Add legend
plt.legend(loc='upper left')
plt.tight_layout()
# Save chart to a bytes buffer
buffer = io.BytesIO()
plt.savefig(buffer, format='png', dpi=300)
buffer.seek(0)
plt.close()
return buffer
def calculate_performance_metrics(metrics_df):
"""Calculate performance metrics based on the production data"""
performance = {}
# Total energy production
performance['total_production'] = metrics_df['Energy Production (kWh)'].sum()
# Total target
performance['total_target'] = metrics_df['Energy Target (kWh)'].sum()
# Performance ratio (actual vs target)
performance['performance_ratio'] = (performance['total_production'] / performance['total_target']) * 100
# Total shutdown energy
performance['grid_shutdown'] = metrics_df['Energy Shutdown by grid (kWh)'].sum()
performance['external_shutdown'] = metrics_df['Energy Shutdown by external (kWh)'].sum()
performance['total_shutdown'] = performance['grid_shutdown'] + performance['external_shutdown']
# Lost production percentage
performance['lost_production_pct'] = (performance['total_shutdown'] /
(performance['total_production'] + performance['total_shutdown'])) * 100
return performance
def generate_pdf_report(park_info, events_df, metrics_df, performance, chart_data):
"""Generate a PDF report with the data"""
# Define the output filename
output_file = f"SolarViz_Report_{park_info['name'].replace(' ', '_')}_{YEAR}_Q{QUARTER}.pdf"
# Create PDF document
doc = SimpleDocTemplate(output_file, pagesize=A4)
styles = getSampleStyleSheet()
# Modify existing styles
styles['Title'].fontName = 'Helvetica-Bold'
styles['Title'].fontSize = 18
styles['Title'].alignment = 1 # Center aligned
styles['Title'].spaceAfter = 12
# Modify Heading2 style
styles['Heading2'].fontName = 'Helvetica-Bold'
styles['Heading2'].fontSize = 14
styles['Heading2'].spaceBefore = 12
styles['Heading2'].spaceAfter = 6
# Modify Normal style
styles['Normal'].fontName = 'Helvetica'
styles['Normal'].fontSize = 10
styles['Normal'].spaceBefore = 6
styles['Normal'].spaceAfter = 6
# Add a custom style for tables
styles.add(ParagraphStyle(name='TableHeader',
parent=styles['Normal'],
fontName='Helvetica-Bold',
fontSize=9,
alignment=1))
# Create document elements
elements = []
# Title
elements.append(Paragraph(f"Energy Production Report: {park_info['name']}", styles['Title']))
elements.append(Spacer(1, 0.5*cm))
# Park Information section
elements.append(Paragraph("Park Information", styles['Heading2']))
park_info_data = [
["Name:", park_info['name']],
["Type:", park_info['type']],
["Location:", f"{park_info['address']['city']}, {park_info['address']['country']}"],
["Peak Capacity:", f"{park_info['peak_production_w'] / 1000000:.2f} MW"],
["Portfolio:", park_info['portfolio']['name']],
["Organization:", park_info['organization']['name']]
]
park_info_table = Table(park_info_data, colWidths=[3*cm, 10*cm])
park_info_table.setStyle(TableStyle([
('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
('FONTNAME', (1, 0), (1, -1), 'Helvetica'),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('LEFTPADDING', (0, 0), (-1, -1), 6),
('TOPPADDING', (0, 0), (-1, -1), 3),
('BOTTOMPADDING', (0, 0), (-1, -1), 3),
]))
elements.append(park_info_table)
elements.append(Spacer(1, 0.5*cm))
# Performance Summary section
elements.append(Paragraph(f"Performance Summary ({YEAR} Q{QUARTER})", styles['Heading2']))
performance_data = [
["Total Energy Production:", f"{performance['total_production']:,.2f} kWh"],
["Target Production:", f"{performance['total_target']:,.2f} kWh"],
["Performance Ratio:", f"{performance['performance_ratio']:.2f}%"],
["Total Energy Lost to Shutdowns:", f"{performance['total_shutdown']:,.2f} kWh"],
[" • Grid Shutdowns:", f"{performance['grid_shutdown']:,.2f} kWh"],
[" • External Shutdowns:", f"{performance['external_shutdown']:,.2f} kWh"],
["Lost Production Percentage:", f"{performance['lost_production_pct']:.2f}%"]
]
performance_table = Table(performance_data, colWidths=[6*cm, 7*cm])
performance_table.setStyle(TableStyle([
('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
('FONTNAME', (1, 0), (1, -1), 'Helvetica'),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('LEFTPADDING', (0, 0), (-1, -1), 6),
('TOPPADDING', (0, 0), (-1, -1), 3),
('BOTTOMPADDING', (0, 0), (-1, -1), 3),
]))
elements.append(performance_table)
elements.append(Spacer(1, 0.5*cm))
# Monthly Production Chart
elements.append(Paragraph("Monthly Production Chart", styles['Heading2']))
# Add the chart image
img = Image(chart_data, width=16*cm, height=8*cm)
elements.append(img)
elements.append(Spacer(1, 0.5*cm))
# Add metrics data table below the graph
elements.append(Paragraph("Monthly Production Data", styles['Heading2']))
# Prepare metrics data for table
# Select relevant columns
if not metrics_df.empty:
# Create a copy of the dataframe with selected columns
table_df = metrics_df.copy()
# Use the first column as the month column
month_col_name = table_df.columns[0]
# Create table data with headers
metrics_data = [['Month', 'Production (kWh)', 'Target (kWh)',
'Grid Shutdown (kWh)', 'External Shutdown (kWh)']]
# Add data rows with formatted numbers
for _, row in table_df.iterrows():
metrics_data.append([
row[month_col_name],
f"{row['Energy Production (kWh)']:,.2f}",
f"{row['Energy Target (kWh)']:,.2f}",
f"{row['Energy Shutdown by grid (kWh)']:,.2f}",
f"{row['Energy Shutdown by external (kWh)']:,.2f}"
])
# Create table and set style
metrics_table = Table(metrics_data, repeatRows=1)
metrics_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.lightgrey),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('ALIGN', (0, 0), (-1, 0), 'CENTER'),
('ALIGN', (1, 1), (-1, -1), 'RIGHT'), # Right-align numeric columns
('BOTTOMPADDING', (0, 0), (-1, 0), 6),
('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('FONTSIZE', (0, 0), (-1, -1), 9),
]))
elements.append(metrics_table)
else:
elements.append(Paragraph("No production data available for the selected period.", styles['Normal']))
elements.append(Spacer(1, 0.5*cm))
# Significant Events section
elements.append(Paragraph("Significant Events", styles['Heading2']))
if not events_df.empty:
# Double check to make sure all ID columns and Priority are removed
id_columns = [col for col in events_df.columns if 'id' in col.lower()]
events_df = events_df.drop(id_columns, axis=1, errors='ignore')
# Also remove Priority column if it still exists
if 'Priority' in events_df.columns:
events_df = events_df.drop('Priority', axis=1)
# Convert DataFrame to a list of lists
events_data = [events_df.columns.tolist()] + events_df.values.tolist()
# Create table and set style
events_table = Table(events_data, repeatRows=1)
events_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.lightgrey),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('ALIGN', (0, 0), (-1, 0), 'CENTER'),
('BOTTOMPADDING', (0, 0), (-1, 0), 6),
('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('FONTSIZE', (0, 0), (-1, -1), 8),
]))
elements.append(events_table)
else:
elements.append(Paragraph("No significant events recorded during this period.", styles['Normal']))
elements.append(Spacer(1, 1*cm))
# Footer section
elements.append(Paragraph("Data Source", styles['Heading2']))
elements.append(Paragraph(
f"This report was generated using data exported from the Mirox platform via its external reporting API.<br/>"
f"Report creation date: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M')}<br/><br/>"
f"<i>Generated by SolarViz - External Reporting Tool</i>",
styles['Normal']))
# Build the PDF document
doc.build(elements)
return output_file
def main():
"""Main function that orchestrates the report generation process"""
try:
print("Fetching park information...")
park_info = fetch_park_info()
print("Fetching events data...")
events_df = fetch_events(year=YEAR, quarter=QUARTER)
print("Fetching production metrics...")
metrics_df = fetch_metrics(resolution="monthly", year=YEAR)
print("Calculating performance metrics...")
performance = calculate_performance_metrics(metrics_df)
print("Creating visualization...")
chart_data = create_production_chart(metrics_df)
print("Generating PDF report...")
output_file = generate_pdf_report(park_info, events_df, metrics_df, performance, chart_data)
print(f"Report successfully generated: {output_file}")
except Exception as e:
print(f"Error generating report: {str(e)}")
if __name__ == "__main__":
main()
Funktionsweise
Konfiguration: Das Skript legt zu Beginn die Mirox-API-URL, das API-Token und die Park-UID fest.
Datenerfassung: Das Skript ruft drei Arten von Daten aus Mirox ab:
- Parkinformationen (JSON) einschließlich Name, Lage und Kapazität
- Bedeutsame Ereignisse (CSV), nach Priorität gefiltert
- Monatliche Energieproduktionsmetriken (CSV)
Datenverarbeitung: Das Skript:
- Konvertiert CSV-Daten in Pandas-DataFrames für eine einfache Verarbeitung
- Berechnet Leistungsmetriken wie das Produktionsverhältnis und die Auswirkung von Abschaltungen
- Erstellt eine gestapelte Balkenvisualisierung der monatlichen Produktion und der Abschaltverluste im Vergleich zur Ziellinie
Berichtserstellung: Das Skript erstellt einen PDF-Bericht (mit ReportLab), der Folgendes enthält:
- Zusammenfassung der Parkinformationen
- Leistungsmetriken
- Energieproduktionsdiagramm
- Tabelle bedeutsamer Ereignisse
Ausgabe: Der Bericht wird als PDF-Datei gespeichert, die:
- In jedem PDF-Betrachter geöffnet werden kann
- Direkt mit Beteiligten geteilt werden kann
- Archiviert oder in Berichts-Workflows integriert werden kann
Anpassungsmöglichkeiten
Der SolarViz Report Generator kann auf verschiedene Weise angepasst werden:
- Zeiträume: Ändern Sie die Variablen YEAR und QUARTER, um Berichte für unterschiedliche Zeiträume zu erstellen
- Diagrammtypen: Passen Sie die Funktion
create_production_chartan, um andere Visualisierungsstile zu verwenden - Zusätzliche Metriken: Rufen Sie zusätzliche Metriken aus Mirox oder anderen Datenquellen ab und binden Sie sie ein
- Berichtsformat: Passen Sie das ReportLab-Layout an oder tauschen Sie es bei Bedarf gegen ein HTML- oder anderes Ausgabeformat aus
- Automatisierung: Integrieren Sie das Skript mit Cron-Jobs oder Task-Schedulern in automatisierte Workflows
Verwandte Funktionen
- Leitfaden zur externen Berichtserstellung — konzeptioneller Überblick und weitere Integrationsmöglichkeiten
- Metrik-Export-API — vollständige Referenz für den oben verwendeten Template-Export-Endpunkt
- API-Token-Nutzung — erstellen und verwalten Sie das für dieses Beispiel benötigte Token
- Berichte — erstellen Sie fertige PDF-/CSV-Berichte direkt in der Plattform