Sammelstand der offenen Arbeit im Dashboard. Einstellungen: eine Eingabemaske fuer die Energiepreise unter restricted/settings.php, dazu costs.php als Modell und ajax/settings.php als Endpunkt. Die Preise stehen jetzt in gridCosts, gasCosts und fuelCosts statt fest im Quelltext von getStats.php; die Jahresstatistik rechnet ueber LEAD() den jeweils gueltigen Zeitraum aus und schlaegt den anteiligen Grundpreis auf. Eingegeben wird in gewohnten Einheiten - l/100 km, kWh/100 km, Euro je Liter -, umgerechnet wird beim Speichern. solarLog_costs.sql beschreibt die Umstellung der Tabellen. Skoda: eigene Seite mit Live-Werten ueber MQTT und Historie ueber ajax/skoda.php, Kommandos ueber ajax/skodaCmd.php. Karte: Leaflet mit einem eigenen Kachel-Zwischenspeicher (ajax/tile.php), dessen Ablage unter tiles/ nicht ins Repository gehoert. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
110 lines
4.4 KiB
PHP
110 lines
4.4 KiB
PHP
<?php
|
|
/**
|
|
* Einstellungsseite: Parameter, die von Hand gepflegt werden.
|
|
*
|
|
* Bisher sind das die Preistabellen aus restricted/costs.php. Die Seite ist
|
|
* als Sammlung von Karten angelegt - eine Karte je Thema. Kommt spaeter ein
|
|
* weiterer Parameter dazu, kommt er als eigene Karte hinzu, ohne dass die
|
|
* vorhandenen etwas davon merken.
|
|
*
|
|
* Die Zeilen zeichnet js/solar/settings.js aus dem Modell, das hier
|
|
* eingebettet wird - dieselbe Arbeitsteilung wie im Automatik-Editor. Sonst
|
|
* gaebe es die erste Zeile als PHP und jede weitere als JavaScript, und die
|
|
* beiden Fassungen liefen frueher oder spaeter auseinander. Aus demselben
|
|
* Grund kommen die Spaltenbreiten aus preisSpalten(): die Kopfzeile hier und
|
|
* die Felder dort muessen dieselben sein.
|
|
*/
|
|
require_once(__DIR__ . "/costs.php");
|
|
|
|
$reihen = preisReihen();
|
|
$daten = [];
|
|
$fehler = "";
|
|
try {
|
|
foreach ($reihen as $key => $reihe) {
|
|
$daten[$key] = [
|
|
"felder" => $reihe["felder"],
|
|
"spalten" => preisSpalten($reihe["felder"]),
|
|
"zeilen" => preiseLaden($key),
|
|
];
|
|
}
|
|
} catch (Throwable $e) {
|
|
$fehler = $e->getMessage();
|
|
}
|
|
?>
|
|
<!--begin::App Main-->
|
|
<main class="app-main">
|
|
<!--begin::App Content Header-->
|
|
<div class="app-content-header">
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<div class="col-sm-12">
|
|
<h3 class="mb-0">Einstellungen</h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!--end::App Content Header-->
|
|
<!--begin::App Content-->
|
|
<div class="app-content">
|
|
<div class="container-fluid">
|
|
<?php if ($fehler): ?>
|
|
<div class="alert alert-danger">Die Einstellungen sind nicht erreichbar: <?= htmlspecialchars($fehler) ?></div>
|
|
<?php endif; ?>
|
|
<?php foreach ($reihen as $key => $reihe): ?>
|
|
<?php $breiten = preisSpalten($reihe["felder"]); ?>
|
|
<div class="row">
|
|
<div class="col-12 col-xxl-9">
|
|
<div class="card mb-4 preis-karte" data-reihe="<?= htmlspecialchars($key) ?>">
|
|
<div class="card-header pb-2 pt-2">
|
|
<h3 class="card-title"><i class="bi <?= $reihe["symbol"] ?> me-2"></i><?= htmlspecialchars($reihe["titel"]) ?></h3>
|
|
<div class="card-tools">
|
|
<button type="button" class="btn btn-tool preis-neu" title="Zeitraum hinzufügen">
|
|
<i class="bi bi-plus-lg"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-tool preis-zurueck" title="Änderungen verwerfen">
|
|
<i class="bi bi-arrow-counterclockwise"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="card-body pb-2">
|
|
<p class="text-secondary small mb-3"><?= htmlspecialchars($reihe["hinweis"]) ?></p>
|
|
|
|
<!-- Spaltenköpfe nur auf breiten Schirmen; auf dem Handy trägt
|
|
jedes Feld seine eigene Beschriftung. -->
|
|
<div class="row g-2 d-none d-xl-flex preis-kopf text-secondary small fw-semibold">
|
|
<div class="col-xl-<?= $breiten["ab"] ?>">Gültig ab</div>
|
|
<div class="col-xl-<?= $breiten["bis"] ?>">Gültig bis</div>
|
|
<?php foreach (array_values($reihe["felder"]) as $i => $feld): ?>
|
|
<div class="col-xl-<?= $breiten["felder"][$i] ?>"><?= htmlspecialchars($feld["titel"]) ?></div>
|
|
<?php endforeach; ?>
|
|
<div class="col-xl-<?= $breiten["aktion"] ?>"></div>
|
|
</div>
|
|
|
|
<div class="preis-zeilen"></div>
|
|
|
|
<button type="button" class="btn btn-sm btn-outline-secondary mt-3 preis-neu">
|
|
<i class="bi bi-plus-lg me-1"></i>Zeitraum hinzufügen
|
|
</button>
|
|
</div>
|
|
<div class="card-footer d-flex align-items-center gap-3">
|
|
<button type="button" class="btn btn-primary preis-speichern">Speichern</button>
|
|
<span class="preis-hinweis small"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
<!--end::App Content-->
|
|
</main>
|
|
<!--end::App Main-->
|
|
<script>
|
|
// Ausgangsstand der Preistabellen. Werte in der Anzeigeeinheit (ct statt
|
|
// Euro); umgerechnet wird in restricted/costs.php - an genau einer Stelle.
|
|
const preisDaten = <?= json_encode($daten, JSON_UNESCAPED_UNICODE) ?>;
|
|
// Aelteste Messung in EnergyFlow. Beginnt eine Preisreihe spaeter, fehlt
|
|
// den Werten davor der Preis - dann warnt die Maske.
|
|
const ersteMessung = <?= json_encode(ersteMessung()) ?>;
|
|
</script>
|