79 lines
2.3 KiB
HTML
79 lines
2.3 KiB
HTML
<!doctype html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>PV_Forecast</title>
|
|
<script src="https://code.highcharts.com/highcharts.js"></script>
|
|
<style>
|
|
body { font-family: sans-serif; margin: 0; padding: 12px; }
|
|
#chart { height: 420px; width: 100%; }
|
|
.row { display:flex; gap:12px; align-items:center; margin-bottom:10px; flex-wrap:wrap; }
|
|
.badge { padding:4px 8px; border-radius:10px; background:#eee; }
|
|
button { padding:6px 10px; cursor:pointer; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="row">
|
|
<button id="reload">Neu laden</button>
|
|
<span class="badge" id="meta">…</span>
|
|
</div>
|
|
|
|
<div id="chart"></div>
|
|
|
|
<script>
|
|
const instanceId = {INSTANCE_ID};
|
|
const endpoint = `/hook/solcastcompare?instance=${instanceId}&action=data`;
|
|
|
|
let chart;
|
|
|
|
async function loadData() {
|
|
const r = await fetch(endpoint, { cache: "no-store" });
|
|
if (!r.ok) throw new Error("HTTP " + r.status);
|
|
return await r.json();
|
|
}
|
|
|
|
function render(data) {
|
|
const cachedAt = data?.meta?.forecast_cached_at
|
|
? new Date(data.meta.forecast_cached_at * 1000).toLocaleString()
|
|
: "unbekannt";
|
|
|
|
document.getElementById("meta").textContent = `Forecast Cache: ${cachedAt}`;
|
|
|
|
const forecast = data?.series?.forecast ?? [];
|
|
const actual = data?.series?.actual ?? [];
|
|
|
|
if (!chart) {
|
|
chart = Highcharts.chart("chart", {
|
|
title: { text: "PV: Erwartung vs. Tatsächlich" },
|
|
xAxis: { type: "datetime" },
|
|
yAxis: { title: { text: "Leistung" } },
|
|
tooltip: { shared: true, xDateFormat: "%d.%m.%Y %H:%M" },
|
|
legend: { enabled: true },
|
|
series: [
|
|
{ name: "Erwartet (Solcast)", data: forecast },
|
|
{ name: "Tatsächlich (Archiv)", data: actual }
|
|
]
|
|
});
|
|
} else {
|
|
chart.series[0].setData(forecast, false);
|
|
chart.series[1].setData(actual, false);
|
|
chart.redraw();
|
|
}
|
|
}
|
|
|
|
async function refresh() {
|
|
try {
|
|
const data = await loadData();
|
|
render(data);
|
|
} catch (e) {
|
|
document.getElementById("meta").textContent = "Fehler beim Laden: " + e.message;
|
|
}
|
|
}
|
|
|
|
document.getElementById("reload").addEventListener("click", refresh);
|
|
|
|
refresh();
|
|
</script>
|
|
</body>
|
|
</html>
|